diff --git a/Package.swift b/Package.swift index 9a9c69d..ba20ee5 100644 --- a/Package.swift +++ b/Package.swift @@ -42,18 +42,7 @@ let package = Package( .define("HAVE_GETHOSTUUID", to: "0"), .define("HAVE_STDINT_H"), .define("LTC_NO_TEST"), - .define("LTC_NO_FILE"), - .define("LTC_NO_HASHES"), - .define("LTC_NO_PKCS"), - .define("LTC_NO_MISC"), - .define("LTC_NO_PK"), - .define("LTC_NO_MACS"), - .define("LTC_MINIMAL"), - .define("LTC_SHA512"), - .define("LTC_SHA1"), - .define("LTC_HMAC"), - .define("LTC_PKCS_5"), - .define("LTC_HASH_HELPERS") + .define("LTC_NO_FILE") ], linkerSettings: [ .linkedLibrary("log", .when(platforms: [.android])) diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/aes/aes.c b/Sources/DataLiteC/libtomcrypt/ciphers/aes/aes.c index ea65a6b..1a5e269 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/aes/aes.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/aes/aes.c @@ -669,7 +669,7 @@ int ECB_TEST(void) unsigned char tmp[2][16]; int i, y; - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { zeromem(&key, sizeof(key)); if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/aes/aes_desc.c b/Sources/DataLiteC/libtomcrypt/ciphers/aes/aes_desc.c index 5b13dc2..7c537df 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/aes/aes_desc.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/aes/aes_desc.c @@ -63,19 +63,10 @@ static LTC_INLINE int s_aesni_is_supported(void) a = 1; c = 0; -#if defined(_MSC_VER) && !defined(__clang__) - int arr[4]; - __cpuidex(arr, a, c); - a = arr[0]; - b = arr[1]; - c = arr[2]; - d = arr[3]; -#else __asm__ volatile ("cpuid" :"=a"(a), "=b"(b), "=c"(c), "=d"(d) :"a"(a), "c"(c) ); -#endif is_supported = ((c >> 19) & 1) && ((c >> 25) & 1); initialized = 1; @@ -198,7 +189,7 @@ int AES_TEST(void) int y; #endif - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { zeromem(&key, sizeof(key)); if ((err = AES_SETUP(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/aes/aesni.c b/Sources/DataLiteC/libtomcrypt/ciphers/aes/aesni.c index 723ad27..ecfc008 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/aes/aesni.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/aes/aesni.c @@ -313,7 +313,7 @@ int aesni_test(void) unsigned char tmp[2][16]; int i, y; - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { zeromem(&key, sizeof(key)); if ((err = aesni_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/anubis.c b/Sources/DataLiteC/libtomcrypt/ciphers/anubis.c index 128b16c..8338fa7 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/anubis.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/anubis.c @@ -1498,7 +1498,7 @@ int anubis_test(void) unsigned char buf[2][16]; symmetric_key skey; - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { anubis_setup(tests[x].key, tests[x].keylen, 0, &skey); anubis_ecb_encrypt(tests[x].pt, buf[0], &skey); anubis_ecb_decrypt(buf[0], buf[1], &skey); diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/camellia.c b/Sources/DataLiteC/libtomcrypt/ciphers/camellia.c index ee40284..702c602 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/camellia.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/camellia.c @@ -680,7 +680,7 @@ int camellia_test(void) int err; unsigned int x; - for (x = 0; x < LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < sizeof(tests)/sizeof(tests[0]); x++) { zeromem(&skey, sizeof(skey)); if ((err = camellia_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/cast5.c b/Sources/DataLiteC/libtomcrypt/ciphers/cast5.c index e55d8ab..d8279b5 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/cast5.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/cast5.c @@ -492,7 +492,7 @@ int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ #endif #define FI cast5_FI -static LTC_INLINE ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr) +LTC_INLINE static ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr) { ulong32 I; I = (Km + R); @@ -500,7 +500,7 @@ static LTC_INLINE ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr) return ((S1[LTC_BYTE(I, 3)] ^ S2[LTC_BYTE(I,2)]) - S3[LTC_BYTE(I,1)]) + S4[LTC_BYTE(I,0)]; } -static LTC_INLINE ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr) +LTC_INLINE static ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr) { ulong32 I; I = (Km ^ R); @@ -508,7 +508,7 @@ static LTC_INLINE ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr) return ((S1[LTC_BYTE(I, 3)] - S2[LTC_BYTE(I,2)]) + S3[LTC_BYTE(I,1)]) ^ S4[LTC_BYTE(I,0)]; } -static LTC_INLINE ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr) +LTC_INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr) { ulong32 I; I = (Km - R); diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/des.c b/Sources/DataLiteC/libtomcrypt/ciphers/des.c index 2c03666..d50e4de 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/des.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/des.c @@ -2,10 +2,6 @@ /* SPDX-License-Identifier: Unlicense */ #include "tomcrypt_private.h" -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wshorten-64-to-32" - /** @file des.c DES code submitted by Dobes Vandermeer @@ -1385,14 +1381,14 @@ static void cookey(const ulong32 *raw1, ulong32 *keyout) for(i=0; i < 16; i++, raw1++) { raw0 = raw1++; - *cook = (*raw0 & 0x00fc0000L) << 6; - *cook |= (*raw0 & 0x00000fc0L) << 10; - *cook |= (*raw1 & 0x00fc0000L) >> 10; - *cook++ |= (*raw1 & 0x00000fc0L) >> 6; - *cook = (*raw0 & 0x0003f000L) << 12; - *cook |= (*raw0 & 0x0000003fL) << 16; - *cook |= (*raw1 & 0x0003f000L) >> 4; - *cook++ |= (*raw1 & 0x0000003fL); + *cook = (ulong32)((*raw0 & 0x00fc0000L) << 6); + *cook |= (ulong32)((*raw0 & 0x00000fc0L) << 10); + *cook |= (ulong32)((*raw1 & 0x00fc0000L) >> 10); + *cook++ |= (ulong32)((*raw1 & 0x00000fc0L) >> 6); + *cook = (ulong32)((*raw0 & 0x0003f000L) << 12); + *cook |= (ulong32)((*raw0 & 0x0000003fL) << 16); + *cook |= (ulong32)((*raw1 & 0x0003f000L) >> 4); + *cook++ |= (ulong32) (*raw1 & 0x0000003fL); } XMEMCPY(keyout, dough, sizeof(dough)); @@ -2022,7 +2018,7 @@ int des_test(void) symmetric_key skey; int i, err; - for (i = 0; i < (int)LTC_ARRAY_SIZE(cases); i++) + for (i = 0; i < (int)(sizeof(cases)/sizeof(cases[0])); i++) { if ((err = des_setup(cases[i].key, 8, 0, &skey)) != CRYPT_OK) { return err; @@ -2129,7 +2125,7 @@ int des3_test(void) return err; } - for (i = 0; i < (int)LTC_ARRAY_SIZE(cases); i++) + for (i = 0; i < (int)(sizeof(cases)/sizeof(cases[0])); i++) { if ((err = des3_setup(cases[i].key, 16, 0, &skey)) != CRYPT_OK) { return err; @@ -2247,4 +2243,3 @@ int des3_keysize(int *keysize) #endif -#pragma clang diagnostic pop diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/idea.c b/Sources/DataLiteC/libtomcrypt/ciphers/idea.c index f663b48..40adc58 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/idea.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/idea.c @@ -226,7 +226,7 @@ int idea_test(void) return CRYPT_FAIL_TESTVECTOR; } - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = idea_setup(tests[x].key, 16, 8, &key)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/kasumi.c b/Sources/DataLiteC/libtomcrypt/ciphers/kasumi.c index 7f25b34..de76fc7 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/kasumi.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/kasumi.c @@ -286,7 +286,7 @@ int kasumi_test(void) symmetric_key key; int err, x; - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = kasumi_setup(tests[x].key, 16, 0, &key)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/khazad.c b/Sources/DataLiteC/libtomcrypt/ciphers/khazad.c index 0f1327d..ccd1b70 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/khazad.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/khazad.c @@ -794,7 +794,7 @@ int khazad_test(void) unsigned char buf[2][8]; symmetric_key skey; - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { khazad_setup(tests[x].key, 16, 0, &skey); khazad_ecb_encrypt(tests[x].pt, buf[0], &skey); khazad_ecb_decrypt(buf[0], buf[1], &skey); diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/kseed.c b/Sources/DataLiteC/libtomcrypt/ciphers/kseed.c index be8ec63..014b4e3 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/kseed.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/kseed.c @@ -334,7 +334,7 @@ int kseed_test(void) unsigned char buf[2][16]; symmetric_key skey; - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { kseed_setup(tests[x].key, 16, 0, &skey); kseed_ecb_encrypt(tests[x].pt, buf[0], &skey); kseed_ecb_decrypt(buf[0], buf[1], &skey); diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/multi2.c b/Sources/DataLiteC/libtomcrypt/ciphers/multi2.c index 2ef7ff0..e1a84ac 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/multi2.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/multi2.c @@ -242,7 +242,7 @@ int multi2_test(void) symmetric_key skey; int err, x; - for (x = 1; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 1; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = multi2_setup(tests[x].key, 40, tests[x].rounds, &skey)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/noekeon.c b/Sources/DataLiteC/libtomcrypt/ciphers/noekeon.c index e5b4ded..3dfe91e 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/noekeon.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/noekeon.c @@ -267,7 +267,7 @@ int noekeon_test(void) unsigned char tmp[2][16]; int err, i, y; - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { zeromem(&key, sizeof(key)); if ((err = noekeon_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/serpent.c b/Sources/DataLiteC/libtomcrypt/ciphers/serpent.c index 03661a1..8f5b785 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/serpent.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/serpent.c @@ -693,7 +693,7 @@ int serpent_test(void) symmetric_key key; int err, x; - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = serpent_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/sm4.c b/Sources/DataLiteC/libtomcrypt/ciphers/sm4.c index 2fc68d0..d21cdce 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/sm4.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/sm4.c @@ -67,7 +67,7 @@ static const sm4_u8_t sm4_sbox_table[16][16] = { * S-box * defined in section 2.6 S-box */ -static LTC_INLINE sm4_u8_t s_sm4_sbox(sm4_u8_t a) +LTC_INLINE static sm4_u8_t s_sm4_sbox(sm4_u8_t a) { return sm4_sbox_table[(a >> 4) & 0x0f][a & 0x0f]; } @@ -80,7 +80,7 @@ static LTC_INLINE sm4_u8_t s_sm4_sbox(sm4_u8_t a) * But we just convert a 32bit word byte by byte. * So it's OK if we don't convert the endian order */ -static LTC_INLINE sm4_u32_t s_sm4_t(sm4_u32_t A) +LTC_INLINE static sm4_u32_t s_sm4_t(sm4_u32_t A) { sm4_u8_t a[4]; sm4_u8_t b[4]; @@ -98,7 +98,7 @@ static LTC_INLINE sm4_u32_t s_sm4_t(sm4_u32_t A) /* * defined in section 6.2 (2) Linear transformation L */ -static LTC_INLINE sm4_u32_t s_sm4_L62(sm4_u32_t B) +LTC_INLINE static sm4_u32_t s_sm4_L62(sm4_u32_t B) { return B ^ ROLc(B, 2) ^ ROLc(B, 10) ^ ROLc(B, 18) ^ ROLc(B, 24); } @@ -106,7 +106,7 @@ static LTC_INLINE sm4_u32_t s_sm4_L62(sm4_u32_t B) /* * defined in section 6.2 Permutation T */ -static LTC_INLINE sm4_u32_t s_sm4_T62(sm4_u32_t Z) +LTC_INLINE static sm4_u32_t s_sm4_T62(sm4_u32_t Z) { return s_sm4_L62(s_sm4_t(Z)); } @@ -137,7 +137,7 @@ static const sm4_u32_t sm4_CK[32] = /* * defined in section 7.3 (1) L' */ -static LTC_INLINE sm4_u32_t s_sm4_L73(sm4_u32_t B) +LTC_INLINE static sm4_u32_t s_sm4_L73(sm4_u32_t B) { return B ^ ROLc(B, 13) ^ ROLc(B, 23); } @@ -145,7 +145,7 @@ static LTC_INLINE sm4_u32_t s_sm4_L73(sm4_u32_t B) /* * defined in section 7.3 (1) T' */ -static LTC_INLINE sm4_u32_t s_sm4_T73(sm4_u32_t Z) +LTC_INLINE static sm4_u32_t s_sm4_T73(sm4_u32_t Z) { return s_sm4_L73(s_sm4_t(Z)); } @@ -153,7 +153,7 @@ static LTC_INLINE sm4_u32_t s_sm4_T73(sm4_u32_t Z) /* * defined in section 7.3 Key Expansion */ -static LTC_INLINE void s_sm4_mk2rk(sm4_u32_t rk[32], sm4_u8_t mk[16]) +LTC_INLINE static void s_sm4_mk2rk(sm4_u32_t rk[32], sm4_u8_t mk[16]) { sm4_u32_t MK[4] = { 0 }; sm4_u32_t K[4+32] = { 0 }; @@ -175,7 +175,7 @@ static LTC_INLINE void s_sm4_mk2rk(sm4_u32_t rk[32], sm4_u8_t mk[16]) /* * defined in section 6 Round Function F */ -static LTC_INLINE sm4_u32_t s_sm4_F(sm4_u32_t X[4], sm4_u32_t rk) +LTC_INLINE static sm4_u32_t s_sm4_F(sm4_u32_t X[4], sm4_u32_t rk) { return X[0] ^ s_sm4_T62(X[1] ^ X[2] ^ X[3] ^ rk); } @@ -183,7 +183,7 @@ static LTC_INLINE sm4_u32_t s_sm4_F(sm4_u32_t X[4], sm4_u32_t rk) /* * defined in section 7.1 (2) The reverse transformation */ -static LTC_INLINE void s_sm4_R(sm4_u32_t Y[4], sm4_u32_t X[32+4]) +LTC_INLINE static void s_sm4_R(sm4_u32_t Y[4], sm4_u32_t X[32+4]) { Y[0] = X[35]; Y[1] = X[34]; @@ -194,7 +194,7 @@ static LTC_INLINE void s_sm4_R(sm4_u32_t Y[4], sm4_u32_t X[32+4]) /* * defined in section 7.1 (En)cryption */ -static LTC_INLINE void s_sm4_crypt(sm4_u32_t Y[4], sm4_u32_t X[4+32], const sm4_u32_t rk[32]) +LTC_INLINE static void s_sm4_crypt(sm4_u32_t Y[4], sm4_u32_t X[4+32], const sm4_u32_t rk[32]) { int i; @@ -203,7 +203,7 @@ static LTC_INLINE void s_sm4_crypt(sm4_u32_t Y[4], sm4_u32_t X[4+32], const sm4_ s_sm4_R(Y, X); } -static LTC_INLINE void s_sm4_setkey(struct sm4_key *sm4, const unsigned char *key) +LTC_INLINE static void s_sm4_setkey(struct sm4_key *sm4, const unsigned char *key) { int i; @@ -229,7 +229,7 @@ int sm4_setup(const unsigned char *key, int keylen, /* * SM4 encryption. */ -static LTC_INLINE void s_sm4_do(void *output, const void *input, const sm4_u32_t rk[32]) +LTC_INLINE static void s_sm4_do(void *output, const void *input, const sm4_u32_t rk[32]) { sm4_u32_t Y[4]; sm4_u32_t X[32+4]; diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/tea.c b/Sources/DataLiteC/libtomcrypt/ciphers/tea.c index c5419bf..128d8a3 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/tea.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/tea.c @@ -150,7 +150,7 @@ int tea_test(void) symmetric_key skey; size_t i; int err, y; - for (i = 0; i < LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { zeromem(&skey, sizeof(skey)); l = sizeof(key); @@ -166,8 +166,8 @@ int tea_test(void) tea_ecb_encrypt(ptct[0], tmp[0], &skey); tea_ecb_decrypt(tmp[0], tmp[1], &skey); - if (compare_testvector(tmp[0], 8, ptct[1], 8, "TEA Encrypt", i) != 0 || - compare_testvector(tmp[1], 8, ptct[0], 8, "TEA Decrypt", i) != 0) { + if (compare_testvector(tmp[0], 8, ptct[1], 8, "TEA Encrypt", (int)i) != 0 || + compare_testvector(tmp[1], 8, ptct[0], 8, "TEA Decrypt", (int)i) != 0) { return CRYPT_FAIL_TESTVECTOR; } diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/twofish/twofish.c b/Sources/DataLiteC/libtomcrypt/ciphers/twofish/twofish.c index 30478f0..48149a2 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/twofish/twofish.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/twofish/twofish.c @@ -651,7 +651,7 @@ int twofish_test(void) unsigned char tmp[2][16]; int err, i, y; - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/ciphers/xtea.c b/Sources/DataLiteC/libtomcrypt/ciphers/xtea.c index 9e86e8d..95aaa1a 100644 --- a/Sources/DataLiteC/libtomcrypt/ciphers/xtea.c +++ b/Sources/DataLiteC/libtomcrypt/ciphers/xtea.c @@ -197,7 +197,7 @@ int xtea_test(void) unsigned char tmp[2][8]; symmetric_key skey; int i, err, y; - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { zeromem(&skey, sizeof(skey)); if ((err = xtea_setup(tests[i].key, 16, 0, &skey)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_add_aad.c b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_add_aad.c index 94d2e2b..130d304 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_add_aad.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_add_aad.c @@ -29,7 +29,7 @@ int ccm_add_aad(ccm_state *ccm, for (y = 0; y < adatalen; y++) { if (ccm->x == 16) { /* full block so let's encrypt it */ - if ((err = ecb_encrypt_block(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { return err; } ccm->x = 0; @@ -40,7 +40,7 @@ int ccm_add_aad(ccm_state *ccm, /* remainder? */ if (ccm->aadlen == ccm->current_aadlen) { if (ccm->x != 0) { - if ((err = ecb_encrypt_block(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { return err; } } diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_add_nonce.c b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_add_nonce.c index 176836b..a56a43a 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_add_nonce.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_add_nonce.c @@ -66,7 +66,7 @@ int ccm_add_nonce(ccm_state *ccm, } /* encrypt PAD */ - if ((err = ecb_encrypt_block(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_done.c b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_done.c index 51ce6cc..965121d 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_done.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_done.c @@ -28,7 +28,7 @@ int ccm_done(ccm_state *ccm, LTC_ARGCHK(taglen != NULL); if (ccm->x != 0) { - if ((err = ecb_encrypt_block(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { return err; } } @@ -37,11 +37,11 @@ int ccm_done(ccm_state *ccm, for (y = 15; y > 15 - ccm->L; y--) { ccm->ctr[y] = 0x00; } - if ((err = ecb_encrypt_block(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) { return err; } - ecb_done(&ccm->K); + cipher_descriptor[ccm->cipher].done(&ccm->K); /* store the TAG */ for (x = 0; x < 16 && x < *taglen; x++) { diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_init.c b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_init.c index 3578bcf..527c6af 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_init.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_init.c @@ -41,9 +41,10 @@ int ccm_init(ccm_state *ccm, int cipher, ccm->taglen = taglen; /* schedule key */ - if ((err = ecb_start(cipher, key, keylen, 0, &ccm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ccm->K)) != CRYPT_OK) { return err; } + ccm->cipher = cipher; /* let's get the L value */ ccm->ptlen = ptlen; diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_memory.c b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_memory.c index d239044..a6498ce 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_memory.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_memory.c @@ -32,7 +32,7 @@ */ int ccm_memory(int cipher, const unsigned char *key, unsigned long keylen, - symmetric_ECB *uskey, + symmetric_key *uskey, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, unsigned char *pt, unsigned long ptlen, @@ -42,7 +42,7 @@ int ccm_memory(int cipher, { unsigned char PAD[16], ctr[16], CTRPAD[16], ptTag[16], b, *pt_real; unsigned char *pt_work = NULL; - symmetric_ECB *skey; + symmetric_key *skey; int err; unsigned long len, L, x, y, z, CTRlen; @@ -78,15 +78,12 @@ int ccm_memory(int cipher, if (*taglen < 4 || *taglen > 16 || (*taglen % 2) == 1 || headerlen > 0x7fffffffu) { return CRYPT_INVALID_ARG; } - if (noncelen < 7) { - return CRYPT_INVALID_ARG; - } /* is there an accelerator? */ if (cipher_descriptor[cipher].accel_ccm_memory != NULL) { return cipher_descriptor[cipher].accel_ccm_memory( key, keylen, - &uskey->key, + uskey, nonce, noncelen, header, headerlen, pt, ptlen, @@ -123,7 +120,7 @@ int ccm_memory(int cipher, } /* initialize the cipher */ - if ((err = ecb_start(cipher, key, keylen, 0, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, (int)keylen, 0, skey)) != CRYPT_OK) { XFREE(skey); return err; } @@ -147,7 +144,7 @@ int ccm_memory(int cipher, (L-1)); /* nonce */ - for (y = 0; y < noncelen; y++) { + for (y = 0; y < 15 - L; y++) { PAD[x++] = nonce[y]; } @@ -173,7 +170,7 @@ int ccm_memory(int cipher, } /* encrypt PAD */ - if ((err = ecb_encrypt_block(PAD, PAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } @@ -198,7 +195,7 @@ int ccm_memory(int cipher, for (y = 0; y < headerlen; y++) { if (x == 16) { /* full block so let's encrypt it */ - if ((err = ecb_encrypt_block(PAD, PAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } x = 0; @@ -207,7 +204,7 @@ int ccm_memory(int cipher, } /* remainder */ - if ((err = ecb_encrypt_block(PAD, PAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } } @@ -242,7 +239,7 @@ int ccm_memory(int cipher, ctr[z] = (ctr[z] + 1) & 255; if (ctr[z]) break; } - if ((err = ecb_encrypt_block(ctr, CTRPAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { goto error; } @@ -251,7 +248,7 @@ int ccm_memory(int cipher, *(LTC_FAST_TYPE_PTR_CAST(&PAD[z])) ^= *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])); *(LTC_FAST_TYPE_PTR_CAST(&ct[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) ^ *(LTC_FAST_TYPE_PTR_CAST(&CTRPAD[z])); } - if ((err = ecb_encrypt_block(PAD, PAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } } @@ -262,7 +259,7 @@ int ccm_memory(int cipher, ctr[z] = (ctr[z] + 1) & 255; if (ctr[z]) break; } - if ((err = ecb_encrypt_block(ctr, CTRPAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { goto error; } @@ -271,7 +268,7 @@ int ccm_memory(int cipher, *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&ct[y+z])) ^ *(LTC_FAST_TYPE_PTR_CAST(&CTRPAD[z])); *(LTC_FAST_TYPE_PTR_CAST(&PAD[z])) ^= *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])); } - if ((err = ecb_encrypt_block(PAD, PAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } } @@ -286,7 +283,7 @@ int ccm_memory(int cipher, ctr[z] = (ctr[z] + 1) & 255; if (ctr[z]) break; } - if ((err = ecb_encrypt_block(ctr, CTRPAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { goto error; } CTRlen = 0; @@ -302,7 +299,7 @@ int ccm_memory(int cipher, } if (x == 16) { - if ((err = ecb_encrypt_block(PAD, PAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } x = 0; @@ -311,7 +308,7 @@ int ccm_memory(int cipher, } if (x != 0) { - if ((err = ecb_encrypt_block(PAD, PAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } } @@ -321,12 +318,12 @@ int ccm_memory(int cipher, for (y = 15; y > 15 - L; y--) { ctr[y] = 0x00; } - if ((err = ecb_encrypt_block(ctr, CTRPAD, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { goto error; } if (skey != uskey) { - ecb_done(skey); + cipher_descriptor[cipher].done(skey); #ifdef LTC_CLEAN_STACK zeromem(skey, sizeof(*skey)); #endif diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_process.c b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_process.c index b5f973d..3d22480 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_process.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_process.c @@ -47,7 +47,7 @@ int ccm_process(ccm_state *ccm, ccm->ctr[z] = (ccm->ctr[z] + 1) & 255; if (ccm->ctr[z]) break; } - if ((err = ecb_encrypt_block(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) { return err; } ccm->CTRlen = 0; @@ -63,7 +63,7 @@ int ccm_process(ccm_state *ccm, } if (ccm->x == 16) { - if ((err = ecb_encrypt_block(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) { return err; } ccm->x = 0; diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_test.c b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_test.c index d725ecd..e551c38 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_test.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ccm/ccm_test.c @@ -108,7 +108,7 @@ int ccm_test(void) unsigned long taglen, x, y; unsigned char buf[64], buf2[64], tag[16], tag2[16], tag3[16], zero[64]; int err, idx; - symmetric_ECB skey; + symmetric_key skey; ccm_state ccm; zeromem(zero, 64); @@ -121,11 +121,11 @@ int ccm_test(void) } } - for (x = 0; x < LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) { for (y = 0; y < 2; y++) { taglen = tests[x].taglen; if (y == 0) { - if ((err = ecb_start(idx, tests[x].key, 16, 0, &skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) { return err; } @@ -151,7 +151,7 @@ int ccm_test(void) return err; } } else { - if ((err = ccm_init(&ccm, idx, tests[x].key, 16, tests[x].ptlen, tests[x].taglen, tests[x].headerlen)) != CRYPT_OK) { + if ((err = ccm_init(&ccm, idx, tests[x].key, 16, tests[x].ptlen, (int)tests[x].taglen, tests[x].headerlen)) != CRYPT_OK) { return err; } if ((err = ccm_add_nonce(&ccm, tests[x].nonce, tests[x].noncelen)) != CRYPT_OK) { @@ -168,10 +168,10 @@ int ccm_test(void) } } - if (compare_testvector(buf, tests[x].ptlen, tests[x].ct, tests[x].ptlen, "CCM encrypt data", x)) { + if (compare_testvector(buf, tests[x].ptlen, tests[x].ct, tests[x].ptlen, "CCM encrypt data", (int)x)) { return CRYPT_FAIL_TESTVECTOR; } - if (compare_testvector(tag, taglen, tests[x].tag, tests[x].taglen, "CCM encrypt tag", x)) { + if (compare_testvector(tag, taglen, tests[x].tag, tests[x].taglen, "CCM encrypt tag", (int)x)) { return CRYPT_FAIL_TESTVECTOR; } @@ -189,7 +189,7 @@ int ccm_test(void) return err; } } else { - if ((err = ccm_init(&ccm, idx, tests[x].key, 16, tests[x].ptlen, tests[x].taglen, tests[x].headerlen)) != CRYPT_OK) { + if ((err = ccm_init(&ccm, idx, tests[x].key, 16, tests[x].ptlen, (int)tests[x].taglen, tests[x].headerlen)) != CRYPT_OK) { return err; } if ((err = ccm_add_nonce(&ccm, tests[x].nonce, tests[x].noncelen)) != CRYPT_OK) { @@ -207,7 +207,7 @@ int ccm_test(void) } - if (compare_testvector(buf2, tests[x].ptlen, tests[x].pt, tests[x].ptlen, "CCM decrypt data", x)) { + if (compare_testvector(buf2, tests[x].ptlen, tests[x].pt, tests[x].ptlen, "CCM decrypt data", (int)x)) { return CRYPT_FAIL_TESTVECTOR; } if (y == 0) { @@ -225,17 +225,17 @@ int ccm_test(void) tag3, &taglen, 1 ) != CRYPT_ERROR) { return CRYPT_FAIL_TESTVECTOR; } - if (compare_testvector(buf2, tests[x].ptlen, zero, tests[x].ptlen, "CCM decrypt wrong tag", x)) { + if (compare_testvector(buf2, tests[x].ptlen, zero, tests[x].ptlen, "CCM decrypt wrong tag", (int)x)) { return CRYPT_FAIL_TESTVECTOR; } } else { - if (compare_testvector(tag2, taglen, tests[x].tag, tests[x].taglen, "CCM decrypt tag", x)) { + if (compare_testvector(tag2, taglen, tests[x].tag, tests[x].taglen, "CCM decrypt tag", (int)x)) { return CRYPT_FAIL_TESTVECTOR; } } if (y == 0) { - ecb_done(&skey); + cipher_descriptor[idx].done(&skey); } } } diff --git a/Sources/DataLiteC/libtomcrypt/encauth/eax/eax_test.c b/Sources/DataLiteC/libtomcrypt/encauth/eax/eax_test.c index adfa879..c613e0d 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/eax/eax_test.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/eax/eax_test.c @@ -216,7 +216,7 @@ int eax_test(void) } } - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { len = sizeof(outtag); if ((err = eax_encrypt_authenticate_memory(idx, tests[x].key, tests[x].keylen, tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen, diff --git a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_add_aad.c b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_add_aad.c index 67a86fe..5c3793e 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_add_aad.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_add_aad.c @@ -20,6 +20,7 @@ int gcm_add_aad(gcm_state *gcm, const unsigned char *adata, unsigned long adatalen) { unsigned long x; + int err; #ifdef LTC_FAST unsigned long y; #endif @@ -33,6 +34,10 @@ int gcm_add_aad(gcm_state *gcm, return CRYPT_INVALID_ARG; } + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + /* in IV mode? */ if (gcm->mode == LTC_GCM_MODE_IV) { /* IV length must be > 0 */ diff --git a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_add_iv.c b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_add_iv.c index b37a55b..33a2444 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_add_iv.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_add_iv.c @@ -20,6 +20,7 @@ int gcm_add_iv(gcm_state *gcm, const unsigned char *IV, unsigned long IVlen) { unsigned long x, y; + int err; LTC_ARGCHK(gcm != NULL); if (IVlen > 0) { @@ -35,6 +36,11 @@ int gcm_add_iv(gcm_state *gcm, return CRYPT_INVALID_ARG; } + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + + /* trip the ivmode flag */ if (IVlen + gcm->buflen > 12) { gcm->ivmode |= 1; diff --git a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_done.c b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_done.c index 5e135d1..464f87a 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_done.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_done.c @@ -30,6 +30,10 @@ int gcm_done(gcm_state *gcm, return CRYPT_INVALID_ARG; } + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + if (gcm->mode == LTC_GCM_MODE_IV) { /* let's process the IV */ if ((err = gcm_add_aad(gcm, NULL, 0)) != CRYPT_OK) return err; @@ -59,7 +63,7 @@ int gcm_done(gcm_state *gcm, gcm_mult_h(gcm, gcm->X); /* encrypt original counter */ - if ((err = ecb_encrypt_block(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) { return err; } for (x = 0; x < 16 && x < *taglen; x++) { @@ -67,7 +71,7 @@ int gcm_done(gcm_state *gcm, } *taglen = x; - ecb_done(&gcm->K); + cipher_descriptor[gcm->cipher].done(&gcm->K); return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_init.c b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_init.c index 96abfe2..1822bdc 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_init.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_init.c @@ -44,19 +44,20 @@ int gcm_init(gcm_state *gcm, int cipher, } /* schedule key */ - if ((err = ecb_start(cipher, key, keylen, 0, &gcm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) { return err; } /* H = E(0) */ zeromem(B, 16); - if ((err = ecb_encrypt_block(B, gcm->H, &gcm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) { return err; } /* setup state */ zeromem(gcm->buf, sizeof(gcm->buf)); zeromem(gcm->X, sizeof(gcm->X)); + gcm->cipher = cipher; gcm->mode = LTC_GCM_MODE_IV; gcm->ivmode = 0; gcm->buflen = 0; diff --git a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_process.c b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_process.c index b75c1d0..e3c956c 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_process.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_process.c @@ -37,6 +37,10 @@ int gcm_process(gcm_state *gcm, return CRYPT_INVALID_ARG; } + if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { + return err; + } + /* 0xFFFFFFFE0 = ((2^39)-256)/8 */ if (gcm->pttotlen / 8 + (ulong64)gcm->buflen + (ulong64)ptlen >= CONST64(0xFFFFFFFE0)) { return CRYPT_INVALID_ARG; @@ -60,7 +64,7 @@ int gcm_process(gcm_state *gcm, if (++gcm->Y[y] & 255) { break; } } /* encrypt the counter */ - if ((err = ecb_encrypt_block(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { return err; } @@ -89,7 +93,7 @@ int gcm_process(gcm_state *gcm, for (y = 15; y >= 12; y--) { if (++gcm->Y[y] & 255) { break; } } - if ((err = ecb_encrypt_block(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { return err; } } @@ -107,7 +111,7 @@ int gcm_process(gcm_state *gcm, for (y = 15; y >= 12; y--) { if (++gcm->Y[y] & 255) { break; } } - if ((err = ecb_encrypt_block(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { return err; } } @@ -125,7 +129,7 @@ int gcm_process(gcm_state *gcm, for (y = 15; y >= 12; y--) { if (++gcm->Y[y] & 255) { break; } } - if ((err = ecb_encrypt_block(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { + if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { return err; } gcm->buflen = 0; diff --git a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_test.c b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_test.c index aa24122..228db57 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_test.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/gcm/gcm_test.c @@ -338,7 +338,7 @@ int gcm_test(void) if ((err = gcm_done(&gcm, T[0], &y)) != CRYPT_OK) return err; if (compare_testvector(T[0], y, tests[0].T, 16, "GCM Encrypt Tag-special", 0)) return CRYPT_FAIL_TESTVECTOR; - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { y = sizeof(T[0]); if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen, tests[x].IV, tests[x].IVlen, diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_decrypt.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_decrypt.c index 98f36e4..dd512ce 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_decrypt.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_decrypt.c @@ -25,8 +25,16 @@ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt) LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); - /* can't use a encrypt-only descriptor */ - LTC_ARGCHK(cipher_descriptor[ocb->key.cipher].ecb_decrypt != NULL); + /* check if valid cipher */ + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + LTC_ARGCHK(cipher_descriptor[ocb->cipher].ecb_decrypt != NULL); + + /* check length */ + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } /* Get Z[i] value */ ocb_shift_xor(ocb, Z); @@ -35,7 +43,7 @@ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt) for (x = 0; x < ocb->block_len; x++) { tmp[x] = ct[x] ^ Z[x]; } - if ((err = ecb_decrypt_block(tmp, pt, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key)) != CRYPT_OK) { return err; } for (x = 0; x < ocb->block_len; x++) { diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_encrypt.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_encrypt.c index a38765a..ad6260f 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_encrypt.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_encrypt.c @@ -24,6 +24,12 @@ int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct) LTC_ARGCHK(ocb != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } /* compute checksum */ for (x = 0; x < ocb->block_len; x++) { @@ -37,7 +43,7 @@ int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct) for (x = 0; x < ocb->block_len; x++) { tmp[x] = pt[x] ^ Z[x]; } - if ((err = ecb_encrypt_block(tmp, ct, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key)) != CRYPT_OK) { return err; } for (x = 0; x < ocb->block_len; x++) { diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_init.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_init.c index 056605c..c10e3c3 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_init.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_init.c @@ -57,7 +57,7 @@ int ocb_init(ocb_state *ocb, int cipher, /* determine which polys to use */ ocb->block_len = cipher_descriptor[cipher].block_length; - x = (int)LTC_ARRAY_SIZE(polys); + x = (int)(sizeof(polys)/sizeof(polys[0])); for (poly = 0; poly < x; poly++) { if (polys[poly].len == ocb->block_len) { break; @@ -71,13 +71,13 @@ int ocb_init(ocb_state *ocb, int cipher, } /* schedule the key */ - if ((err = ecb_start(cipher, key, keylen, 0, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) { return err; } /* find L = E[0] */ zeromem(ocb->L, ocb->block_len); - if ((err = ecb_encrypt_block(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) { return err; } @@ -85,7 +85,7 @@ int ocb_init(ocb_state *ocb, int cipher, for (x = 0; x < ocb->block_len; x++) { ocb->R[x] = ocb->L[x] ^ nonce[x]; } - if ((err = ecb_encrypt_block(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) { return err; } @@ -126,6 +126,7 @@ int ocb_init(ocb_state *ocb, int cipher, /* set other params */ ocb->block_index = 1; + ocb->cipher = cipher; return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_ntz.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_ntz.c index bf933fd..b0f5570 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_ntz.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_ntz.c @@ -17,11 +17,6 @@ */ int ocb_ntz(unsigned long x) { -#if defined(LTC_HAVE_CTZL_BUILTIN) - if (x == 0) - return sizeof(unsigned long) * CHAR_BIT; - return __builtin_ctzl(x); -#else int c; x &= 0xFFFFFFFFUL; c = 0; @@ -30,7 +25,6 @@ int ocb_ntz(unsigned long x) x >>= 1; } return c; -#endif } #endif diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_test.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_test.c index 12942b5..b03c2fd 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_test.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb/ocb_test.c @@ -167,7 +167,7 @@ int ocb_test(void) } } - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { len = sizeof(outtag); if ((err = ocb_encrypt_authenticate_memory(idx, tests[x].key, 16, tests[x].nonce, tests[x].pt, tests[x].ptlen, outct, outtag, &len)) != CRYPT_OK) { diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb/s_ocb_done.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb/s_ocb_done.c index 9336b75..c5987b9 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb/s_ocb_done.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb/s_ocb_done.c @@ -40,7 +40,11 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(taglen != NULL); - if ((int)ptlen > ocb->block_len || (int)ptlen < 0) { + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length || + (int)ptlen > ocb->block_len || (int)ptlen < 0) { return CRYPT_INVALID_ARG; } @@ -72,7 +76,7 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, } /* Y[m] = E(X[m])) */ - if ((err = ecb_encrypt_block(X, Y, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key)) != CRYPT_OK) { goto error; } @@ -103,10 +107,10 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, } /* encrypt checksum, er... tag!! */ - if ((err = ecb_encrypt_block(ocb->checksum, X, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key)) != CRYPT_OK) { goto error; } - ecb_done(&ocb->key); + cipher_descriptor[ocb->cipher].done(&ocb->key); /* now store it */ for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) { diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_add_aad.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_add_aad.c index 1c08423..6215e9d 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_add_aad.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_add_aad.c @@ -29,7 +29,7 @@ static int s_ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_bl /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ ocb3_int_xor_blocks(tmp, aad_block, ocb->aOffset_current, ocb->block_len); - if ((err = ecb_encrypt_block(tmp, tmp, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) { return err; } ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len); diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_decrypt.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_decrypt.c index 15a3175..6d85036 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_decrypt.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_decrypt.c @@ -32,7 +32,14 @@ int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, LTC_ARGCHK(ct != NULL); LTC_ARGCHK(pt != NULL); - if (ctlen % ocb->block_len) { /* ctlen has to be multiple of block_len */ + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + if (ctlen % ocb->block_len) { /* ctlen has to bu multiple of block_len */ return CRYPT_INVALID_ARG; } @@ -48,7 +55,7 @@ int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, ocb3_int_xor_blocks(tmp, ct_b, ocb->Offset_current, ocb->block_len); /* decrypt */ - if ((err = ecb_decrypt_block(tmp, tmp, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_decrypt_last.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_decrypt_last.c index 9ef69f7..6a1ea9d 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_decrypt_last.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_decrypt_last.c @@ -34,6 +34,10 @@ int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ct LTC_ARGCHK(pt != NULL); } + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + goto LBL_ERR; + } + full_blocks = ctlen/ocb->block_len; full_blocks_len = full_blocks * ocb->block_len; last_block_len = ctlen - full_blocks_len; @@ -50,7 +54,7 @@ int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ct ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len); /* Pad = ENCIPHER(K, Offset_*) */ - if ((err = ecb_encrypt_block(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) { goto LBL_ERR; } @@ -72,7 +76,7 @@ int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ct for(x=0; xblock_len; x++) { ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x]; } - if ((err = ecb_encrypt_block(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { goto LBL_ERR; } } @@ -82,7 +86,7 @@ int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ct for(x=0; xblock_len; x++) { ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x]; } - if ((err = ecb_encrypt_block(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { goto LBL_ERR; } } diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_done.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_done.c index 00a8c29..688aa80 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_done.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_done.c @@ -24,6 +24,9 @@ int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen) LTC_ARGCHK(ocb != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(taglen != NULL); + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + goto LBL_ERR; + } /* check taglen */ if ((int)*taglen < ocb->tag_len) { @@ -49,7 +52,7 @@ int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen) } /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */ - if ((err = ecb_encrypt_block(tmp, tmp, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) { goto LBL_ERR; } ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len); diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_encrypt.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_encrypt.c index 152c1b5..7f17715 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_encrypt.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_encrypt.c @@ -32,7 +32,14 @@ int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); - if (ptlen % ocb->block_len) { /* ptlen has to be multiple of block_len */ + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + return err; + } + if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { + return CRYPT_INVALID_ARG; + } + + if (ptlen % ocb->block_len) { /* ptlen has to bu multiple of block_len */ return CRYPT_INVALID_ARG; } @@ -48,7 +55,7 @@ int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, ocb3_int_xor_blocks(tmp, pt_b, ocb->Offset_current, ocb->block_len); /* encrypt */ - if ((err = ecb_encrypt_block(tmp, tmp, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_encrypt_last.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_encrypt_last.c index 81bfa5c..c5d7b68 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_encrypt_last.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_encrypt_last.c @@ -34,6 +34,10 @@ int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long pt LTC_ARGCHK(ct != NULL); } + if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { + goto LBL_ERR; + } + full_blocks = ptlen/ocb->block_len; full_blocks_len = full_blocks * ocb->block_len; last_block_len = ptlen - full_blocks_len; @@ -52,7 +56,7 @@ int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long pt ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len); /* Pad = ENCIPHER(K, Offset_*) */ - if ((err = ecb_encrypt_block(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) { goto LBL_ERR; } @@ -74,7 +78,7 @@ int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long pt for(x=0; xblock_len; x++) { ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x]; } - if ((err = ecb_encrypt_block(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { goto LBL_ERR; } } else { @@ -83,7 +87,7 @@ int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long pt for(x=0; xblock_len; x++) { ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x]; } - if ((err = ecb_encrypt_block(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { goto LBL_ERR; } } diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_init.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_init.c index 51279a2..d85d006 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_init.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_init.c @@ -34,7 +34,7 @@ static void s_ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *no /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */ iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0; - if ((ecb_encrypt_block(iNonce, iKtop, &ocb->key)) != CRYPT_OK) { + if ((cipher_descriptor[ocb->cipher].ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) { zeromem(ocb->Offset_current, ocb->block_len); return; } @@ -100,6 +100,7 @@ int ocb3_init(ocb3_state *ocb, int cipher, if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } + ocb->cipher = cipher; /* Valid Nonce? * As of RFC7253: "string of no more than 120 bits" */ @@ -120,7 +121,7 @@ int ocb3_init(ocb3_state *ocb, int cipher, /* determine which polys to use */ ocb->block_len = cipher_descriptor[cipher].block_length; - x = (int)LTC_ARRAY_SIZE(polys); + x = (int)(sizeof(polys)/sizeof(polys[0])); for (poly = 0; poly < x; poly++) { if (polys[poly].len == ocb->block_len) { break; @@ -134,13 +135,13 @@ int ocb3_init(ocb3_state *ocb, int cipher, } /* schedule the key */ - if ((err = ecb_start(cipher, key, keylen, 0, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) { return err; } /* L_* = ENCIPHER(K, zeros(128)) */ zeromem(ocb->L_star, ocb->block_len); - if ((err = ecb_encrypt_block(ocb->L_star, ocb->L_star, &ocb->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L_star, ocb->L_star, &ocb->key)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_int_ntz.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_int_ntz.c index a667ff6..86942ce 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_int_ntz.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_int_ntz.c @@ -16,11 +16,6 @@ */ int ocb3_int_ntz(unsigned long x) { -#if defined(LTC_HAVE_CTZL_BUILTIN) - if (x == 0) - return sizeof(unsigned long) * CHAR_BIT; - return __builtin_ctzl(x); -#else int c; x &= 0xFFFFFFFFUL; c = 0; @@ -29,7 +24,6 @@ int ocb3_int_ntz(unsigned long x) x >>= 1; } return c; -#endif } #endif diff --git a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_test.c b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_test.c index 3c6cfe5..3a9816e 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_test.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/ocb3/ocb3_test.c @@ -209,7 +209,7 @@ int ocb3_test(void) } } - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { len = 16; /* must be the same as the required taglen */ if ((err = ocb3_encrypt_authenticate_memory(idx, key, sizeof(key), diff --git a/Sources/DataLiteC/libtomcrypt/encauth/siv/siv.c b/Sources/DataLiteC/libtomcrypt/encauth/siv/siv.c index d3dd578..425dd9e 100644 --- a/Sources/DataLiteC/libtomcrypt/encauth/siv/siv.c +++ b/Sources/DataLiteC/libtomcrypt/encauth/siv/siv.c @@ -612,7 +612,7 @@ int siv_test(void) cipher = find_cipher("aes"); - for (n = 0; n < LTC_ARRAY_SIZE(siv_tests); ++n) { + for (n = 0; n < sizeof(siv_tests)/sizeof(siv_tests[0]); ++n) { buflen = sizeof(buf); if ((err = siv_encrypt_memory(cipher, siv_tests[n].Key, siv_tests[n].Keylen, diff --git a/Sources/DataLiteC/libtomcrypt/hashes/chc/chc.c b/Sources/DataLiteC/libtomcrypt/hashes/chc/chc.c index 3a394d4..e82b2b3 100644 --- a/Sources/DataLiteC/libtomcrypt/hashes/chc/chc.c +++ b/Sources/DataLiteC/libtomcrypt/hashes/chc/chc.c @@ -277,7 +277,7 @@ int chc_test(void) oldhashidx = cipher_idx; chc_register(idx); - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { if ((err = chc_init(&md)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/hashes/rmd128.c b/Sources/DataLiteC/libtomcrypt/hashes/rmd128.c index cc894e1..7d57af8 100644 --- a/Sources/DataLiteC/libtomcrypt/hashes/rmd128.c +++ b/Sources/DataLiteC/libtomcrypt/hashes/rmd128.c @@ -380,7 +380,7 @@ int rmd128_test(void) unsigned char tmp[16]; hash_state md; - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { rmd128_init(&md); rmd128_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg)); rmd128_done(&md, tmp); diff --git a/Sources/DataLiteC/libtomcrypt/hashes/rmd160.c b/Sources/DataLiteC/libtomcrypt/hashes/rmd160.c index d4cba27..6e45a7e 100644 --- a/Sources/DataLiteC/libtomcrypt/hashes/rmd160.c +++ b/Sources/DataLiteC/libtomcrypt/hashes/rmd160.c @@ -439,7 +439,7 @@ int rmd160_test(void) unsigned char tmp[20]; hash_state md; - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { rmd160_init(&md); rmd160_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg)); rmd160_done(&md, tmp); diff --git a/Sources/DataLiteC/libtomcrypt/hashes/rmd256.c b/Sources/DataLiteC/libtomcrypt/hashes/rmd256.c index 4eecd3f..704c86e 100644 --- a/Sources/DataLiteC/libtomcrypt/hashes/rmd256.c +++ b/Sources/DataLiteC/libtomcrypt/hashes/rmd256.c @@ -405,7 +405,7 @@ int rmd256_test(void) unsigned char tmp[32]; hash_state md; - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { rmd256_init(&md); rmd256_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg)); rmd256_done(&md, tmp); diff --git a/Sources/DataLiteC/libtomcrypt/hashes/rmd320.c b/Sources/DataLiteC/libtomcrypt/hashes/rmd320.c index 1148b42..e25b6d9 100644 --- a/Sources/DataLiteC/libtomcrypt/hashes/rmd320.c +++ b/Sources/DataLiteC/libtomcrypt/hashes/rmd320.c @@ -470,7 +470,7 @@ int rmd320_test(void) unsigned char tmp[40]; hash_state md; - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { rmd320_init(&md); rmd320_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg)); rmd320_done(&md, tmp); diff --git a/Sources/DataLiteC/libtomcrypt/hashes/tiger.c b/Sources/DataLiteC/libtomcrypt/hashes/tiger.c index a1b66f7..e88fb3a 100644 --- a/Sources/DataLiteC/libtomcrypt/hashes/tiger.c +++ b/Sources/DataLiteC/libtomcrypt/hashes/tiger.c @@ -566,7 +566,7 @@ static const ulong64 table[4*256] = { CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */}; /* one round of the hash function */ -static LTC_INLINE void s_tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul) +LTC_INLINE static void tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul) { ulong64 tmp; tmp = (*c ^= x); @@ -582,14 +582,14 @@ static LTC_INLINE void s_tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 /* one complete pass */ static void s_pass(ulong64 *a, ulong64 *b, ulong64 *c, const ulong64 *x, int mul) { - s_tiger_round(a,b,c,x[0],mul); - s_tiger_round(b,c,a,x[1],mul); - s_tiger_round(c,a,b,x[2],mul); - s_tiger_round(a,b,c,x[3],mul); - s_tiger_round(b,c,a,x[4],mul); - s_tiger_round(c,a,b,x[5],mul); - s_tiger_round(a,b,c,x[6],mul); - s_tiger_round(b,c,a,x[7],mul); + tiger_round(a,b,c,x[0],mul); + tiger_round(b,c,a,x[1],mul); + tiger_round(c,a,b,x[2],mul); + tiger_round(a,b,c,x[3],mul); + tiger_round(b,c,a,x[4],mul); + tiger_round(c,a,b,x[5],mul); + tiger_round(a,b,c,x[6],mul); + tiger_round(b,c,a,x[7],mul); } /* The key mixing schedule */ diff --git a/Sources/DataLiteC/libtomcrypt/hashes/whirl/whirl.c b/Sources/DataLiteC/libtomcrypt/hashes/whirl/whirl.c index 802cdc3..c1e4616 100644 --- a/Sources/DataLiteC/libtomcrypt/hashes/whirl/whirl.c +++ b/Sources/DataLiteC/libtomcrypt/hashes/whirl/whirl.c @@ -281,7 +281,7 @@ int whirlpool_test(void) unsigned char tmp[64]; hash_state md; - for (i = 0; i < (int)LTC_ARRAY_SIZE(tests); i++) { + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { whirlpool_init(&md); whirlpool_process(&md, (unsigned char *)tests[i].msg, tests[i].len); whirlpool_done(&md, tmp); diff --git a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_cfg.h b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_cfg.h index af828e2..38eca37 100644 --- a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_cfg.h +++ b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_cfg.h @@ -295,14 +295,6 @@ typedef unsigned long ltc_mp_digit; #define LTC_HAVE_ROTATE_BUILTIN #endif -#if __has_builtin(__builtin_clzl) - #define LTC_HAVE_CLZL_BUILTIN -#endif - -#if __has_builtin(__builtin_ctzl) - #define LTC_HAVE_CTZL_BUILTIN -#endif - #if defined(__GNUC__) #define LTC_ALIGN(n) __attribute__((aligned(n))) #else diff --git a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_cipher.h b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_cipher.h index 60e6c9a..9ba04fe 100644 --- a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_cipher.h +++ b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_cipher.h @@ -274,14 +274,18 @@ typedef struct { #ifdef LTC_CFB_MODE /** A block cipher CFB structure */ typedef struct { - /** The ECB context of the cipher */ - symmetric_ECB ecb; /** The current IV */ unsigned char IV[MAXBLOCKSIZE], /** The pad used to encrypt/decrypt */ pad[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, /** The width of the mode: 1, 8, 64, or 128 */ - int width, + width, /** The padding offset */ padlen; } symmetric_CFB; @@ -290,23 +294,30 @@ typedef struct { #ifdef LTC_OFB_MODE /** A block cipher OFB structure */ typedef struct { - /** The ECB context of the cipher */ - symmetric_ECB ecb; /** The current IV */ unsigned char IV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, /** The padding offset */ - int padlen; - + padlen; } symmetric_OFB; #endif #ifdef LTC_CBC_MODE /** A block cipher CBC structure */ typedef struct { - /** The ECB context of the cipher */ - symmetric_ECB ecb; /** The current IV */ unsigned char IV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen; } symmetric_CBC; #endif @@ -314,15 +325,19 @@ typedef struct { #ifdef LTC_CTR_MODE /** A block cipher CTR structure */ typedef struct { - /** The ECB context of the cipher */ - symmetric_ECB ecb; /** The counter */ unsigned char ctr[MAXBLOCKSIZE]; /** The pad used to encrypt/decrypt */ unsigned char pad[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, /** The padding offset */ - int padlen, + padlen, /** The mode (endianess) of the CTR, 0==little, 1==big */ mode, /** counter width */ @@ -334,14 +349,18 @@ typedef struct { #ifdef LTC_LRW_MODE /** A LRW structure */ typedef struct { - /** The ECB context of the cipher */ - symmetric_ECB ecb; /** The current IV */ unsigned char IV[16], + /** the tweak key */ tweak[16], + /** The current pad, it's the product of the first 15 bytes against the tweak key */ pad[16]; + + /** The scheduled symmetric key */ + symmetric_key key; + #ifdef LTC_LRW_TABLES /** The pre-computed multiplication table */ unsigned char PC[16][256][16]; @@ -355,13 +374,17 @@ typedef struct { #ifdef LTC_F8_MODE /** A block cipher F8 structure */ typedef struct { - /** The ECB context of the cipher */ - symmetric_ECB ecb; /** The current IV */ unsigned char IV[MAXBLOCKSIZE], MIV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, /** The padding offset */ - int padlen; + padlen; /** Current block count */ ulong32 blockcnt; } symmetric_F8; @@ -428,7 +451,7 @@ extern struct ltc_cipher_descriptor { @param skey The scheduled key context @return CRYPT_OK if successful */ - int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, const symmetric_key *skey); + int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey); /** Accelerated ECB decryption @param pt Plaintext @@ -437,7 +460,7 @@ extern struct ltc_cipher_descriptor { @param skey The scheduled key context @return CRYPT_OK if successful */ - int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, const symmetric_key *skey); + int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey); /** Accelerated CBC encryption @param pt Plaintext @@ -447,7 +470,7 @@ extern struct ltc_cipher_descriptor { @param skey The scheduled key context @return CRYPT_OK if successful */ - int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const symmetric_key *skey); + int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey); /** Accelerated CBC decryption @param pt Plaintext @@ -457,7 +480,7 @@ extern struct ltc_cipher_descriptor { @param skey The scheduled key context @return CRYPT_OK if successful */ - int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const symmetric_key *skey); + int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey); /** Accelerated CTR encryption @param pt Plaintext @@ -468,7 +491,7 @@ extern struct ltc_cipher_descriptor { @param skey The scheduled key context @return CRYPT_OK if successful */ - int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, const symmetric_key *skey); + int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); /** Accelerated LRW @param pt Plaintext @@ -479,7 +502,7 @@ extern struct ltc_cipher_descriptor { @param skey The scheduled key context @return CRYPT_OK if successful */ - int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, const symmetric_key *skey); + int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); /** Accelerated LRW @param ct Ciphertext @@ -490,7 +513,7 @@ extern struct ltc_cipher_descriptor { @param skey The scheduled key context @return CRYPT_OK if successful */ - int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, const symmetric_key *skey); + int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); /** Accelerated CCM packet (one-shot) @param key The secret key to use @@ -510,7 +533,7 @@ extern struct ltc_cipher_descriptor { */ int (*accel_ccm_memory)( const unsigned char *key, unsigned long keylen, - const symmetric_key *uskey, + symmetric_key *uskey, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, unsigned char *pt, unsigned long ptlen, @@ -900,8 +923,8 @@ extern const struct ltc_cipher_descriptor tea_desc; #ifdef LTC_ECB_MODE int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb); -int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, const symmetric_ECB *ecb); -int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, const symmetric_ECB *ecb); +int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb); +int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb); int ecb_done(symmetric_ECB *ecb); #endif @@ -993,7 +1016,7 @@ int f8_test_mode(void); #ifdef LTC_XTS_MODE typedef struct { - symmetric_ECB key1, key2; + symmetric_key key1, key2; int cipher; } symmetric_xts; diff --git a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_custom.h b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_custom.h index 31440b4..b1731b9 100644 --- a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_custom.h +++ b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_custom.h @@ -710,18 +710,6 @@ #error LTC_NO_MATH defined, but also a math descriptor #endif -#if !defined(LTC_ECB_MODE) -#if defined(LTC_CFB_MODE) || defined(LTC_OFB_MODE) || defined(LTC_CBC_MODE) || defined(LTC_CTR_MODE) || \ - defined(LTC_F8_MODE) || defined(LTC_LRW_MODE) || defined(LTC_XTS_MODE) ) - #error LTC_ECB_MODE not defined, but all other modes depend on it -#endif -#if defined(LTC_OMAC) || defined(LTC_PMAC) || defined(LTC_XCBC) || defined(LTC_F9_MODE) || defined(LTC_EAX_MODE) || \ - defined(LTC_OCB_MODE) || defined(LTC_OCB3_MODE) || defined(LTC_CCM_MODE) || defined(LTC_GCM_MODE) ) - #error LTC_ECB_MODE not defined, but most MAC and AEAD modes depend on it -#endif -#endif - - /* THREAD management */ #ifdef LTC_PTHREAD diff --git a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_mac.h b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_mac.h index 2e067bc..3ca09ff 100644 --- a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_mac.h +++ b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_mac.h @@ -29,12 +29,13 @@ int hmac_file(int hash, const char *fname, const unsigned char *key, #ifdef LTC_OMAC typedef struct { - int buflen, + int cipher_idx, + buflen, blklen; unsigned char block[MAXBLOCKSIZE], prev[MAXBLOCKSIZE], Lu[2][MAXBLOCKSIZE]; - symmetric_ECB key; + symmetric_key key; } omac_state; int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); @@ -65,9 +66,10 @@ typedef struct { block[MAXBLOCKSIZE], /* currently accumulated block */ checksum[MAXBLOCKSIZE]; /* current checksum */ - symmetric_ECB key; /* scheduled key for cipher */ + symmetric_key key; /* scheduled key for cipher */ unsigned long block_index; /* index # for current block */ - int block_len, /* length of block */ + int cipher_idx, /* cipher idx */ + block_len, /* length of block */ buflen; /* number of bytes in the buffer */ } pmac_state; @@ -179,9 +181,10 @@ typedef struct { unsigned char K[3][MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; - symmetric_ECB key; + symmetric_key key; - int buflen, + int cipher, + buflen, blocksize; } xcbc_state; @@ -212,7 +215,7 @@ typedef struct { ACC[MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; - symmetric_ECB key; + symmetric_key key; int cipher, buflen, @@ -294,9 +297,10 @@ typedef struct { R[MAXBLOCKSIZE], /* R value */ checksum[MAXBLOCKSIZE]; /* current checksum */ - symmetric_ECB key; /* scheduled key for cipher */ + symmetric_key key; /* scheduled key for cipher */ unsigned long block_index; /* index # for current block */ - int block_len; /* length of block */ + int cipher, /* cipher idx */ + block_len; /* length of block */ } ocb_state; int ocb_init(ocb_state *ocb, int cipher, @@ -355,11 +359,12 @@ typedef struct { aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */ adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */ - symmetric_ECB key; /* scheduled key for cipher */ + symmetric_key key; /* scheduled key for cipher */ int adata_buffer_bytes; /* bytes in AAD buffer */ unsigned long ablock_index; /* index # for current adata (AAD) block */ unsigned long block_index; /* index # for current data block */ - int tag_len, /* length of tag */ + int cipher, /* cipher idx */ + tag_len, /* length of tag */ block_len; /* length of block */ } ocb3_state; @@ -402,13 +407,14 @@ int ocb3_test(void); #define CCM_DECRYPT LTC_DECRYPT typedef struct { - symmetric_ECB K; unsigned char PAD[16], /* flags | Nonce N | l(m) */ ctr[16], CTRPAD[16]; + symmetric_key K; - int taglen, /* length of the tag (encoded in M value) */ + int cipher, /* which cipher */ + taglen, /* length of the tag (encoded in M value) */ x; /* index in PAD */ unsigned long L, /* L value */ @@ -442,7 +448,7 @@ int ccm_done(ccm_state *ccm, int ccm_memory(int cipher, const unsigned char *key, unsigned long keylen, - symmetric_ECB *uskey, + symmetric_key *uskey, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, unsigned char *pt, unsigned long ptlen, @@ -474,7 +480,6 @@ extern const unsigned char gcm_shift_table[]; #define LTC_GCM_MODE_TEXT 2 typedef struct { - symmetric_ECB K; unsigned char H[16], /* multiplier */ X[16], /* accumulator */ Y[16], /* counter */ @@ -484,7 +489,11 @@ typedef struct { #ifdef LTC_GCM_TABLES unsigned char PC[16][256][16]; /* 16 tables of 8x128 */ #endif - int ivmode, /* Which mode is the IV in? */ + + symmetric_key K; + + int cipher, /* which cipher */ + ivmode, /* Which mode is the IV in? */ mode, /* mode the GCM code is in */ buflen; /* length of data in buf */ diff --git a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_pk.h b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_pk.h index c4a2017..8ba34d8 100644 --- a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_pk.h +++ b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_pk.h @@ -281,18 +281,8 @@ typedef struct { /** The private key */ void *k; - - /** The hash algorithm to use when creating a signature. - * Setting this will enable RFC6979 compatible signature generation. - * The macro ECC_SET_RFC6979_HASH_ALG() is provided as a helper - * to set this.*/ - const char *rfc6979_hash_alg; } ecc_key; -#define ECC_SET_RFC6979_HASH_ALG(key, alg) do { \ - (key)->rfc6979_hash_alg = (alg); \ -} while(0) - /** Formats of ECC signatures */ typedef enum ecc_signature_type_ { /* ASN.1 encoded, ANSI X9.62 */ @@ -844,6 +834,7 @@ int der_encode_object_identifier(const unsigned long *words, unsigned long nwor int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, unsigned long *words, unsigned long *outlen); int der_length_object_identifier(const unsigned long *words, unsigned long nwords, unsigned long *outlen); +unsigned long der_object_identifier_bits(unsigned long x); /* IA5 STRING */ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, @@ -852,6 +843,9 @@ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); +int der_ia5_char_encode(int c); +int der_ia5_value_decode(int v); + /* TELETEX STRING */ int der_decode_teletex_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); @@ -864,6 +858,9 @@ int der_decode_printable_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); +int der_printable_char_encode(int c); +int der_printable_value_decode(int v); + /* UTF-8 */ #if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(__WCHAR_MAX__) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR) #if defined(__WCHAR_MAX__) @@ -883,6 +880,7 @@ int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, wchar_t *out, unsigned long *outlen); +unsigned long der_utf8_charsize(const wchar_t c); int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen); diff --git a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_private.h b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_private.h index 7069b16..f6b0bc2 100644 --- a/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_private.h +++ b/Sources/DataLiteC/libtomcrypt/headers/tomcrypt_private.h @@ -45,8 +45,6 @@ LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*) #define LTC_NULL ((void *)0) #endif -#define LTC_ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) - /* * Internal Enums */ @@ -124,10 +122,6 @@ typedef struct { /* tomcrypt_cipher.h */ -int ecb_encrypt_block(const unsigned char *pt, unsigned char *ct, const symmetric_ECB *ecb); -int ecb_decrypt_block(const unsigned char *ct, unsigned char *pt, const symmetric_ECB *ecb); - - void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey); int blowfish_expand(const unsigned char *key, int keylen, const unsigned char *data, int datalen, @@ -363,7 +357,6 @@ struct get_char { } data; struct str unget_buf; char unget_buf_[LTC_PEM_DECODE_BUFSZ]; - int prev_get; }; #endif @@ -390,7 +383,7 @@ int pem_decrypt(unsigned char *data, unsigned long *datalen, int pem_get_char_from_file(struct get_char *g); #endif /* LTC_NO_FILE */ int pem_get_char_from_buf(struct get_char *g); -int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, struct get_char *g); +int pem_read(void *pem, unsigned long *w, struct pem_headers *hdr, struct get_char *g); #endif /* tomcrypt_pk.h */ @@ -448,8 +441,6 @@ int ecc_verify_hash_internal(void *r, void *s, const unsigned char *hash, unsigned long hashlen, int *stat, const ecc_key *key); -int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long inlen, ecc_key *key); - #ifdef LTC_SSH int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key); #endif @@ -588,17 +579,6 @@ int der_length_asn1_length(unsigned long len, unsigned long *outlen); int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen, unsigned long *payloadlen); -int der_length_object_identifier_full(const unsigned long *words, unsigned long nwords, - unsigned long *outlen, unsigned long *datalen); - -int der_ia5_char_encode(int c); -int der_ia5_value_decode(int v); - -int der_printable_char_encode(int c); -int der_printable_value_decode(int v); - -unsigned long der_utf8_charsize(const wchar_t c); - typedef struct { ltc_asn1_type t; ltc_asn1_list **pp; diff --git a/Sources/DataLiteC/libtomcrypt/mac/f9/f9_done.c b/Sources/DataLiteC/libtomcrypt/mac/f9/f9_done.c index 596a33b..38d1371 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/f9/f9_done.c +++ b/Sources/DataLiteC/libtomcrypt/mac/f9/f9_done.c @@ -33,7 +33,7 @@ int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen) if (f9->buflen != 0) { /* encrypt */ - ecb_encrypt_block(f9->IV, f9->IV, &f9->key); + cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); f9->buflen = 0; for (x = 0; x < f9->blocksize; x++) { f9->ACC[x] ^= f9->IV[x]; @@ -41,13 +41,13 @@ int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen) } /* schedule modified key */ - if ((err = ecb_start(f9->cipher, f9->akey, f9->keylen, 0, &f9->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[f9->cipher].setup(f9->akey, f9->keylen, 0, &f9->key)) != CRYPT_OK) { return err; } /* encrypt the ACC */ - ecb_encrypt_block(f9->ACC, f9->ACC, &f9->key); - ecb_done(&f9->key); + cipher_descriptor[f9->cipher].ecb_encrypt(f9->ACC, f9->ACC, &f9->key); + cipher_descriptor[f9->cipher].done(&f9->key); /* extract tag */ for (x = 0; x < f9->blocksize && (unsigned long)x < *outlen; x++) { diff --git a/Sources/DataLiteC/libtomcrypt/mac/f9/f9_init.c b/Sources/DataLiteC/libtomcrypt/mac/f9/f9_init.c index 8a6e630..60e25dc 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/f9/f9_init.c +++ b/Sources/DataLiteC/libtomcrypt/mac/f9/f9_init.c @@ -38,7 +38,7 @@ int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long ke } #endif - if ((err = ecb_start(cipher, key, keylen, 0, &f9->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &f9->key)) != CRYPT_OK) { goto done; } diff --git a/Sources/DataLiteC/libtomcrypt/mac/f9/f9_process.c b/Sources/DataLiteC/libtomcrypt/mac/f9/f9_process.c index 8860da3..e416b54 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/f9/f9_process.c +++ b/Sources/DataLiteC/libtomcrypt/mac/f9/f9_process.c @@ -38,7 +38,7 @@ int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen) for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) { *(LTC_FAST_TYPE_PTR_CAST(&(f9->IV[x]))) ^= *(LTC_FAST_TYPE_PTR_CAST(&(in[x]))); } - ecb_encrypt_block(f9->IV, f9->IV, &f9->key); + cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) { *(LTC_FAST_TYPE_PTR_CAST(&(f9->ACC[x]))) ^= *(LTC_FAST_TYPE_PTR_CAST(&(f9->IV[x]))); } @@ -50,7 +50,7 @@ int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen) while (inlen) { if (f9->buflen == f9->blocksize) { - ecb_encrypt_block(f9->IV, f9->IV, &f9->key); + cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); for (x = 0; x < f9->blocksize; x++) { f9->ACC[x] ^= f9->IV[x]; } diff --git a/Sources/DataLiteC/libtomcrypt/mac/f9/f9_test.c b/Sources/DataLiteC/libtomcrypt/mac/f9/f9_test.c index 2616d42..779fdf1 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/f9/f9_test.c +++ b/Sources/DataLiteC/libtomcrypt/mac/f9/f9_test.c @@ -48,7 +48,7 @@ int f9_test(void) return CRYPT_NOP; } - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { taglen = 4; if ((err = f9_memory(idx, tests[x].K, 16, tests[x].M, tests[x].msglen, T, &taglen)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/mac/omac/omac_done.c b/Sources/DataLiteC/libtomcrypt/mac/omac/omac_done.c index 7997d7a..c60067f 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/omac/omac_done.c +++ b/Sources/DataLiteC/libtomcrypt/mac/omac/omac_done.c @@ -24,6 +24,9 @@ int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen) LTC_ARGCHK(omac != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); + if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) { + return err; + } if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) || (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) { @@ -50,10 +53,10 @@ int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen) } /* encrypt it */ - if ((err = ecb_encrypt_block(omac->block, omac->block, &omac->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key)) != CRYPT_OK) { return err; } - ecb_done(&omac->key); + cipher_descriptor[omac->cipher_idx].done(&omac->key); /* output it */ for (x = 0; x < (unsigned)omac->blklen && x < *outlen; x++) { diff --git a/Sources/DataLiteC/libtomcrypt/mac/omac/omac_init.c b/Sources/DataLiteC/libtomcrypt/mac/omac/omac_init.c index f2e9857..440bc01 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/omac/omac_init.c +++ b/Sources/DataLiteC/libtomcrypt/mac/omac/omac_init.c @@ -51,7 +51,7 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l default: return CRYPT_INVALID_ARG; } - if ((err = ecb_start(cipher, key, keylen, 0, &omac->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) { return err; } @@ -59,7 +59,7 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l /* first calc L which is Ek(0) */ zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length); - if ((err = ecb_encrypt_block(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) { return err; } @@ -81,6 +81,7 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l } /* setup state */ + omac->cipher_idx = cipher; omac->buflen = 0; omac->blklen = len; zeromem(omac->prev, sizeof(omac->prev)); diff --git a/Sources/DataLiteC/libtomcrypt/mac/omac/omac_process.c b/Sources/DataLiteC/libtomcrypt/mac/omac/omac_process.c index 35ee9d2..b8e3160 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/omac/omac_process.c +++ b/Sources/DataLiteC/libtomcrypt/mac/omac/omac_process.c @@ -24,6 +24,9 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) LTC_ARGCHK(omac != NULL); LTC_ARGCHK(in != NULL); + if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) { + return err; + } if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) || (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) { @@ -31,17 +34,22 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) } #ifdef LTC_FAST - if (omac->buflen == 0 && inlen > (unsigned long)omac->blklen) { - for (x = 0; x < (inlen - omac->blklen); x += omac->blklen) { - for (n = 0; n < (unsigned long)omac->blklen; n += sizeof(LTC_FAST_TYPE)) { - *(LTC_FAST_TYPE_PTR_CAST(&omac->prev[n])) ^= *(LTC_FAST_TYPE_PTR_CAST(&in[n])); - } - in += omac->blklen; - if ((err = ecb_encrypt_block(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) { - return err; - } - } - inlen -= x; + { + unsigned long blklen = cipher_descriptor[omac->cipher_idx].block_length; + + if (omac->buflen == 0 && inlen > blklen) { + unsigned long y; + for (x = 0; x < (inlen - blklen); x += blklen) { + for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) { + *(LTC_FAST_TYPE_PTR_CAST(&omac->prev[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&in[y])); + } + in += blklen; + if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) { + return err; + } + } + inlen -= x; + } } #endif @@ -51,7 +59,7 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) for (x = 0; x < (unsigned long)omac->blklen; x++) { omac->block[x] ^= omac->prev[x]; } - if ((err = ecb_encrypt_block(omac->block, omac->prev, &omac->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) { return err; } omac->buflen = 0; diff --git a/Sources/DataLiteC/libtomcrypt/mac/omac/omac_test.c b/Sources/DataLiteC/libtomcrypt/mac/omac/omac_test.c index c797794..bca6d9c 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/omac/omac_test.c +++ b/Sources/DataLiteC/libtomcrypt/mac/omac/omac_test.c @@ -76,7 +76,7 @@ int omac_test(void) } } - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { len = sizeof(out); if ((err = omac_memory(idx, tests[x].key, tests[x].keylen, tests[x].msg, tests[x].msglen, out, &len)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/mac/pelican/pelican_test.c b/Sources/DataLiteC/libtomcrypt/mac/pelican/pelican_test.c index 31a237c..2ec696a 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/pelican/pelican_test.c +++ b/Sources/DataLiteC/libtomcrypt/mac/pelican/pelican_test.c @@ -80,7 +80,7 @@ int pelican_test(void) unsigned char out[16]; pelican_state pel; - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = pelican_init(&pel, tests[x].K, tests[x].keylen)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_done.c b/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_done.c index bcad06a..222790d 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_done.c +++ b/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_done.c @@ -15,6 +15,9 @@ int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen) LTC_ARGCHK(pmac != NULL); LTC_ARGCHK(out != NULL); + if ((err = cipher_is_valid(pmac->cipher_idx)) != CRYPT_OK) { + return err; + } if ((pmac->buflen > (int)sizeof(pmac->block)) || (pmac->buflen < 0) || (pmac->block_len > (int)sizeof(pmac->block)) || (pmac->buflen > pmac->block_len)) { @@ -38,10 +41,10 @@ int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen) } /* encrypt it */ - if ((err = ecb_encrypt_block(pmac->checksum, pmac->checksum, &pmac->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(pmac->checksum, pmac->checksum, &pmac->key)) != CRYPT_OK) { return err; } - ecb_done(&pmac->key); + cipher_descriptor[pmac->cipher_idx].done(&pmac->key); /* store it */ for (x = 0; x < pmac->block_len && x < (int)*outlen; x++) { diff --git a/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_init.c b/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_init.c index fb5daa9..9787e6a 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_init.c +++ b/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_init.c @@ -55,12 +55,12 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l /* determine which polys to use */ pmac->block_len = cipher_descriptor[cipher].block_length; - for (poly = 0; poly < (int)LTC_ARRAY_SIZE(polys); poly++) { + for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { if (polys[poly].len == pmac->block_len) { break; } } - if (poly >= (int)LTC_ARRAY_SIZE(polys)) { + if (poly >= (int)(sizeof(polys)/sizeof(polys[0]))) { return CRYPT_INVALID_ARG; } if (polys[poly].len != pmac->block_len) { @@ -75,7 +75,7 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l /* schedule the key */ - if ((err = ecb_start(cipher, key, keylen, 0, &pmac->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) { return err; } @@ -87,7 +87,7 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l /* find L = E[0] */ zeromem(L, pmac->block_len); - if ((err = ecb_encrypt_block(L, L, &pmac->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) { goto error; } @@ -124,6 +124,7 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l /* zero buffer, counters, etc... */ pmac->block_index = 1; + pmac->cipher_idx = cipher; pmac->buflen = 0; zeromem(pmac->block, sizeof(pmac->block)); zeromem(pmac->Li, sizeof(pmac->Li)); diff --git a/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_ntz.c b/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_ntz.c index 86142ba..ed71f33 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_ntz.c +++ b/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_ntz.c @@ -14,11 +14,6 @@ */ int pmac_ntz(unsigned long x) { -#if defined(LTC_HAVE_CTZL_BUILTIN) - if (x == 0) - return sizeof(unsigned long) * CHAR_BIT; - return __builtin_ctzl(x); -#else int c; x &= 0xFFFFFFFFUL; c = 0; @@ -27,7 +22,6 @@ int pmac_ntz(unsigned long x) x >>= 1; } return c; -#endif } #endif diff --git a/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_process.c b/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_process.c index b154aef..7b654f4 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_process.c +++ b/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_process.c @@ -29,6 +29,9 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) LTC_ARGCHK(pmac != NULL); LTC_ARGCHK(in != NULL); + if ((err = cipher_is_valid(pmac->cipher_idx)) != CRYPT_OK) { + return err; + } if ((pmac->buflen > (int)sizeof(pmac->block)) || (pmac->buflen < 0) || (pmac->block_len > (int)sizeof(pmac->block)) || (pmac->buflen > pmac->block_len)) { @@ -43,7 +46,7 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { *(LTC_FAST_TYPE_PTR_CAST(&Z[y])) = *(LTC_FAST_TYPE_PTR_CAST(&in[y])) ^ *(LTC_FAST_TYPE_PTR_CAST(&pmac->Li[y])); } - if ((err = ecb_encrypt_block(Z, Z, &pmac->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { return err; } for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { @@ -62,7 +65,7 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) for (x = 0; x < (unsigned long)pmac->block_len; x++) { Z[x] = pmac->Li[x] ^ pmac->block[x]; } - if ((err = ecb_encrypt_block(Z, Z, &pmac->key)) != CRYPT_OK) { + if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { return err; } for (x = 0; x < (unsigned long)pmac->block_len; x++) { diff --git a/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_test.c b/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_test.c index ccbd6c6..3ccf06e 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_test.c +++ b/Sources/DataLiteC/libtomcrypt/mac/pmac/pmac_test.c @@ -124,7 +124,7 @@ int pmac_test(void) } } - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { len = sizeof(outtag); if ((err = pmac_memory(idx, tests[x].key, 16, tests[x].msg, tests[x].msglen, outtag, &len)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_done.c b/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_done.c index 4163e22..7da72f3 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_done.c +++ b/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_done.c @@ -17,11 +17,17 @@ */ int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen) { - int x; + int err, x; LTC_ARGCHK(xcbc != NULL); LTC_ARGCHK(out != NULL); - if ((xcbc->blocksize < 0) || (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) { + /* check structure */ + if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) { + return err; + } + + if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) || + (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) { return CRYPT_INVALID_ARG; } @@ -40,8 +46,8 @@ int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen) } /* encrypt */ - ecb_encrypt_block(xcbc->IV, xcbc->IV, &xcbc->key); - ecb_done(&xcbc->key); + cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); + cipher_descriptor[xcbc->cipher].done(&xcbc->key); /* extract tag */ for (x = 0; x < xcbc->blocksize && (unsigned long)x < *outlen; x++) { diff --git a/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_init.c b/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_init.c index 10c55da..a80f9e4 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_init.c +++ b/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_init.c @@ -23,7 +23,7 @@ int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen) { int x, y, err; - symmetric_ECB *skey; + symmetric_key *skey; unsigned long k1; LTC_ARGCHK(xcbc != NULL); @@ -64,7 +64,7 @@ int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned l return CRYPT_MEM; } - if ((err = ecb_start(cipher, key, keylen, 0, skey)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { goto done; } @@ -73,19 +73,20 @@ int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned l for (x = 0; x < cipher_descriptor[cipher].block_length; x++) { xcbc->K[y][x] = y + 1; } - ecb_encrypt_block(xcbc->K[y], xcbc->K[y], skey); + cipher_descriptor[cipher].ecb_encrypt(xcbc->K[y], xcbc->K[y], skey); } } /* setup K1 */ - err = ecb_start(cipher, xcbc->K[0], k1, 0, &xcbc->key); + err = cipher_descriptor[cipher].setup(xcbc->K[0], k1, 0, &xcbc->key); /* setup struct */ zeromem(xcbc->IV, cipher_descriptor[cipher].block_length); xcbc->blocksize = cipher_descriptor[cipher].block_length; + xcbc->cipher = cipher; xcbc->buflen = 0; done: - ecb_done(skey); + cipher_descriptor[cipher].done(skey); if (skey != NULL) { #ifdef LTC_CLEAN_STACK zeromem(skey, sizeof(*skey)); diff --git a/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_process.c b/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_process.c index a6e5145..3cb0c46 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_process.c +++ b/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_process.c @@ -17,6 +17,7 @@ */ int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen) { + int err; #ifdef LTC_FAST int x; #endif @@ -24,7 +25,13 @@ int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen) LTC_ARGCHK(xcbc != NULL); LTC_ARGCHK(in != NULL); - if ((xcbc->blocksize < 0) || (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) { + /* check structure */ + if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) { + return err; + } + + if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) || + (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) { return CRYPT_INVALID_ARG; } @@ -34,7 +41,7 @@ int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen) for (x = 0; x < xcbc->blocksize; x += sizeof(LTC_FAST_TYPE)) { *(LTC_FAST_TYPE_PTR_CAST(&(xcbc->IV[x]))) ^= *(LTC_FAST_TYPE_PTR_CAST(&(in[x]))); } - ecb_encrypt_block(xcbc->IV, xcbc->IV, &xcbc->key); + cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); in += xcbc->blocksize; inlen -= xcbc->blocksize; } @@ -43,7 +50,7 @@ int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen) while (inlen) { if (xcbc->buflen == xcbc->blocksize) { - ecb_encrypt_block(xcbc->IV, xcbc->IV, &xcbc->key); + cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); xcbc->buflen = 0; } xcbc->IV[xcbc->buflen++] ^= *in++; diff --git a/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_test.c b/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_test.c index 2c61105..23555de 100644 --- a/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_test.c +++ b/Sources/DataLiteC/libtomcrypt/mac/xcbc/xcbc_test.c @@ -98,7 +98,7 @@ int xcbc_test(void) } } - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { taglen = 16; if ((err = xcbc_memory(idx, tests[x].K, 16, tests[x].M, tests[x].msglen, T, &taglen)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/math/ltm_desc.c b/Sources/DataLiteC/libtomcrypt/math/ltm_desc.c index 99c9f14..a7df222 100644 --- a/Sources/DataLiteC/libtomcrypt/math/ltm_desc.c +++ b/Sources/DataLiteC/libtomcrypt/math/ltm_desc.c @@ -33,7 +33,7 @@ static int mpi_to_ltc_error(mp_err err) { size_t x; - for (x = 0; x < LTC_ARRAY_SIZE(mpi_to_ltc_codes); x++) { + for (x = 0; x < sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0]); x++) { if (err == mpi_to_ltc_codes[x].mpi_code) { return mpi_to_ltc_codes[x].ltc_code; } diff --git a/Sources/DataLiteC/libtomcrypt/math/tfm_desc.c b/Sources/DataLiteC/libtomcrypt/math/tfm_desc.c index 7c3b400..94a1d78 100644 --- a/Sources/DataLiteC/libtomcrypt/math/tfm_desc.c +++ b/Sources/DataLiteC/libtomcrypt/math/tfm_desc.c @@ -39,7 +39,7 @@ static int tfm_to_ltc_error(int err) { int x; - for (x = 0; x < (int)LTC_ARRAY_SIZE(tfm_to_ltc_codes); x++) { + for (x = 0; x < (int)(sizeof(tfm_to_ltc_codes)/sizeof(tfm_to_ltc_codes[0])); x++) { if (err == tfm_to_ltc_codes[x].tfm_code) { return tfm_to_ltc_codes[x].ltc_code; } diff --git a/Sources/DataLiteC/libtomcrypt/misc/base16/base16_encode.c b/Sources/DataLiteC/libtomcrypt/misc/base16/base16_encode.c index 206827c..649a4d8 100644 --- a/Sources/DataLiteC/libtomcrypt/misc/base16/base16_encode.c +++ b/Sources/DataLiteC/libtomcrypt/misc/base16/base16_encode.c @@ -52,11 +52,10 @@ int base16_encode(const unsigned char *in, unsigned long inlen, alphabet = alphabets[1]; } - for (i = x; i > 0; i -= 2) { - out[i-2] = alphabet[(in[(i-1)/2] >> 4) & 0x0f]; - out[i-1] = alphabet[in[(i-1)/2] & 0x0f]; + for (i = 0; i < x; i += 2) { + out[i] = alphabet[(in[i/2] >> 4) & 0x0f]; + out[i+1] = alphabet[in[i/2] & 0x0f]; } - out[x] = '\0'; return CRYPT_OK; diff --git a/Sources/DataLiteC/libtomcrypt/misc/crypt/crypt.c b/Sources/DataLiteC/libtomcrypt/misc/crypt/crypt.c index 61b5cd0..c4675de 100644 --- a/Sources/DataLiteC/libtomcrypt/misc/crypt/crypt.c +++ b/Sources/DataLiteC/libtomcrypt/misc/crypt/crypt.c @@ -548,15 +548,6 @@ const char *crypt_build_settings = " LTC_NO_ROLC " #endif #endif -#if defined(LTC_HAVE_ROTATE_BUILTIN) - " LTC_HAVE_ROTATE_BUILTIN " -#endif -#if defined(LTC_HAVE_CLZL_BUILTIN) - " LTC_HAVE_CLZL_BUILTIN " -#endif -#if defined(LTC_HAVE_CTZL_BUILTIN) - " LTC_HAVE_CTZL_BUILTIN " -#endif #if defined(LTC_NO_TEST) " LTC_NO_TEST " #endif diff --git a/Sources/DataLiteC/libtomcrypt/misc/crypt/crypt_register_all_hashes.c b/Sources/DataLiteC/libtomcrypt/misc/crypt/crypt_register_all_hashes.c index 362205f..328e84a 100644 --- a/Sources/DataLiteC/libtomcrypt/misc/crypt/crypt_register_all_hashes.c +++ b/Sources/DataLiteC/libtomcrypt/misc/crypt/crypt_register_all_hashes.c @@ -89,13 +89,8 @@ int register_all_hashes(void) REGISTER_HASH(&blake2b_512_desc); #endif #ifdef LTC_CHC_HASH - { - int aes_index = find_cipher_any("aes", 8, 16); - if (aes_index != -1) { - REGISTER_HASH(&chc_desc); - LTC_ARGCHK(chc_register(aes_index) == CRYPT_OK); - } - } + REGISTER_HASH(&chc_desc); + LTC_ARGCHK(chc_register(find_cipher_any("aes", 8, 16)) == CRYPT_OK); #endif return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/misc/error_to_string.c b/Sources/DataLiteC/libtomcrypt/misc/error_to_string.c index fd306bb..631fdbc 100644 --- a/Sources/DataLiteC/libtomcrypt/misc/error_to_string.c +++ b/Sources/DataLiteC/libtomcrypt/misc/error_to_string.c @@ -54,7 +54,7 @@ static const char * const err_2_str[CRYPT_ERR_NUM] = "The PEM header was not recognized", }; -LTC_STATIC_ASSERT(correct_err_2_str_size, LTC_ARRAY_SIZE(err_2_str) == CRYPT_ERR_NUM) +LTC_STATIC_ASSERT(correct_err_2_str_size, (sizeof(err_2_str)/sizeof(err_2_str[0])) == CRYPT_ERR_NUM) /** Convert an LTC error code to ASCII diff --git a/Sources/DataLiteC/libtomcrypt/misc/pbes/pbes2.c b/Sources/DataLiteC/libtomcrypt/misc/pbes/pbes2.c index 75d17d3..cfb3426 100644 --- a/Sources/DataLiteC/libtomcrypt/misc/pbes/pbes2.c +++ b/Sources/DataLiteC/libtomcrypt/misc/pbes/pbes2.c @@ -51,7 +51,7 @@ static const oid_to_pbes s_pbes2_list[] = { static int s_pbes2_from_oid(const ltc_asn1_list *cipher_oid, const ltc_asn1_list *hmac_oid, pbes_properties *res) { unsigned int i; - for (i = 0; i < LTC_ARRAY_SIZE(s_pbes2_list); ++i) { + for (i = 0; i < sizeof(s_pbes2_list)/sizeof(s_pbes2_list[0]); ++i) { if (pk_oid_cmp_with_asn1(s_pbes2_list[i].oid, cipher_oid) == CRYPT_OK) { *res = *s_pbes2_list[i].data; break; @@ -59,7 +59,7 @@ static int s_pbes2_from_oid(const ltc_asn1_list *cipher_oid, const ltc_asn1_list } if (res->c == NULL) return CRYPT_INVALID_CIPHER; if (hmac_oid != NULL) { - for (i = 0; i < LTC_ARRAY_SIZE(s_hmac_oid_names); ++i) { + for (i = 0; i < sizeof(s_hmac_oid_names)/sizeof(s_hmac_oid_names[0]); ++i) { if (pk_oid_cmp_with_asn1(s_hmac_oid_names[i].oid, hmac_oid) == CRYPT_OK) { res->h = s_hmac_oid_names[i].id; return CRYPT_OK; diff --git a/Sources/DataLiteC/libtomcrypt/misc/pem/pem.c b/Sources/DataLiteC/libtomcrypt/misc/pem/pem.c index ca6e350..35a8fac 100644 --- a/Sources/DataLiteC/libtomcrypt/misc/pem/pem.c +++ b/Sources/DataLiteC/libtomcrypt/misc/pem/pem.c @@ -69,7 +69,7 @@ const struct pem_header_id pem_std_headers[] = { .pka = LTC_PKA_DSA, }, }; -const unsigned long pem_std_headers_num = LTC_ARRAY_SIZE(pem_std_headers); +const unsigned long pem_std_headers_num = sizeof(pem_std_headers)/sizeof(pem_std_headers[0]); /* Encrypted PEM files */ const struct str pem_proc_type_encrypted = { SET_CSTR(, "Proc-Type: 4,ENCRYPTED") }; @@ -151,7 +151,7 @@ const struct blockcipher_info pem_dek_infos[] = { .name = "SEED-CFB,", .algo = "seed", .keylen = 128 / 8, .mode = cm_cfb, }, { .name = "SEED-OFB,", .algo = "seed", .keylen = 128 / 8, .mode = cm_ofb, }, }; -const unsigned long pem_dek_infos_num = LTC_ARRAY_SIZE(pem_dek_infos); +const unsigned long pem_dek_infos_num = sizeof(pem_dek_infos)/sizeof(pem_dek_infos[0]); int pem_decrypt(unsigned char *data, unsigned long *datalen, unsigned char *key, unsigned long keylen, @@ -201,7 +201,7 @@ int pem_decrypt(unsigned char *data, unsigned long *datalen, goto error_out; } - if ((err = padding_depad(data, datalen, padding | s.ctx.cbc.ecb.blocklen)) != CRYPT_OK) { + if ((err = padding_depad(data, datalen, padding | s.ctx.cbc.blocklen)) != CRYPT_OK) { goto error_out; } #else diff --git a/Sources/DataLiteC/libtomcrypt/misc/pem/pem_pkcs.c b/Sources/DataLiteC/libtomcrypt/misc/pem/pem_pkcs.c index 682d819..c8fc1bf 100644 --- a/Sources/DataLiteC/libtomcrypt/misc/pem/pem_pkcs.c +++ b/Sources/DataLiteC/libtomcrypt/misc/pem/pem_pkcs.c @@ -16,7 +16,7 @@ extern const struct pem_header_id pem_std_headers[]; extern const unsigned long pem_std_headers_num; -static int s_decrypt_pem(unsigned char *asn1_cert, unsigned long *asn1_len, const struct pem_headers *hdr) +static int s_decrypt_pem(unsigned char *pem, unsigned long *l, const struct pem_headers *hdr) { unsigned char iv[MAXBLOCKSIZE], key[MAXBLOCKSIZE]; unsigned long ivlen, klen; @@ -38,7 +38,7 @@ static int s_decrypt_pem(unsigned char *asn1_cert, unsigned long *asn1_len, cons return err; } - err = pem_decrypt(asn1_cert, asn1_len, key, klen, iv, ivlen, NULL, 0, &hdr->info, LTC_PAD_PKCS7); + err = pem_decrypt(pem, l, key, klen, iv, ivlen, NULL, 0, &hdr->info, LTC_PAD_PKCS7); zeromem(key, sizeof(key)); zeromem(iv, sizeof(iv)); @@ -86,12 +86,12 @@ static const import_fn s_import_x509_fns[LTC_PKA_NUM] = { #endif }; -static int s_import_x509(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k) +static int s_import_x509(unsigned char *pem, unsigned long l, ltc_pka_key *k) { enum ltc_pka_id pka = LTC_PKA_UNDEF; ltc_asn1_list *d, *spki; int err; - if ((err = x509_decode_spki(asn1_cert, asn1_len, &d, &spki)) != CRYPT_OK) { + if ((err = x509_decode_spki(pem, l, &d, &spki)) != CRYPT_OK) { return err; } err = s_get_pka(spki, &pka); @@ -100,23 +100,23 @@ static int s_import_x509(unsigned char *asn1_cert, unsigned long asn1_len, ltc_p return err; } if (pka < 0 - || pka > LTC_ARRAY_SIZE(s_import_x509_fns) + || pka > sizeof(s_import_x509_fns)/sizeof(s_import_x509_fns[0]) || s_import_x509_fns[pka] == NULL) { return CRYPT_PK_INVALID_TYPE; } - if ((err = s_import_x509_fns[pka](asn1_cert, asn1_len, &k->u)) == CRYPT_OK) { + if ((err = s_import_x509_fns[pka](pem, l, &k->u)) == CRYPT_OK) { k->id = pka; } return err; } -static int s_import_pkcs8(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, const password_ctx *pw_ctx) +static int s_import_pkcs8(unsigned char *pem, unsigned long l, ltc_pka_key *k, const password_ctx *pw_ctx) { int err; enum ltc_oid_id pka; ltc_asn1_list *alg_id, *priv_key; ltc_asn1_list *p8_asn1 = NULL; - if ((err = pkcs8_decode_flexi(asn1_cert, asn1_len, pw_ctx, &p8_asn1)) != CRYPT_OK) { + if ((err = pkcs8_decode_flexi(pem, l, pw_ctx, &p8_asn1)) != CRYPT_OK) { goto cleanup; } if ((err = pkcs8_get_children(p8_asn1, &pka, &alg_id, &priv_key)) != CRYPT_OK) { @@ -168,11 +168,11 @@ cleanup: return err; } -static int s_extract_pka(unsigned char *asn1_cert, unsigned long asn1_len, enum ltc_pka_id *pka) +static int s_extract_pka(unsigned char *pem, unsigned long w, enum ltc_pka_id *pka) { ltc_asn1_list *pub; int err = CRYPT_ERROR; - if ((err = der_decode_sequence_flexi(asn1_cert, &asn1_len, &pub)) != CRYPT_OK) { + if ((err = der_decode_sequence_flexi(pem, &w, &pub)) != CRYPT_OK) { return err; } err = s_get_pka(pub, pka); @@ -198,8 +198,8 @@ static const import_fn s_import_openssl_fns[LTC_PKA_NUM] = { static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx) { - unsigned char *asn1_cert = NULL; - unsigned long w, asn1_len, n; + unsigned char *pem = NULL; + unsigned long w, l, n; int err = CRYPT_ERROR; struct pem_headers hdr = { 0 }; struct password pw = { 0 }; @@ -207,10 +207,10 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c XMEMSET(k, 0, sizeof(*k)); w = LTC_PEM_READ_BUFSIZE * 2; retry: - asn1_cert = XREALLOC(asn1_cert, w); + pem = XREALLOC(pem, w); for (n = 0; n < pem_std_headers_num; ++n) { hdr.id = &pem_std_headers[n]; - err = pem_read(asn1_cert, &w, &hdr, g); + err = pem_read(pem, &w, &hdr, g); if (err == CRYPT_BUFFER_OVERFLOW) { goto retry; } else if (err == CRYPT_OK) { @@ -223,15 +223,15 @@ retry: /* id not found */ if (hdr.id == NULL) goto cleanup; - asn1_len = w; + l = w; if (hdr.id->flags & pf_pkcs8) { - err = s_import_pkcs8(asn1_cert, asn1_len, k, pw_ctx); + err = s_import_pkcs8(pem, l, k, pw_ctx); goto cleanup; } else if (hdr.id->flags == pf_x509) { - err = s_import_x509(asn1_cert, asn1_len, k); + err = s_import_x509(pem, l, k); goto cleanup; } else if ((hdr.id->flags & pf_public) && hdr.id->pka == LTC_PKA_UNDEF) { - if ((err = s_extract_pka(asn1_cert, asn1_len, &pka)) != CRYPT_OK) { + if ((err = s_extract_pka(pem, w, &pka)) != CRYPT_OK) { goto cleanup; } } else if (hdr.encrypted) { @@ -246,7 +246,7 @@ retry: goto cleanup; } - if ((err = s_decrypt_pem(asn1_cert, &asn1_len, &hdr)) != CRYPT_OK) { + if ((err = s_decrypt_pem(pem, &l, &hdr)) != CRYPT_OK) { goto cleanup; } pka = hdr.id->pka; @@ -255,18 +255,18 @@ retry: } if (pka < 0 - || pka > LTC_ARRAY_SIZE(s_import_openssl_fns) + || pka > sizeof(s_import_openssl_fns)/sizeof(s_import_openssl_fns[0]) || s_import_openssl_fns[pka] == NULL) { err = CRYPT_PK_INVALID_TYPE; goto cleanup; } - if ((err = s_import_openssl_fns[pka](asn1_cert, asn1_len, &k->u)) == CRYPT_OK) { + if ((err = s_import_openssl_fns[pka](pem, l, &k->u)) == CRYPT_OK) { k->id = pka; } cleanup: password_free(hdr.pw, pw_ctx); - XFREE(asn1_cert); + XFREE(pem); return err; } diff --git a/Sources/DataLiteC/libtomcrypt/misc/pem/pem_read.c b/Sources/DataLiteC/libtomcrypt/misc/pem/pem_read.c index abefff9..3625b1a 100644 --- a/Sources/DataLiteC/libtomcrypt/misc/pem/pem_read.c +++ b/Sources/DataLiteC/libtomcrypt/misc/pem/pem_read.c @@ -62,10 +62,10 @@ static void s_tts(char *buf, unsigned long *buflen) } } -static char* s_get_line_i(char *buf, unsigned long *buflen, struct get_char *g, int search_for_start) +static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g) { - unsigned long blen = 0, wr = 0; - int c_; + unsigned long blen = 0; + int c = -1, c_; if (g->unget_buf.p) { if (*buflen < g->unget_buf.len) { return NULL; @@ -75,44 +75,30 @@ static char* s_get_line_i(char *buf, unsigned long *buflen, struct get_char *g, RESET_STR(g->unget_buf); return buf; } - if (g->prev_get == -1) { - return NULL; - } - while(blen < *buflen || search_for_start) { - wr = blen < *buflen ? blen : *buflen - 1; - c_ = g->prev_get; - g->prev_get = g->get(g); - if (g->prev_get == '\n') { - buf[wr] = '\0'; + while(blen < *buflen) { + c_ = c; + c = g->get(g); + if (c == '\n') { + buf[blen] = '\0'; if (c_ == '\r') { - buf[--wr] = '\0'; + buf[--blen] = '\0'; } - s_tts(buf, &wr); - *buflen = wr; + s_tts(buf, &blen); + *buflen = blen; return buf; } - if (g->prev_get == -1 || g->prev_get == '\0') { - buf[wr] = '\0'; - s_tts(buf, &wr); - *buflen = wr; + if (c == -1 || c == '\0') { + buf[blen] = '\0'; + s_tts(buf, &blen); + *buflen = blen; return buf; } - buf[wr] = g->prev_get; + buf[blen] = c; blen++; } return NULL; } -LTC_INLINE static char* s_get_first_line(char *buf, unsigned long *buflen, struct get_char *g) -{ - return s_get_line_i(buf, buflen, g, 1); -} - -LTC_INLINE static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g) -{ - return s_get_line_i(buf, buflen, g, 0); -} - static LTC_INLINE int s_fits_buf(void *dest, unsigned long to_write, void *end) { unsigned char *d = dest; @@ -190,29 +176,20 @@ static int s_pem_decode_headers(struct pem_headers *hdr, struct get_char *g) return CRYPT_OK; } -int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, struct get_char *g) +int pem_read(void *pem, unsigned long *w, struct pem_headers *hdr, struct get_char *g) { char buf[LTC_PEM_DECODE_BUFSZ]; - char *wpem = asn1_cert; - char *end = wpem + *asn1_len; - const char pem_start[] = "----"; + char *wpem = pem; + char *end = wpem + *w; unsigned long slen, linelen; int err, hdr_ok = 0; int would_overflow = 0; unsigned char empty_lines = 0; - g->prev_get = 0; - do { - linelen = sizeof(buf); - if (s_get_first_line(buf, &linelen, g) == NULL) { - if (g->prev_get == -1) - return CRYPT_NOP; - else - return CRYPT_INVALID_PACKET; - } - if (linelen < sizeof(pem_start) - 1) - continue; - } while(XMEMCMP(buf, pem_start, sizeof(pem_start) - 1) != 0); + linelen = sizeof(buf); + if (s_get_line(buf, &linelen, g) == NULL) { + return CRYPT_INVALID_PACKET; + } if (hdr->id->start.len != linelen || XMEMCMP(buf, hdr->id->start.p, hdr->id->start.len)) { s_unget_line(buf, linelen, g); return CRYPT_UNKNOWN_PEM; @@ -249,16 +226,16 @@ int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, /* NUL termination */ wpem++; /* prevent a wrap-around */ - if (wpem < (char*)asn1_cert) + if (wpem < (char*)pem) return CRYPT_OVERFLOW; - *asn1_len = wpem - (char*)asn1_cert; + *w = wpem - (char*)pem; return CRYPT_BUFFER_OVERFLOW; } - *asn1_len = wpem - (char*)asn1_cert; + *w = wpem - (char*)pem; *wpem++ = '\0'; - if ((err = base64_strict_decode(asn1_cert, *asn1_len, asn1_cert, asn1_len)) != CRYPT_OK) { + if ((err = base64_strict_decode(pem, *w, pem, w)) != CRYPT_OK) { return err; } return CRYPT_OK; diff --git a/Sources/DataLiteC/libtomcrypt/misc/pem/pem_ssh.c b/Sources/DataLiteC/libtomcrypt/misc/pem/pem_ssh.c index 18a18d0..fe096d5 100644 --- a/Sources/DataLiteC/libtomcrypt/misc/pem/pem_ssh.c +++ b/Sources/DataLiteC/libtomcrypt/misc/pem/pem_ssh.c @@ -51,7 +51,7 @@ const struct blockcipher_info ssh_ciphers[] = { .name = "twofish256-cbc", .algo = "twofish", .keylen = 256 / 8, .mode = cm_cbc }, { .name = "twofish256-ctr", .algo = "twofish", .keylen = 256 / 8, .mode = cm_ctr }, }; -const unsigned long ssh_ciphers_num = LTC_ARRAY_SIZE(ssh_ciphers); +const unsigned long ssh_ciphers_num = sizeof(ssh_ciphers)/sizeof(ssh_ciphers[0]); struct kdf_options { const char *name; @@ -402,7 +402,7 @@ static int s_decode_key(const unsigned char *in, unsigned long *inlen, ltc_pka_k remaining -= cur_len; cur_len = remaining; - for (n = 0; n < LTC_ARRAY_SIZE(ssh_pkas); ++n) { + for (n = 0; n < sizeof(ssh_pkas)/sizeof(ssh_pkas[0]); ++n) { if (ssh_pkas[n].name.p != NULL) { if (pkalen != ssh_pkas[n].name.len || XMEMCMP(pka, ssh_pkas[n].name.p, ssh_pkas[n].name.len) != 0) continue; @@ -415,7 +415,7 @@ static int s_decode_key(const unsigned char *in, unsigned long *inlen, ltc_pka_k } break; } - if (n == LTC_ARRAY_SIZE(ssh_pkas)) { + if (n == sizeof(ssh_pkas)/sizeof(ssh_pkas[0])) { return CRYPT_PK_INVALID_TYPE; } @@ -490,7 +490,7 @@ static int s_parse_line(char *line, unsigned long *len, ltc_pka_key *key, char * rlen = *len; /* Chop up string into the three authorized_keys_elements */ - for (n = 0; n < LTC_ARRAY_SIZE(elements) && rlen; ++n) { + for (n = 0; n < sizeof(elements)/sizeof(elements[0]) && rlen; ++n) { skip_spaces(&r, &rlen); elements[n].p = r; if (n != 2) @@ -502,7 +502,7 @@ static int s_parse_line(char *line, unsigned long *len, ltc_pka_key *key, char * r++; } - for (n = 0; n < LTC_ARRAY_SIZE(ssh_pkas); ++n) { + for (n = 0; n < sizeof(ssh_pkas)/sizeof(ssh_pkas[0]); ++n) { if (ssh_pkas[n].name.p != NULL) { if (elements[ake_algo_name].len != ssh_pkas[n].name.len || XMEMCMP(elements[ake_algo_name].p, ssh_pkas[n].name.p, ssh_pkas[n].name.len) != 0) continue; @@ -711,7 +711,7 @@ static const struct pem_header_id pem_openssh[] = { .flags = pf_public }, }; -static const unsigned long pem_openssh_num = LTC_ARRAY_SIZE(pem_openssh); +static const unsigned long pem_openssh_num = sizeof(pem_openssh)/sizeof(pem_openssh[0]); static int s_decode_openssh(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx) { @@ -819,11 +819,9 @@ int ssh_read_authorized_keys_filehandle(FILE *f, ssh_authorized_key_cb cb, void LTC_ARGCHK(f != NULL); LTC_ARGCHK(cb != NULL); - if (fseek(f, 0, SEEK_END) == -1) - return CRYPT_ERROR; + fseek(f, 0, SEEK_END); tot_data = ftell(f); - if (fseek(f, 0, SEEK_SET) == -1) - return CRYPT_ERROR; + rewind(f); buf = XMALLOC(tot_data); if (buf == NULL) { return CRYPT_MEM; diff --git a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_decrypt.c b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_decrypt.c index 4c3add7..5fa3ee3 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_decrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_decrypt.c @@ -32,51 +32,51 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s LTC_ARGCHK(ct != NULL); LTC_ARGCHK(cbc != NULL); - if ((err = cipher_is_valid(cbc->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { return err; } /* is blocklen valid? */ - if (cbc->ecb.blocklen < 1 || cbc->ecb.blocklen > (int)sizeof(cbc->IV) || cbc->ecb.blocklen > (int)sizeof(tmp)) { + if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV) || cbc->blocklen > (int)sizeof(tmp)) { return CRYPT_INVALID_ARG; } - if (len % cbc->ecb.blocklen) { + if (len % cbc->blocklen) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST - if (cbc->ecb.blocklen % sizeof(LTC_FAST_TYPE)) { + if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif - if (cipher_descriptor[cbc->ecb.cipher].accel_cbc_decrypt != NULL) { - return cipher_descriptor[cbc->ecb.cipher].accel_cbc_decrypt(ct, pt, len / cbc->ecb.blocklen, cbc->IV, &cbc->ecb.key); + if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) { + return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key); } while (len) { /* decrypt */ - if ((err = ecb_decrypt_block(ct, tmp, &cbc->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) { return err; } /* xor IV against plaintext */ #if defined(LTC_FAST) - for (x = 0; x < cbc->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) { + for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { tmpy = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)tmp + x)); *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)); *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) = tmpy; } #else - for (x = 0; x < cbc->ecb.blocklen; x++) { + for (x = 0; x < cbc->blocklen; x++) { tmpy = tmp[x] ^ cbc->IV[x]; cbc->IV[x] = ct[x]; pt[x] = tmpy; } #endif - ct += cbc->ecb.blocklen; - pt += cbc->ecb.blocklen; - len -= cbc->ecb.blocklen; + ct += cbc->blocklen; + pt += cbc->blocklen; + len -= cbc->blocklen; } return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_done.c b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_done.c index d66e86f..985551f 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_done.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_done.c @@ -15,9 +15,14 @@ */ int cbc_done(symmetric_CBC *cbc) { + int err; LTC_ARGCHK(cbc != NULL); - return ecb_done(&cbc->ecb); + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[cbc->cipher].done(&cbc->key); + return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_encrypt.c b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_encrypt.c index 7274d69..50d91c4 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_encrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_encrypt.c @@ -26,58 +26,58 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s LTC_ARGCHK(ct != NULL); LTC_ARGCHK(cbc != NULL); - if ((err = cipher_is_valid(cbc->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { return err; } /* is blocklen valid? */ - if (cbc->ecb.blocklen < 1 || cbc->ecb.blocklen > (int)sizeof(cbc->IV)) { + if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) { return CRYPT_INVALID_ARG; } - if (len % cbc->ecb.blocklen) { + if (len % cbc->blocklen) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST - if (cbc->ecb.blocklen % sizeof(LTC_FAST_TYPE)) { + if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif - if (cipher_descriptor[cbc->ecb.cipher].accel_cbc_encrypt != NULL) { - return cipher_descriptor[cbc->ecb.cipher].accel_cbc_encrypt(pt, ct, len / cbc->ecb.blocklen, cbc->IV, &cbc->ecb.key); + if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) { + return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key); } while (len) { /* xor IV against plaintext */ #if defined(LTC_FAST) - for (x = 0; x < cbc->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) { + for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^= *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)); } #else - for (x = 0; x < cbc->ecb.blocklen; x++) { + for (x = 0; x < cbc->blocklen; x++) { cbc->IV[x] ^= pt[x]; } #endif /* encrypt */ - if ((err = ecb_encrypt_block(cbc->IV, ct, &cbc->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) { return err; } /* store IV [ciphertext] for a future block */ #if defined(LTC_FAST) - for (x = 0; x < cbc->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) { + for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)); } #else - for (x = 0; x < cbc->ecb.blocklen; x++) { + for (x = 0; x < cbc->blocklen; x++) { cbc->IV[x] = ct[x]; } #endif - ct += cbc->ecb.blocklen; - pt += cbc->ecb.blocklen; - len -= cbc->ecb.blocklen; + ct += cbc->blocklen; + pt += cbc->blocklen; + len -= cbc->blocklen; } return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_getiv.c b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_getiv.c index 37bf600..7af2cf1 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_getiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_getiv.c @@ -21,12 +21,12 @@ int cbc_getiv(unsigned char *IV, unsigned long *len, const symmetric_CBC *cbc) LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(cbc != NULL); - if ((unsigned long)cbc->ecb.blocklen > *len) { - *len = cbc->ecb.blocklen; + if ((unsigned long)cbc->blocklen > *len) { + *len = cbc->blocklen; return CRYPT_BUFFER_OVERFLOW; } - XMEMCPY(IV, cbc->IV, cbc->ecb.blocklen); - *len = cbc->ecb.blocklen; + XMEMCPY(IV, cbc->IV, cbc->blocklen); + *len = cbc->blocklen; return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_setiv.c b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_setiv.c index 92620b0..a9e91c3 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_setiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_setiv.c @@ -21,7 +21,7 @@ int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc) { LTC_ARGCHK(IV != NULL); LTC_ARGCHK(cbc != NULL); - if (len != (unsigned long)cbc->ecb.blocklen) { + if (len != (unsigned long)cbc->blocklen) { return CRYPT_INVALID_ARG; } XMEMCPY(cbc->IV, IV, len); diff --git a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_start.c b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_start.c index 58322e1..4156739 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_start.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cbc/cbc_start.c @@ -28,13 +28,20 @@ int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, LTC_ARGCHK(key != NULL); LTC_ARGCHK(cbc != NULL); + /* bad param? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + /* setup cipher */ - if ((err = ecb_start(cipher, key, keylen, num_rounds, &cbc->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) { return err; } /* copy IV */ - for (x = 0; x < cbc->ecb.blocklen; x++) { + cbc->blocklen = cipher_descriptor[cipher].block_length; + cbc->cipher = cipher; + for (x = 0; x < cbc->blocklen; x++) { cbc->IV[x] = IV[x]; } return CRYPT_OK; diff --git a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_decrypt.c b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_decrypt.c index 69026e3..ee06988 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_decrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_decrypt.c @@ -57,12 +57,12 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s return CRYPT_OVERFLOW; } - if ((err = cipher_is_valid(cfb->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ - if (cfb->ecb.blocklen < 0 || cfb->ecb.blocklen > (int)sizeof(cfb->IV) || + if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { return CRYPT_INVALID_ARG; } @@ -70,8 +70,8 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s bits_per_round = cfb->width == 1 ? 1 : 8; while (bitlen > 0) { - if (cfb->padlen == cfb->ecb.blocklen) { - if ((err = ecb_encrypt_block(cfb->pad, cfb->IV, &cfb->ecb)) != CRYPT_OK) { + if (cfb->padlen == cfb->blocklen) { + if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) { return err; } cfb->padlen = 0; @@ -85,22 +85,22 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s ct_ <<= 1; pt_ <<= 1; } - if (cfb->ecb.blocklen == 16) + if (cfb->blocklen == 16) s_shift1left_128(cfb->pad, ct_ >> 7); else s_shift1left_64(cfb->pad, ct_ >> 7); pt_ |= ((ct_ ^ cfb->IV[0]) >> 7) & 0x01u; - cfb->padlen = cfb->ecb.blocklen; + cfb->padlen = cfb->blocklen; if (cur_bit % 8 == 0) { *pt++ = pt_; cur_bit = 0; } break; case 8: - XMEMMOVE(cfb->pad, cfb->pad + 1, cfb->ecb.blocklen - 1); - cfb->pad[cfb->ecb.blocklen - 1] = *ct; + XMEMMOVE(cfb->pad, cfb->pad + 1, cfb->blocklen - 1); + cfb->pad[cfb->blocklen - 1] = *ct; *pt++ = *ct++ ^ cfb->IV[0]; - cfb->padlen = cfb->ecb.blocklen; + cfb->padlen = cfb->blocklen; break; case 64: case 128: diff --git a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_done.c b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_done.c index 881a17c..8f8f9cd 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_done.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_done.c @@ -15,9 +15,14 @@ */ int cfb_done(symmetric_CFB *cfb) { + int err; LTC_ARGCHK(cfb != NULL); - return ecb_done(&cfb->ecb); + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[cfb->cipher].done(&cfb->key); + return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_encrypt.c b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_encrypt.c index 22e27aa..e0a3643 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_encrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_encrypt.c @@ -57,12 +57,12 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s return CRYPT_OVERFLOW; } - if ((err = cipher_is_valid(cfb->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ - if (cfb->ecb.blocklen < 0 || cfb->ecb.blocklen > (int)sizeof(cfb->IV) || + if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { return CRYPT_INVALID_ARG; } @@ -70,8 +70,8 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s bits_per_round = cfb->width == 1 ? 1 : 8; while (bitlen > 0) { - if (cfb->padlen == cfb->ecb.blocklen) { - if ((err = ecb_encrypt_block(cfb->pad, cfb->IV, &cfb->ecb)) != CRYPT_OK) { + if (cfb->padlen == cfb->blocklen) { + if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) { return err; } cfb->padlen = 0; @@ -86,22 +86,22 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s ct_ <<= 1; } ct_ |= ((pt_ ^ cfb->IV[0]) >> 7) & 0x01u; - if (cfb->ecb.blocklen == 16) + if (cfb->blocklen == 16) s_shift1left_128(cfb->pad, ct_); else s_shift1left_64(cfb->pad, ct_); - cfb->padlen = cfb->ecb.blocklen; + cfb->padlen = cfb->blocklen; if (cur_bit % 8 == 0) { *ct++ = ct_; cur_bit = 0; } break; case 8: - XMEMMOVE(cfb->pad, cfb->pad + 1, cfb->ecb.blocklen - 1); - cfb->pad[cfb->ecb.blocklen - 1] = (*ct = *pt ^ cfb->IV[0]); + XMEMMOVE(cfb->pad, cfb->pad + 1, cfb->blocklen - 1); + cfb->pad[cfb->blocklen - 1] = (*ct = *pt ^ cfb->IV[0]); ++pt; ++ct; - cfb->padlen = cfb->ecb.blocklen; + cfb->padlen = cfb->blocklen; break; case 64: case 128: diff --git a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_getiv.c b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_getiv.c index 75ce264..ca72dd6 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_getiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_getiv.c @@ -21,12 +21,12 @@ int cfb_getiv(unsigned char *IV, unsigned long *len, const symmetric_CFB *cfb) LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(cfb != NULL); - if ((unsigned long)cfb->ecb.blocklen > *len) { - *len = cfb->ecb.blocklen; + if ((unsigned long)cfb->blocklen > *len) { + *len = cfb->blocklen; return CRYPT_BUFFER_OVERFLOW; } - XMEMCPY(IV, cfb->pad, cfb->ecb.blocklen); - *len = cfb->ecb.blocklen; + XMEMCPY(IV, cfb->pad, cfb->blocklen); + *len = cfb->blocklen; return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_setiv.c b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_setiv.c index 1758d64..60572de 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_setiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_setiv.c @@ -23,18 +23,18 @@ int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb) LTC_ARGCHK(IV != NULL); LTC_ARGCHK(cfb != NULL); - if ((err = cipher_is_valid(cfb->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { return err; } - if (len != (unsigned long)cfb->ecb.blocklen) { + if (len != (unsigned long)cfb->blocklen) { return CRYPT_INVALID_ARG; } /* force next block */ cfb->padlen = 0; XMEMCPY(cfb->pad, IV, len); - return ecb_encrypt_block(IV, cfb->IV, &cfb->ecb); + return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key); } #endif diff --git a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_start.c b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_start.c index 8b78b34..c95a657 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_start.c +++ b/Sources/DataLiteC/libtomcrypt/modes/cfb/cfb_start.c @@ -52,19 +52,23 @@ int cfb_start_ex(int cipher, const unsigned char *IV, const unsigned char *key, return CRYPT_INVALID_ARG; } - cfb->width = width; - /* init the cipher */ - if ((err = ecb_start(cipher, key, keylen, num_rounds, &cfb->ecb)) != CRYPT_OK) { - return err; - } + /* copy data */ - for (x = 0; x < cfb->ecb.blocklen; x++) { + cfb->cipher = cipher; + cfb->width = width; + cfb->blocklen = cipher_descriptor[cipher].block_length; + for (x = 0; x < cfb->blocklen; x++) { cfb->pad[x] = IV[x]; } + /* init the cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) { + return err; + } + /* encrypt the IV */ cfb->padlen = 0; - return ecb_encrypt_block(cfb->pad, cfb->IV, &cfb->ecb); + return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key); } /** diff --git a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_done.c b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_done.c index 670c63b..f93d971 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_done.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_done.c @@ -15,9 +15,14 @@ */ int ctr_done(symmetric_CTR *ctr) { + int err; LTC_ARGCHK(ctr != NULL); - return ecb_done(&ctr->ecb); + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ctr->cipher].done(&ctr->key); + return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_encrypt.c b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_encrypt.c index 2859574..b8c08f7 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_encrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_encrypt.c @@ -24,7 +24,7 @@ static int s_ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned lo while (len) { /* is the pad empty? */ - if (ctr->padlen == ctr->ecb.blocklen) { + if (ctr->padlen == ctr->blocklen) { /* increment counter */ if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) { /* little-endian */ @@ -36,7 +36,7 @@ static int s_ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned lo } } else { /* big-endian */ - for (x = ctr->ecb.blocklen-1; x >= ctr->ctrlen; x--) { + for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) { ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; if (ctr->ctr[x] != (unsigned char)0) { break; @@ -45,21 +45,21 @@ static int s_ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned lo } /* encrypt it */ - if ((err = ecb_encrypt_block(ctr->ctr, ctr->pad, &ctr->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) { return err; } ctr->padlen = 0; } #ifdef LTC_FAST - if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->ecb.blocklen)) { - for (x = 0; x < ctr->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) { + if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->blocklen)) { + for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) { *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x)); } - pt += ctr->ecb.blocklen; - ct += ctr->ecb.blocklen; - len -= ctr->ecb.blocklen; - ctr->padlen = ctr->ecb.blocklen; + pt += ctr->blocklen; + ct += ctr->blocklen; + len -= ctr->blocklen; + ctr->padlen = ctr->blocklen; continue; } #endif @@ -85,26 +85,26 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ctr != NULL); - if ((err = cipher_is_valid(ctr->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ - if ((ctr->ecb.blocklen < 1) || (ctr->ecb.blocklen > (int)sizeof(ctr->ctr)) || + if ((ctr->blocklen < 1) || (ctr->blocklen > (int)sizeof(ctr->ctr)) || (ctr->padlen < 0) || (ctr->padlen > (int)sizeof(ctr->pad))) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST - if (ctr->ecb.blocklen % sizeof(LTC_FAST_TYPE)) { + if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ - if ((cipher_descriptor[ctr->ecb.cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->ecb.blocklen)) { - if (ctr->padlen < ctr->ecb.blocklen) { - fr = ctr->ecb.blocklen - ctr->padlen; + if ((cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->blocklen)) { + if (ctr->padlen < ctr->blocklen) { + fr = ctr->blocklen - ctr->padlen; if ((err = s_ctr_encrypt(pt, ct, fr, ctr)) != CRYPT_OK) { return err; } @@ -113,13 +113,13 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s len -= fr; } - if (len >= (unsigned long)ctr->ecb.blocklen) { - if ((err = cipher_descriptor[ctr->ecb.cipher].accel_ctr_encrypt(pt, ct, len/ctr->ecb.blocklen, ctr->ctr, ctr->mode, &ctr->ecb.key)) != CRYPT_OK) { + if (len >= (unsigned long)ctr->blocklen) { + if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { return err; } - pt += (len / ctr->ecb.blocklen) * ctr->ecb.blocklen; - ct += (len / ctr->ecb.blocklen) * ctr->ecb.blocklen; - len %= ctr->ecb.blocklen; + pt += (len / ctr->blocklen) * ctr->blocklen; + ct += (len / ctr->blocklen) * ctr->blocklen; + len %= ctr->blocklen; } } diff --git a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_getiv.c b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_getiv.c index 7704a7f..05277fa 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_getiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_getiv.c @@ -21,12 +21,12 @@ int ctr_getiv(unsigned char *IV, unsigned long *len, const symmetric_CTR *ctr) LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(ctr != NULL); - if ((unsigned long)ctr->ecb.blocklen > *len) { - *len = ctr->ecb.blocklen; + if ((unsigned long)ctr->blocklen > *len) { + *len = ctr->blocklen; return CRYPT_BUFFER_OVERFLOW; } - XMEMCPY(IV, ctr->ctr, ctr->ecb.blocklen); - *len = ctr->ecb.blocklen; + XMEMCPY(IV, ctr->ctr, ctr->blocklen); + *len = ctr->blocklen; return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_setiv.c b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_setiv.c index 75ea1ab..be80f1a 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_setiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_setiv.c @@ -24,11 +24,11 @@ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr) LTC_ARGCHK(ctr != NULL); /* bad param? */ - if ((err = cipher_is_valid(ctr->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { return err; } - if (len != (unsigned long)ctr->ecb.blocklen) { + if (len != (unsigned long)ctr->blocklen) { return CRYPT_INVALID_ARG; } @@ -37,7 +37,7 @@ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr) /* force next block */ ctr->padlen = 0; - return ecb_encrypt_block(IV, ctr->pad, &ctr->ecb); + return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key); } #endif diff --git a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_start.c b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_start.c index 03b18a4..0ccdfd2 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_start.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_start.c @@ -49,14 +49,16 @@ int ctr_start( int cipher, } /* setup cipher */ - if ((err = ecb_start(cipher, key, keylen, num_rounds, &ctr->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) { return err; } /* copy ctr */ + ctr->blocklen = cipher_descriptor[cipher].block_length; + ctr->cipher = cipher; ctr->padlen = 0; ctr->mode = ctr_mode & 0x1000; - for (x = 0; x < ctr->ecb.blocklen; x++) { + for (x = 0; x < ctr->blocklen; x++) { ctr->ctr[x] = IV[x]; } @@ -72,7 +74,7 @@ int ctr_start( int cipher, } } else { /* big-endian */ - for (x = ctr->ecb.blocklen-1; x >= ctr->ctrlen; x--) { + for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) { ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; if (ctr->ctr[x] != (unsigned char)0) { break; @@ -81,7 +83,7 @@ int ctr_start( int cipher, } } - return ecb_encrypt_block(ctr->ctr, ctr->pad, &ctr->ecb); + return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); } #endif diff --git a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_test.c b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_test.c index 48c9498..df7e649 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_test.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ctr/ctr_test.c @@ -51,7 +51,7 @@ int ctr_test(void) } } - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = ctr_start(idx, tests[x].IV, tests[x].key, tests[x].keylen, 0, CTR_COUNTER_BIG_ENDIAN|LTC_CTR_RFC3686, &ctr)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/ecb/ecb_decrypt.c b/Sources/DataLiteC/libtomcrypt/modes/ecb/ecb_decrypt.c index b8a48b0..3069779 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ecb/ecb_decrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ecb/ecb_decrypt.c @@ -8,14 +8,6 @@ */ #ifdef LTC_ECB_MODE -int ecb_decrypt_block(const unsigned char *ct, unsigned char *pt, const symmetric_ECB *ecb) -{ - /* check for accel */ - if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) { - return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, 1, &ecb->key); - } - return cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key); -} /** ECB decrypt @@ -25,7 +17,7 @@ int ecb_decrypt_block(const unsigned char *ct, unsigned char *pt, const symmetri @param ecb ECB state @return CRYPT_OK if successful */ -int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, const symmetric_ECB *ecb) +int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb) { int err; LTC_ARGCHK(pt != NULL); diff --git a/Sources/DataLiteC/libtomcrypt/modes/ecb/ecb_encrypt.c b/Sources/DataLiteC/libtomcrypt/modes/ecb/ecb_encrypt.c index 07e8672..661d994 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ecb/ecb_encrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ecb/ecb_encrypt.c @@ -8,14 +8,6 @@ */ #ifdef LTC_ECB_MODE -int ecb_encrypt_block(const unsigned char *pt, unsigned char *ct, const symmetric_ECB *ecb) -{ - /* check for accel */ - if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) { - return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, 1, &ecb->key); - } - return cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key); -} /** ECB encrypt @@ -25,7 +17,7 @@ int ecb_encrypt_block(const unsigned char *pt, unsigned char *ct, const symmetri @param ecb ECB state @return CRYPT_OK if successful */ -int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, const symmetric_ECB *ecb) +int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb) { int err; LTC_ARGCHK(pt != NULL); diff --git a/Sources/DataLiteC/libtomcrypt/modes/f8/f8_done.c b/Sources/DataLiteC/libtomcrypt/modes/f8/f8_done.c index 78ee9fe..7d25b04 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/f8/f8_done.c +++ b/Sources/DataLiteC/libtomcrypt/modes/f8/f8_done.c @@ -15,9 +15,14 @@ */ int f8_done(symmetric_F8 *f8) { + int err; LTC_ARGCHK(f8 != NULL); - return ecb_done(&f8->ecb); + if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[f8->cipher].done(&f8->key); + return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/f8/f8_encrypt.c b/Sources/DataLiteC/libtomcrypt/modes/f8/f8_encrypt.c index ec147fd..671c904 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/f8/f8_encrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/f8/f8_encrypt.c @@ -24,12 +24,12 @@ int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, sy LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(f8 != NULL); - if ((err = cipher_is_valid(f8->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ - if (f8->ecb.blocklen < 0 || f8->ecb.blocklen > (int)sizeof(f8->IV) || + if (f8->blocklen < 0 || f8->blocklen > (int)sizeof(f8->IV) || f8->padlen < 0 || f8->padlen > (int)sizeof(f8->IV)) { return CRYPT_INVALID_ARG; } @@ -37,14 +37,14 @@ int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, sy zeromem(buf, sizeof(buf)); /* make sure the pad is empty */ - if (f8->padlen == f8->ecb.blocklen) { + if (f8->padlen == f8->blocklen) { /* xor of IV, MIV and blockcnt == what goes into cipher */ - STORE32H(f8->blockcnt, (buf+(f8->ecb.blocklen-4))); + STORE32H(f8->blockcnt, (buf+(f8->blocklen-4))); ++(f8->blockcnt); - for (x = 0; x < f8->ecb.blocklen; x++) { + for (x = 0; x < f8->blocklen; x++) { f8->IV[x] ^= f8->MIV[x] ^ buf[x]; } - if ((err = ecb_encrypt_block(f8->IV, f8->IV, &f8->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) { return err; } f8->padlen = 0; @@ -52,14 +52,14 @@ int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, sy #ifdef LTC_FAST if (f8->padlen == 0) { - while (len >= (unsigned long)f8->ecb.blocklen) { - STORE32H(f8->blockcnt, (buf+(f8->ecb.blocklen-4))); + while (len >= (unsigned long)f8->blocklen) { + STORE32H(f8->blockcnt, (buf+(f8->blocklen-4))); ++(f8->blockcnt); - for (x = 0; x < f8->ecb.blocklen; x += sizeof(LTC_FAST_TYPE)) { + for (x = 0; x < f8->blocklen; x += sizeof(LTC_FAST_TYPE)) { *(LTC_FAST_TYPE_PTR_CAST(&ct[x])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&f8->IV[x])); *(LTC_FAST_TYPE_PTR_CAST(&f8->IV[x])) ^= *(LTC_FAST_TYPE_PTR_CAST(&f8->MIV[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&buf[x])); } - if ((err = ecb_encrypt_block(f8->IV, f8->IV, &f8->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) { return err; } len -= x; @@ -70,14 +70,14 @@ int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, sy #endif while (len > 0) { - if (f8->padlen == f8->ecb.blocklen) { + if (f8->padlen == f8->blocklen) { /* xor of IV, MIV and blockcnt == what goes into cipher */ - STORE32H(f8->blockcnt, (buf+(f8->ecb.blocklen-4))); + STORE32H(f8->blockcnt, (buf+(f8->blocklen-4))); ++(f8->blockcnt); - for (x = 0; x < f8->ecb.blocklen; x++) { + for (x = 0; x < f8->blocklen; x++) { f8->IV[x] ^= f8->MIV[x] ^ buf[x]; } - if ((err = ecb_encrypt_block(f8->IV, f8->IV, &f8->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) { return err; } f8->padlen = 0; diff --git a/Sources/DataLiteC/libtomcrypt/modes/f8/f8_getiv.c b/Sources/DataLiteC/libtomcrypt/modes/f8/f8_getiv.c index a38ffde..1a4e53f 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/f8/f8_getiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/f8/f8_getiv.c @@ -21,12 +21,12 @@ int f8_getiv(unsigned char *IV, unsigned long *len, const symmetric_F8 *f8) LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(f8 != NULL); - if ((unsigned long)f8->ecb.blocklen > *len) { - *len = f8->ecb.blocklen; + if ((unsigned long)f8->blocklen > *len) { + *len = f8->blocklen; return CRYPT_BUFFER_OVERFLOW; } - XMEMCPY(IV, f8->IV, f8->ecb.blocklen); - *len = f8->ecb.blocklen; + XMEMCPY(IV, f8->IV, f8->blocklen); + *len = f8->blocklen; return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/f8/f8_setiv.c b/Sources/DataLiteC/libtomcrypt/modes/f8/f8_setiv.c index fd5411e..51a80ab 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/f8/f8_setiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/f8/f8_setiv.c @@ -23,17 +23,17 @@ int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8) LTC_ARGCHK(IV != NULL); LTC_ARGCHK(f8 != NULL); - if ((err = cipher_is_valid(f8->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { return err; } - if (len != (unsigned long)f8->ecb.blocklen) { + if (len != (unsigned long)f8->blocklen) { return CRYPT_INVALID_ARG; } /* force next block */ f8->padlen = 0; - return ecb_encrypt_block(IV, f8->IV, &f8->ecb); + return cipher_descriptor[f8->cipher].ecb_encrypt(IV, f8->IV, &f8->key); } #endif diff --git a/Sources/DataLiteC/libtomcrypt/modes/f8/f8_start.c b/Sources/DataLiteC/libtomcrypt/modes/f8/f8_start.c index cb60803..58f126f 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/f8/f8_start.c +++ b/Sources/DataLiteC/libtomcrypt/modes/f8/f8_start.c @@ -47,7 +47,9 @@ int f8_start( int cipher, const unsigned char *IV, /* copy details */ f8->blockcnt = 0; - f8->padlen = cipher_descriptor[cipher].block_length; + f8->cipher = cipher; + f8->blocklen = cipher_descriptor[cipher].block_length; + f8->padlen = f8->blocklen; /* now get key ^ salt_key [extend salt_ket with 0x55 as required to match length] */ zeromem(tkey, sizeof(tkey)); @@ -62,23 +64,23 @@ int f8_start( int cipher, const unsigned char *IV, } /* now encrypt with tkey[0..keylen-1] the IV and use that as the IV */ - if ((err = ecb_start(cipher, tkey, keylen, num_rounds, &f8->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(tkey, keylen, num_rounds, &f8->key)) != CRYPT_OK) { return err; } /* encrypt IV */ - if ((err = ecb_encrypt_block(IV, f8->MIV, &f8->ecb)) != CRYPT_OK) { - ecb_done(&f8->ecb); + if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(IV, f8->MIV, &f8->key)) != CRYPT_OK) { + cipher_descriptor[f8->cipher].done(&f8->key); return err; } zeromem(tkey, sizeof(tkey)); zeromem(f8->IV, sizeof(f8->IV)); /* terminate this cipher */ - ecb_done(&f8->ecb); + cipher_descriptor[f8->cipher].done(&f8->key); /* init the cipher */ - return ecb_start(cipher, key, keylen, num_rounds, &f8->ecb); + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &f8->key); } #endif diff --git a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_decrypt.c b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_decrypt.c index b4f4059..ba3b38a 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_decrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_decrypt.c @@ -24,12 +24,12 @@ int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s LTC_ARGCHK(ct != NULL); LTC_ARGCHK(lrw != NULL); - if ((err = cipher_is_valid(lrw->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { return err; } - if (cipher_descriptor[lrw->ecb.cipher].accel_lrw_decrypt != NULL) { - return cipher_descriptor[lrw->ecb.cipher].accel_lrw_decrypt(ct, pt, len, lrw->IV, lrw->tweak, &lrw->ecb.key); + if (cipher_descriptor[lrw->cipher].accel_lrw_decrypt != NULL) { + return cipher_descriptor[lrw->cipher].accel_lrw_decrypt(ct, pt, len, lrw->IV, lrw->tweak, &lrw->key); } return lrw_process(ct, pt, len, LRW_DECRYPT, lrw); diff --git a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_done.c b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_done.c index 83ad5f3..dc649a0 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_done.c +++ b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_done.c @@ -16,9 +16,16 @@ */ int lrw_done(symmetric_LRW *lrw) { + int err; + LTC_ARGCHK(lrw != NULL); - return ecb_done(&lrw->ecb); + if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[lrw->cipher].done(&lrw->key); + + return CRYPT_OK; } #endif diff --git a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_encrypt.c b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_encrypt.c index 7c8e1ba..fde442b 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_encrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_encrypt.c @@ -24,12 +24,12 @@ int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s LTC_ARGCHK(ct != NULL); LTC_ARGCHK(lrw != NULL); - if ((err = cipher_is_valid(lrw->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { return err; } - if (cipher_descriptor[lrw->ecb.cipher].accel_lrw_encrypt != NULL) { - return cipher_descriptor[lrw->ecb.cipher].accel_lrw_encrypt(pt, ct, len, lrw->IV, lrw->tweak, &lrw->ecb.key); + if (cipher_descriptor[lrw->cipher].accel_lrw_encrypt != NULL) { + return cipher_descriptor[lrw->cipher].accel_lrw_encrypt(pt, ct, len, lrw->IV, lrw->tweak, &lrw->key); } return lrw_process(pt, ct, len, LRW_ENCRYPT, lrw); diff --git a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_process.c b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_process.c index a04f90d..d9a3edd 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_process.c +++ b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_process.c @@ -77,11 +77,11 @@ int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, i /* send through cipher */ if (mode == LRW_ENCRYPT) { - if ((err = ecb_encrypt_block(ct, ct, &lrw->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[lrw->cipher].ecb_encrypt(ct, ct, &lrw->key)) != CRYPT_OK) { return err; } } else { - if ((err = ecb_decrypt_block(ct, ct, &lrw->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[lrw->cipher].ecb_decrypt(ct, ct, &lrw->key)) != CRYPT_OK) { return err; } } diff --git a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_setiv.c b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_setiv.c index 72615e7..efb4412 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_setiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_setiv.c @@ -30,7 +30,7 @@ int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw) return CRYPT_INVALID_ARG; } - if ((err = cipher_is_valid(lrw->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { return err; } @@ -38,7 +38,7 @@ int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw) XMEMCPY(lrw->IV, IV, 16); /* check if we have to actually do work */ - if (cipher_descriptor[lrw->ecb.cipher].accel_lrw_encrypt != NULL && cipher_descriptor[lrw->ecb.cipher].accel_lrw_decrypt != NULL) { + if (cipher_descriptor[lrw->cipher].accel_lrw_encrypt != NULL && cipher_descriptor[lrw->cipher].accel_lrw_decrypt != NULL) { /* we have accelerators, let's bail since they don't use lrw->pad anyways */ return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_start.c b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_start.c index fb0b95e..2095685 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_start.c +++ b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_start.c @@ -53,10 +53,10 @@ int lrw_start( int cipher, } /* schedule key */ - if ((err = ecb_start(cipher, key, keylen, num_rounds, &lrw->ecb)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &lrw->key)) != CRYPT_OK) { return err; } - lrw->ecb.cipher = cipher; + lrw->cipher = cipher; /* copy the IV and tweak */ XMEMCPY(lrw->tweak, tweak, 16); diff --git a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_test.c b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_test.c index 893f88d..3d9015b 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_test.c +++ b/Sources/DataLiteC/libtomcrypt/modes/lrw/lrw_test.c @@ -73,7 +73,7 @@ int lrw_test(void) } } - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { /* schedule it */ if ((err = lrw_start(idx, tests[x].IV, tests[x].key, 16, tests[x].tweak, 0, &lrw)) != CRYPT_OK) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_done.c b/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_done.c index 15cf1f6..c4a0184 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_done.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_done.c @@ -15,9 +15,14 @@ */ int ofb_done(symmetric_OFB *ofb) { + int err; LTC_ARGCHK(ofb != NULL); - return ecb_done(&ofb->ecb); + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ofb->cipher].done(&ofb->key); + return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_encrypt.c b/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_encrypt.c index 211efcc..63f1e18 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_encrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_encrypt.c @@ -23,19 +23,19 @@ int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ofb != NULL); - if ((err = cipher_is_valid(ofb->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ - if (ofb->ecb.blocklen < 0 || ofb->ecb.blocklen > (int)sizeof(ofb->IV) || + if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) || ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) { return CRYPT_INVALID_ARG; } while (len-- > 0) { - if (ofb->padlen == ofb->ecb.blocklen) { - if ((err = ecb_encrypt_block(ofb->IV, ofb->IV, &ofb->ecb)) != CRYPT_OK) { + if (ofb->padlen == ofb->blocklen) { + if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) { return err; } ofb->padlen = 0; diff --git a/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_getiv.c b/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_getiv.c index 6a40c1b..0a799f0 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_getiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_getiv.c @@ -21,12 +21,12 @@ int ofb_getiv(unsigned char *IV, unsigned long *len, const symmetric_OFB *ofb) LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(ofb != NULL); - if ((unsigned long)ofb->ecb.blocklen > *len) { - *len = ofb->ecb.blocklen; + if ((unsigned long)ofb->blocklen > *len) { + *len = ofb->blocklen; return CRYPT_BUFFER_OVERFLOW; } - XMEMCPY(IV, ofb->IV, ofb->ecb.blocklen); - *len = ofb->ecb.blocklen; + XMEMCPY(IV, ofb->IV, ofb->blocklen); + *len = ofb->blocklen; return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_setiv.c b/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_setiv.c index 9a06cc5..1fdec7f 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_setiv.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_setiv.c @@ -23,17 +23,17 @@ int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb) LTC_ARGCHK(IV != NULL); LTC_ARGCHK(ofb != NULL); - if ((err = cipher_is_valid(ofb->ecb.cipher)) != CRYPT_OK) { + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { return err; } - if (len != (unsigned long)ofb->ecb.blocklen) { + if (len != (unsigned long)ofb->blocklen) { return CRYPT_INVALID_ARG; } /* force next block */ ofb->padlen = 0; - return ecb_encrypt_block(IV, ofb->IV, &ofb->ecb); + return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key); } #endif diff --git a/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_start.c b/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_start.c index 2998f3f..179fe57 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_start.c +++ b/Sources/DataLiteC/libtomcrypt/modes/ofb/ofb_start.c @@ -33,18 +33,16 @@ int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, return err; } - /* init the cipher */ - if ((err = ecb_start(cipher, key, keylen, num_rounds, &ofb->ecb)) != CRYPT_OK) { - return err; - } - ofb->padlen = cipher_descriptor[cipher].block_length; - /* copy details */ - for (x = 0; x < ofb->ecb.blocklen; x++) { + ofb->cipher = cipher; + ofb->blocklen = cipher_descriptor[cipher].block_length; + for (x = 0; x < ofb->blocklen; x++) { ofb->IV[x] = IV[x]; } - return CRYPT_OK; + /* init the cipher */ + ofb->padlen = ofb->blocklen; + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key); } #endif diff --git a/Sources/DataLiteC/libtomcrypt/modes/xts/xts_decrypt.c b/Sources/DataLiteC/libtomcrypt/modes/xts/xts_decrypt.c index 50019b9..f1747d5 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/xts/xts_decrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/xts/xts_decrypt.c @@ -24,7 +24,7 @@ static int s_tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned ch } #endif - err = ecb_decrypt_block(P, P, &xts->key1); + err = cipher_descriptor[xts->cipher].ecb_decrypt(P, P, &xts->key1); #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { @@ -53,7 +53,7 @@ static int s_tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned ch int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt, unsigned char *tweak, const symmetric_xts *xts) { - unsigned char PP[16] = {0}, CC[16], T[16]; + unsigned char PP[16], CC[16], T[16]; unsigned long i, m, mo, lim; int err; @@ -86,7 +86,7 @@ int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt, if (cipher_descriptor[xts->cipher].accel_xts_decrypt && lim > 0) { /* use accelerated decryption for whole blocks */ - if ((err = cipher_descriptor[xts->cipher].accel_xts_decrypt(ct, pt, lim, tweak, &xts->key1.key, &xts->key2.key)) != + if ((err = cipher_descriptor[xts->cipher].accel_xts_decrypt(ct, pt, lim, tweak, &xts->key1, &xts->key2)) != CRYPT_OK) { return err; } @@ -97,7 +97,7 @@ int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt, XMEMCPY(T, tweak, sizeof(T)); } else { /* encrypt the tweak */ - if ((err = ecb_encrypt_block(tweak, T, &xts->key2)) != CRYPT_OK) { + if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) { return err; } @@ -136,7 +136,7 @@ int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt, } /* Decrypt the tweak back */ - if ((err = ecb_decrypt_block(T, tweak, &xts->key2)) != CRYPT_OK) { + if ((err = cipher_descriptor[xts->cipher].ecb_decrypt(T, tweak, &xts->key2)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/xts/xts_done.c b/Sources/DataLiteC/libtomcrypt/modes/xts/xts_done.c index dd7ed25..4f77521 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/xts/xts_done.c +++ b/Sources/DataLiteC/libtomcrypt/modes/xts/xts_done.c @@ -14,8 +14,8 @@ void xts_done(symmetric_xts *xts) { LTC_ARGCHKVD(xts != NULL); - ecb_done(&xts->key1); - ecb_done(&xts->key2); + cipher_descriptor[xts->cipher].done(&xts->key1); + cipher_descriptor[xts->cipher].done(&xts->key2); } #endif diff --git a/Sources/DataLiteC/libtomcrypt/modes/xts/xts_encrypt.c b/Sources/DataLiteC/libtomcrypt/modes/xts/xts_encrypt.c index 65b129c..c269b7c 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/xts/xts_encrypt.c +++ b/Sources/DataLiteC/libtomcrypt/modes/xts/xts_encrypt.c @@ -24,7 +24,7 @@ static int s_tweak_crypt(const unsigned char *P, unsigned char *C, unsigned char } #endif - if ((err = ecb_encrypt_block(C, C, &xts->key1)) != CRYPT_OK) { + if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(C, C, &xts->key1)) != CRYPT_OK) { return err; } @@ -55,7 +55,7 @@ static int s_tweak_crypt(const unsigned char *P, unsigned char *C, unsigned char int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tweak, const symmetric_xts *xts) { - unsigned char PP[16], CC[16] = {0}, T[16]; + unsigned char PP[16], CC[16], T[16]; unsigned long i, m, mo, lim; int err; @@ -88,7 +88,7 @@ int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct, if (cipher_descriptor[xts->cipher].accel_xts_encrypt && lim > 0) { /* use accelerated encryption for whole blocks */ - if ((err = cipher_descriptor[xts->cipher].accel_xts_encrypt(pt, ct, lim, tweak, &xts->key1.key, &xts->key2.key)) != + if ((err = cipher_descriptor[xts->cipher].accel_xts_encrypt(pt, ct, lim, tweak, &xts->key1, &xts->key2)) != CRYPT_OK) { return err; } @@ -100,7 +100,7 @@ int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct, } else { /* encrypt the tweak */ - if ((err = ecb_encrypt_block(tweak, T, &xts->key2)) != CRYPT_OK) { + if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) { return err; } @@ -137,7 +137,7 @@ int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct, } /* Decrypt the tweak back */ - if ((err = ecb_decrypt_block(T, tweak, &xts->key2)) != CRYPT_OK) { + if ((err = cipher_descriptor[xts->cipher].ecb_decrypt(T, tweak, &xts->key2)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/modes/xts/xts_init.c b/Sources/DataLiteC/libtomcrypt/modes/xts/xts_init.c index b523467..92e10a0 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/xts/xts_init.c +++ b/Sources/DataLiteC/libtomcrypt/modes/xts/xts_init.c @@ -41,10 +41,10 @@ int xts_start(int cipher, const unsigned char *key1, const unsigned char *key2, } /* schedule the two ciphers */ - if ((err = ecb_start(cipher, key1, keylen, num_rounds, &xts->key1)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key1, keylen, num_rounds, &xts->key1)) != CRYPT_OK) { return err; } - if ((err = ecb_start(cipher, key2, keylen, num_rounds, &xts->key2)) != CRYPT_OK) { + if ((err = cipher_descriptor[cipher].setup(key2, keylen, num_rounds, &xts->key2)) != CRYPT_OK) { return err; } xts->cipher = cipher; diff --git a/Sources/DataLiteC/libtomcrypt/modes/xts/xts_test.c b/Sources/DataLiteC/libtomcrypt/modes/xts/xts_test.c index 90e5bdf..ad92735 100644 --- a/Sources/DataLiteC/libtomcrypt/modes/xts/xts_test.c +++ b/Sources/DataLiteC/libtomcrypt/modes/xts/xts_test.c @@ -23,10 +23,8 @@ static int s_xts_test_accel_xts_encrypt(const unsigned char *pt, unsigned char * orig = cipher_descriptor[xts.cipher].accel_xts_encrypt; cipher_descriptor[xts.cipher].accel_xts_encrypt = NULL; - XMEMCPY(&xts.key1.key, skey1, sizeof(xts.key1)); - XMEMCPY(&xts.key2.key, skey2, sizeof(xts.key2)); - xts.key1.cipher = xts.key2.cipher = xts.cipher; - xts.key1.blocklen = xts.key2.blocklen = cipher_descriptor[xts.cipher].block_length; + XMEMCPY(&xts.key1, skey1, sizeof(symmetric_key)); + XMEMCPY(&xts.key2, skey2, sizeof(symmetric_key)); ret = xts_encrypt(pt, blocks << 4, ct, tweak, &xts); cipher_descriptor[xts.cipher].accel_xts_encrypt = orig; @@ -52,10 +50,8 @@ static int s_xts_test_accel_xts_decrypt(const unsigned char *ct, unsigned char * orig = cipher_descriptor[xts.cipher].accel_xts_decrypt; cipher_descriptor[xts.cipher].accel_xts_decrypt = NULL; - XMEMCPY(&xts.key1.key, skey1, sizeof(xts.key1)); - XMEMCPY(&xts.key2.key, skey2, sizeof(xts.key2)); - xts.key1.cipher = xts.key2.cipher = xts.cipher; - xts.key1.blocklen = xts.key2.blocklen = cipher_descriptor[xts.cipher].block_length; + XMEMCPY(&xts.key1, skey1, sizeof(symmetric_key)); + XMEMCPY(&xts.key2, skey2, sizeof(symmetric_key)); ret = xts_decrypt(ct, blocks << 4, pt, tweak, &xts); cipher_descriptor[xts.cipher].accel_xts_decrypt = orig; diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/general/der_asn1_maps.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/general/der_asn1_maps.c index e98ab39..8f54f09 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/general/der_asn1_maps.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/general/der_asn1_maps.c @@ -39,7 +39,7 @@ const int der_asn1_type_to_identifier_map[] = 24, /* LTC_ASN1_GENERALIZEDTIME, */ -1, /* LTC_ASN1_CUSTOM_TYPE, */ }; -const unsigned long der_asn1_type_to_identifier_map_sz = LTC_ARRAY_SIZE(der_asn1_type_to_identifier_map); +const unsigned long der_asn1_type_to_identifier_map_sz = sizeof(der_asn1_type_to_identifier_map)/sizeof(der_asn1_type_to_identifier_map[0]); /** A Map from the ASN.1 Class to its string @@ -51,7 +51,7 @@ const char* der_asn1_class_to_string_map[] = "CONTEXT-SPECIFIC", "PRIVATE", }; -const unsigned long der_asn1_class_to_string_map_sz = LTC_ARRAY_SIZE(der_asn1_class_to_string_map); +const unsigned long der_asn1_class_to_string_map_sz = sizeof(der_asn1_class_to_string_map)/sizeof(der_asn1_class_to_string_map[0]); /** A Map from the ASN.1 P/C-bit to its string @@ -61,7 +61,7 @@ const char* der_asn1_pc_to_string_map[] = "PRIMITIVE", "CONSTRUCTED", }; -const unsigned long der_asn1_pc_to_string_map_sz = LTC_ARRAY_SIZE(der_asn1_pc_to_string_map); +const unsigned long der_asn1_pc_to_string_map_sz = sizeof(der_asn1_pc_to_string_map)/sizeof(der_asn1_pc_to_string_map[0]); /** A Map from the ASN.1 tag to its string @@ -106,7 +106,7 @@ const char* der_asn1_tag_to_string_map[] = "OID internationalized resource identifier type", "Relative OID internationalized resource identifier type", }; -const unsigned long der_asn1_tag_to_string_map_sz = LTC_ARRAY_SIZE(der_asn1_tag_to_string_map); +const unsigned long der_asn1_tag_to_string_map_sz = sizeof(der_asn1_tag_to_string_map)/sizeof(der_asn1_tag_to_string_map[0]); /** A Map from ASN.1 Tags to ltc_asn1_type @@ -152,6 +152,6 @@ const ltc_asn1_type der_asn1_tag_to_type_map[] = /* 30 */ LTC_ASN1_CUSTOM_TYPE, /* BMPString types */ }; -const unsigned long der_asn1_tag_to_type_map_sz = LTC_ARRAY_SIZE(der_asn1_tag_to_type_map); +const unsigned long der_asn1_tag_to_type_map_sz = sizeof(der_asn1_tag_to_type_map)/sizeof(der_asn1_tag_to_type_map[0]); #endif diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/general/der_decode_asn1_identifier.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/general/der_decode_asn1_identifier.c index 78866c9..865e097 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/general/der_decode_asn1_identifier.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/general/der_decode_asn1_identifier.c @@ -47,7 +47,7 @@ static const unsigned char tag_constructed_map[] = LTC_ASN1_PC_PRIMITIVE, LTC_ASN1_PC_PRIMITIVE, }; - static const unsigned long tag_constructed_map_sz = LTC_ARRAY_SIZE(tag_constructed_map); + static const unsigned long tag_constructed_map_sz = sizeof(tag_constructed_map)/sizeof(tag_constructed_map[0]); /** Decode the ASN.1 Identifier diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/ia5/der_length_ia5_string.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/ia5/der_length_ia5_string.c index 4bce85e..e397b1c 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/ia5/der_length_ia5_string.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/ia5/der_length_ia5_string.c @@ -119,7 +119,7 @@ static const struct { int der_ia5_char_encode(int c) { int x; - for (x = 0; x < (int)LTC_ARRAY_SIZE(ia5_table); x++) { + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { if (ia5_table[x].code == c) { return ia5_table[x].value; } @@ -130,7 +130,7 @@ int der_ia5_char_encode(int c) int der_ia5_value_decode(int v) { int x; - for (x = 0; x < (int)LTC_ARRAY_SIZE(ia5_table); x++) { + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { if (ia5_table[x].value == v) { return ia5_table[x].code; } diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/object_identifier/der_encode_object_identifier.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/object_identifier/der_encode_object_identifier.c index af56354..9a9c62d 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/object_identifier/der_encode_object_identifier.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/object_identifier/der_encode_object_identifier.c @@ -27,7 +27,7 @@ int der_encode_object_identifier(const unsigned long *words, unsigned long nwor LTC_ARGCHK(outlen != NULL); /* check length */ - if ((err = der_length_object_identifier_full(words, nwords, &x, &z)) != CRYPT_OK) { + if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) { return err; } if (x > *outlen) { @@ -35,6 +35,17 @@ int der_encode_object_identifier(const unsigned long *words, unsigned long nwor return CRYPT_BUFFER_OVERFLOW; } + /* compute length to store OID data */ + z = 0; + wordbuf = words[0] * 40 + words[1]; + for (y = 1; y < nwords; y++) { + t = der_object_identifier_bits(wordbuf); + z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); + if (y < nwords - 1) { + wordbuf = words[y + 1]; + } + } + /* store header + length */ x = 0; out[x++] = 0x06; @@ -48,7 +59,7 @@ int der_encode_object_identifier(const unsigned long *words, unsigned long nwor wordbuf = words[0] * 40 + words[1]; for (i = 1; i < nwords; i++) { /* store 7 bit words in little endian */ - t = wordbuf; + t = wordbuf & 0xFFFFFFFF; if (t) { y = x; mask = 0; diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/object_identifier/der_length_object_identifier.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/object_identifier/der_length_object_identifier.c index 8facf74..d9ded02 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/object_identifier/der_length_object_identifier.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/object_identifier/der_length_object_identifier.c @@ -9,24 +9,27 @@ #ifdef LTC_DER -static LTC_INLINE unsigned long s_der_object_identifier_bits(unsigned long x) +unsigned long der_object_identifier_bits(unsigned long x) { -#if defined(LTC_HAVE_CLZL_BUILTIN) - if (x == 0) - return 0; - return sizeof(unsigned long) * CHAR_BIT - __builtin_clzl(x); -#else unsigned long c; + x &= 0xFFFFFFFF; c = 0; while (x) { ++c; x >>= 1; } return c; -#endif } -int der_length_object_identifier_full(const unsigned long *words, unsigned long nwords, unsigned long *outlen, unsigned long *datalen) + +/** + Gets length of DER encoding of Object Identifier + @param nwords The number of OID words + @param words The actual OID words to get the size of + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_object_identifier(const unsigned long *words, unsigned long nwords, unsigned long *outlen) { unsigned long y, z, t, wordbuf; @@ -48,7 +51,7 @@ int der_length_object_identifier_full(const unsigned long *words, unsigned long z = 0; wordbuf = words[0] * 40 + words[1]; for (y = 1; y < nwords; y++) { - t = s_der_object_identifier_bits(wordbuf); + t = der_object_identifier_bits(wordbuf); z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); if (y < nwords - 1) { /* grab next word */ @@ -56,9 +59,6 @@ int der_length_object_identifier_full(const unsigned long *words, unsigned long } } - if (datalen) { - *datalen = z; - } /* now depending on the length our length encoding changes */ if (z < 128) { z += 2; @@ -74,16 +74,4 @@ int der_length_object_identifier_full(const unsigned long *words, unsigned long return CRYPT_OK; } -/** - Gets length of DER encoding of Object Identifier - @param nwords The number of OID words - @param words The actual OID words to get the size of - @param outlen [out] The length of the DER encoding for the given string - @return CRYPT_OK if successful -*/ -int der_length_object_identifier(const unsigned long *words, unsigned long nwords, unsigned long *outlen) -{ - return der_length_object_identifier_full(words, nwords, outlen, NULL); -} - #endif diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/printable_string/der_length_printable_string.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/printable_string/der_length_printable_string.c index dcfcae9..c52e36d 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/printable_string/der_length_printable_string.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/printable_string/der_length_printable_string.c @@ -91,7 +91,7 @@ static const struct { int der_printable_char_encode(int c) { int x; - for (x = 0; x < (int)LTC_ARRAY_SIZE(printable_table); x++) { + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { if (printable_table[x].code == c) { return printable_table[x].value; } @@ -102,7 +102,7 @@ int der_printable_char_encode(int c) int der_printable_value_decode(int v) { int x; - for (x = 0; x < (int)LTC_ARRAY_SIZE(printable_table); x++) { + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { if (printable_table[x].value == v) { return printable_table[x].code; } diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/sequence/der_decode_sequence_flexi.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/sequence/der_decode_sequence_flexi.c index e434f05..61fe34a 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/sequence/der_decode_sequence_flexi.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/sequence/der_decode_sequence_flexi.c @@ -31,22 +31,6 @@ static int s_new_element(ltc_asn1_list **l) } return CRYPT_OK; } -#if defined(LTC_TEST_DBG) -void s_print_err(const char *errstr, ltc_asn1_list *l, int err, unsigned long identifier, unsigned long data_offset, unsigned long len) -{ -#if LTC_TEST_DBG <= 1 - if (err == CRYPT_OK) - return; -#endif - if (l->type == LTC_ASN1_CUSTOM_TYPE) { - fprintf(stderr, "%s %02lx: hl=%4lu l=%4lu - %s[%s %llu] (%s)\n", errstr, identifier, data_offset, len, der_asn1_class_to_string_map[l->klass], der_asn1_pc_to_string_map[l->pc], l->tag, error_to_string(err)); - } else { - fprintf(stderr, "%s %02lx: hl=%4lu l=%4lu - %s (%s)\n", errstr, identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag], error_to_string(err)); - } -} -#else -#define s_print_err(errstr, l, err, identifier, data_offset, len) LTC_UNUSED_PARAM(data_offset) -#endif /** ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements. @@ -59,8 +43,7 @@ void s_print_err(const char *errstr, ltc_asn1_list *l, int err, unsigned long id static int s_der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out, unsigned long depth) { ltc_asn1_list *l; - int err; - unsigned long identifier, len, totlen, data_offset, id_len, len_len; + unsigned long err, identifier, len, totlen, data_offset, id_len, len_len; void *realloc_tmp; LTC_ARGCHK(in != NULL); @@ -94,19 +77,30 @@ static int s_der_decode_sequence_flexi(const unsigned char *in, unsigned long *i if (l->type != LTC_ASN1_EOL) { /* fetch length */ len_len = *inlen - id_len; - /* init with dummy values for error cases */ +#if defined(LTC_TEST_DBG) data_offset = 666; len = 0; +#endif if ((err = der_decode_asn1_length(&in[id_len], &len_len, &len)) != CRYPT_OK) { - s_print_err("E1", l, err, identifier, data_offset, len); +#if defined(LTC_TEST_DBG) + fprintf(stderr, "E1 %02lx: hl=%4lu l=%4lu - %s (%s)\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag], error_to_string(err)); +#endif goto error; } else if (len > (*inlen - id_len - len_len)) { err = CRYPT_INVALID_PACKET; - s_print_err("E2", l, err, identifier, data_offset, len); +#if defined(LTC_TEST_DBG) + fprintf(stderr, "E2 %02lx: hl=%4lu l=%4lu - %s (%s)\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag], error_to_string(err)); +#endif goto error; } data_offset = id_len + len_len; - s_print_err("OK", l, err, identifier, data_offset, len); +#if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1 + if (l->type == LTC_ASN1_CUSTOM_TYPE && l->klass == LTC_ASN1_CL_CONTEXT_SPECIFIC) { + fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - Context Specific[%s %llu]\n", identifier, data_offset, len, der_asn1_pc_to_string_map[l->pc], l->tag); + } else { + fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - %s\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag]); + } +#endif len += data_offset; if (l->type == LTC_ASN1_CUSTOM_TYPE) { diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/teletex_string/der_length_teletex_string.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/teletex_string/der_length_teletex_string.c index 01b94a3..05dc4b0 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/der/teletex_string/der_length_teletex_string.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/der/teletex_string/der_length_teletex_string.c @@ -135,7 +135,7 @@ static const struct { int der_teletex_char_encode(int c) { int x; - for (x = 0; x < (int)LTC_ARRAY_SIZE(teletex_table); x++) { + for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) { if (teletex_table[x].code == c) { return teletex_table[x].value; } @@ -146,7 +146,7 @@ int der_teletex_char_encode(int c) int der_teletex_value_decode(int v) { int x; - for (x = 0; x < (int)LTC_ARRAY_SIZE(teletex_table); x++) { + for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) { if (teletex_table[x].value == v) { return teletex_table[x].code; } diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_get.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_get.c index 1fd5872..48a8a98 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_get.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_get.c @@ -66,7 +66,7 @@ int pk_get_oid_id(enum ltc_pka_id pka, enum ltc_oid_id *oid) { unsigned int i; LTC_ARGCHK(oid != NULL); - for (i = 1; i < LTC_ARRAY_SIZE(pka_oids); ++i) { + for (i = 1; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) { if (pka_oids[i].pka == pka) { *oid = pka_oids[i].id; return CRYPT_OK; @@ -95,7 +95,7 @@ int pk_get_oid_from_asn1(const ltc_asn1_list *oid, enum ltc_oid_id *id) return err; } - for (i = 1; i < LTC_ARRAY_SIZE(pka_oids); ++i) { + for (i = 1; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) { if (XSTRCMP(pka_oids[i].oid, tmp) == 0) { *id = pka_oids[i].id; return CRYPT_OK; diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_oid_str.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_oid_str.c index e12cdf4..fef567b 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_oid_str.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_oid_str.c @@ -10,18 +10,20 @@ int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen) { unsigned long i, j, limit, oid_j; + size_t OID_len; LTC_ARGCHK(oidlen != NULL); limit = *oidlen; *oidlen = 0; /* make sure that we return zero oidlen on error */ - if (oid != NULL) { - XMEMSET(oid, 0, sizeof(*oid) * limit); - } - if (OID == NULL) return CRYPT_OK; - if (OID[0] == '\0') return CRYPT_OK; + for (i = 0; i < limit; i++) oid[i] = 0; - for (i = 0, j = 0; OID[i] != '\0'; i++) { + if (OID == NULL) return CRYPT_OK; + + OID_len = XSTRLEN(OID); + if (OID_len == 0) return CRYPT_OK; + + for (i = 0, j = 0; i < OID_len; i++) { if (OID[i] == '.') { if (++j >= limit) continue; } @@ -36,75 +38,50 @@ int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen } } if (j == 0) return CRYPT_ERROR; - *oidlen = j + 1; - if (j >= limit || oid == NULL) { + if (j >= limit) { + *oidlen = j; return CRYPT_BUFFER_OVERFLOW; } + *oidlen = j + 1; return CRYPT_OK; } -typedef struct num_to_str { - int err; - char *wr; - unsigned long max_len, res_len; -} num_to_str; - -static LTC_INLINE void s_wr(char c, num_to_str *w) -{ - if (w->res_len == ULONG_MAX) { - w->err = CRYPT_OVERFLOW; - return; - } - w->res_len++; - if (w->res_len > w->max_len) w->wr = NULL; - if (w->wr) w->wr[w->max_len - w->res_len] = c; -} - int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen) { int i; - num_to_str w; - unsigned long j; + unsigned long j, k; + char tmp[LTC_OID_MAX_STRLEN] = { 0 }; LTC_ARGCHK(oid != NULL); LTC_ARGCHK(oidlen < INT_MAX); LTC_ARGCHK(outlen != NULL); - if (OID == NULL || *outlen == 0) { - w.max_len = ULONG_MAX; - w.wr = NULL; - } else { - w.max_len = *outlen; - w.wr = OID; - } - w.res_len = 0; - w.err = CRYPT_OK; - - s_wr('\0', &w); - for (i = oidlen; i --> 0;) { + for (i = oidlen - 1, k = 0; i >= 0; i--) { j = oid[i]; if (j == 0) { - s_wr('0', &w); - } else { + tmp[k] = '0'; + if (++k >= sizeof(tmp)) return CRYPT_ERROR; + } + else { while (j > 0) { - s_wr('0' + (j % 10), &w); + tmp[k] = '0' + (j % 10); + if (++k >= sizeof(tmp)) return CRYPT_ERROR; j /= 10; } } if (i > 0) { - s_wr('.', &w); + tmp[k] = '.'; + if (++k >= sizeof(tmp)) return CRYPT_ERROR; } } - if (w.err != CRYPT_OK) { - return w.err; - } - if (*outlen < w.res_len || OID == NULL) { - *outlen = w.res_len; + if (*outlen < k + 1) { + *outlen = k + 1; return CRYPT_BUFFER_OVERFLOW; } LTC_ARGCHK(OID != NULL); - XMEMMOVE(OID, OID + (w.max_len - w.res_len), w.res_len); - *outlen = w.res_len; + for (j = 0; j < k; j++) OID[j] = tmp[k - j - 1]; + OID[k] = '\0'; + *outlen = k; /* the length without terminating NUL byte */ return CRYPT_OK; } diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/x509/x509_decode_subject_public_key_info.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/x509/x509_decode_subject_public_key_info.c index 0725611..f958825 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/x509/x509_decode_subject_public_key_info.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/x509/x509_decode_subject_public_key_info.c @@ -70,7 +70,7 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i } /* this includes the internal hash ID and optional params (NULL in this case) */ - LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, LTC_ARRAY_SIZE(tmpoid)); + LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); if (parameters_type == LTC_ASN1_EOL) { alg_id_num = 1; } else { diff --git a/Sources/DataLiteC/libtomcrypt/pk/asn1/x509/x509_encode_subject_public_key_info.c b/Sources/DataLiteC/libtomcrypt/pk/asn1/x509/x509_encode_subject_public_key_info.c index 52a80a1..874574d 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/asn1/x509/x509_encode_subject_public_key_info.c +++ b/Sources/DataLiteC/libtomcrypt/pk/asn1/x509/x509_encode_subject_public_key_info.c @@ -47,7 +47,7 @@ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outle return err; } - oidlen = LTC_ARRAY_SIZE(oid); + oidlen = sizeof(oid)/sizeof(oid[0]); if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) { return err; } @@ -56,7 +56,7 @@ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outle LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len); return der_encode_sequence_multi(out, outlen, - LTC_ASN1_SEQUENCE, (unsigned long)LTC_ARRAY_SIZE(alg_id), alg_id, + LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id, LTC_ASN1_RAW_BIT_STRING, public_key_len*8U, public_key, LTC_ASN1_EOL, 0UL, NULL); diff --git a/Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_decrypt_key.c b/Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_decrypt_key.c index 734a2e0..fa87ef9 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_decrypt_key.c +++ b/Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_decrypt_key.c @@ -40,7 +40,7 @@ int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, } /* decode to find out hash */ - LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, LTC_ARRAY_SIZE(hashOID)); + LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); err = der_decode_sequence(in, inlen, decode, 1); if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_generate_pqg.c b/Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_generate_pqg.c index a9887c0..8e47f50 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_generate_pqg.c +++ b/Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_generate_pqg.c @@ -93,7 +93,7 @@ static int s_dsa_make_params(prng_state *prng, int wprng, int group_size, int mo #endif hash = -1; - for (i = 0; i < LTC_ARRAY_SIZE(accepted_hashes); ++i) { + for (i = 0; i < sizeof(accepted_hashes)/sizeof(accepted_hashes[0]); ++i) { hash = find_hash(accepted_hashes[i]); if (hash != -1) break; } diff --git a/Sources/DataLiteC/libtomcrypt/pk/ec25519/ec25519_export.c b/Sources/DataLiteC/libtomcrypt/pk/ec25519/ec25519_export.c index 5cd7c10..a6dba67 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/ec25519/ec25519_export.c +++ b/Sources/DataLiteC/libtomcrypt/pk/ec25519/ec25519_export.c @@ -46,7 +46,7 @@ int ec25519_export( unsigned char *out, unsigned long *outlen, if ((err = pk_get_oid(oid_id, &OID)) != CRYPT_OK) { return err; } - oidlen = LTC_ARRAY_SIZE(oid); + oidlen = sizeof(oid)/sizeof(oid[0]); if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) { return err; } diff --git a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_decrypt_key.c b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_decrypt_key.c index 7a4fac2..6697eda 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_decrypt_key.c +++ b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_decrypt_key.c @@ -41,7 +41,7 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, } /* decode to find out hash */ - LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, LTC_ARRAY_SIZE(hashOID)); + LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); err = der_decode_sequence(in, inlen, decode, 1); if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) { return err; diff --git a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_export_openssl.c b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_export_openssl.c index a58f40e..35d8ed0 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_export_openssl.c +++ b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_export_openssl.c @@ -90,7 +90,7 @@ int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, cons } */ - oidlen = LTC_ARRAY_SIZE(oid); + oidlen = sizeof(oid)/sizeof(oid[0]); if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) { goto error; } diff --git a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_make_key.c b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_make_key.c index c8239cf..1b04741 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_make_key.c +++ b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_make_key.c @@ -59,7 +59,6 @@ int ecc_generate_key(prng_state *prng, int wprng, ecc_key *key) goto error; } key->type = PK_PRIVATE; - key->rfc6979_hash_alg = NULL; /* success */ err = CRYPT_OK; diff --git a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_rfc6979_key.c b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_rfc6979_key.c deleted file mode 100644 index ebd17eb..0000000 --- a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_rfc6979_key.c +++ /dev/null @@ -1,162 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -#include "tomcrypt_private.h" - -/** - @file ecc_rfc6979_key.c - ECC Crypto, Russ Williams -*/ - -#ifdef LTC_MECC -#ifdef LTC_SHA256 - -/** - Make deterministic ECC key using the RFC6979 method - @param priv [in] Private key for HMAC - @param in Message to sign for HMAC - @param inlen Length of the message - @param key [out] Newly created deterministic key - @return CRYPT_OK if successful, upon error all allocated memory will be freed -*/ -int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long inlen, ecc_key *key) -{ - int err, hash = -1; - unsigned char v[MAXBLOCKSIZE], k[MAXBLOCKSIZE]; - unsigned char buffer[256], sep[1], privkey[128]; - unsigned long order_bits, len_diff, pk_len, zero_extend, outlen, klen, vlen, buflen, qlen, hashsize; - void *r, *d; - - LTC_ARGCHK(ltc_mp.name != NULL); - LTC_ARGCHK(priv != NULL); - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(key->dp.size > 0); - - if (priv->rfc6979_hash_alg == NULL) { - return CRYPT_INVALID_ARG; - } - hash = find_hash(priv->rfc6979_hash_alg); - if ((err = hash_is_valid(hash)) != CRYPT_OK) { - return err; - } - - hashsize = hash_descriptor[hash].hashsize; - - if ((err = ltc_mp_init_multi(&r, &d, NULL)) != CRYPT_OK) { - return err; - } - - /* Length, in bytes, of key */ - order_bits = ltc_mp_count_bits(key->dp.order); - qlen = (order_bits+7) >> 3; - len_diff = qlen > inlen ? qlen - inlen : 0; - pk_len = (ltc_mp_count_bits(priv->k)+7) >> 3; - zero_extend = qlen - pk_len; - XMEMSET(buffer, 0x00, len_diff + zero_extend); - - /* RFC6979 3.2b, set V */ - XMEMSET(v, 0x01, hashsize); - - /* RFC6979 3.2c, set K */ - XMEMSET(k, 0x00, hashsize); - - if ((err = ltc_mp_to_unsigned_bin(priv->k, privkey) != CRYPT_OK)) { goto error; } - /* RFC6979 3.2d, set K to HMAC_K(V::0x00::priv::in) */ - sep[0] = 0; - klen = sizeof(k); - if((err = hmac_memory_multi(hash, - k, hashsize, - k, &klen, - v, hashsize, - sep, 1, - buffer, zero_extend, - privkey, qlen - zero_extend, - buffer, len_diff, - in, qlen - len_diff, - LTC_NULL)) != CRYPT_OK) { goto error; } - - /* RFC6979 3.2e, set V = HMAC_K(V) */ - vlen = sizeof(v); - if((err = hmac_memory(hash, k, klen, v, hashsize, v, &vlen)) != CRYPT_OK) { goto error; } - - /* RFC6979 3.2f, set K to HMAC_K(V::0x01::priv::in) */ - sep[0] = 0x01; - outlen = sizeof(k); - if((err = hmac_memory_multi(hash, - k, klen, - k, &klen, - v, hashsize, - sep, 1, - buffer, zero_extend, - privkey, qlen - zero_extend, - buffer, len_diff, - in, qlen - len_diff, - LTC_NULL)) != CRYPT_OK) { goto error; } - - /* RFC6979 3.2g, set V = HMAC_K(V) */ - outlen = sizeof(v); - if((err = hmac_memory(hash, k, klen, v, hashsize, v, &outlen)) != CRYPT_OK) { goto error; } - - /* RFC6979 3.2h, generate and check key */ - do { - /* concatenate hash bits into T */ - buflen = 0; - while (buflen < qlen) { - if (buflen + hashsize >= sizeof(buffer) || buflen + hashsize < buflen) { - err = CRYPT_BUFFER_OVERFLOW; - goto error; - } - outlen = sizeof(v); - if((err = hmac_memory(hash, k, klen, v, hashsize, v, &outlen)) != CRYPT_OK) { goto error; } - XMEMCPY(&buffer[buflen], v, hashsize); - buflen += hashsize; - } - - /* key->k = bits2int(T) */ - if ((err = ltc_mp_read_unsigned_bin(r, buffer, qlen)) != CRYPT_OK) { goto error; } - if ((qlen * 8) > order_bits) { - if ((err = ltc_mp_2expt(d, (qlen * 8) - order_bits)) != CRYPT_OK) { goto error; } - if ((err = ltc_mp_div(r, d, r, NULL)) != CRYPT_OK) { goto error; } - if ((err = ltc_mp_to_unsigned_bin(r, buffer)) != CRYPT_OK) { goto error; } - qlen = ltc_mp_unsigned_bin_size(r); - } - - if ((err = ecc_set_key(buffer, qlen, PK_PRIVATE, key))!= CRYPT_OK) { goto error; } - - /* check that k is in range [1,q-1] */ - if (ltc_mp_cmp_d(key->k, 0) == LTC_MP_GT && ltc_mp_cmp(key->k, key->dp.order) == LTC_MP_LT) { - /* Check that pubkey.x != 0 (mod p) */ - if ((err = ltc_mp_mod(key->pubkey.x, key->dp.order, r)) != CRYPT_OK) { goto error; } - - /* if we have a valid key, exit loop */ - if (ltc_mp_iszero(r) == LTC_MP_NO) - break; - } else { - /* K = HMAC_K(V::0x00) */ - buffer[0] = 0x0; - outlen = sizeof(k); - if((err = hmac_memory_multi(hash, k, klen, k, &klen, v, hashsize, buffer, 1, LTC_NULL)) != CRYPT_OK) { goto error; } - - /* V = HMAC_K(V) */ - outlen = sizeof(v); - if((err = hmac_memory(hash, k, klen, v, hashsize, v, &outlen)) != CRYPT_OK) { goto error; } - - /* ... and try again! */ - } - } while (1); - - key->type = PK_PRIVATE; - - /* success */ - err = CRYPT_OK; - goto cleanup; - -error: - ecc_free(key); -cleanup: - ltc_mp_cleanup_multi(&d, &r, NULL); - return err; -} - -#endif -#endif diff --git a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_set_curve.c b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_set_curve.c index f340776..b6c21e8 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_set_curve.c +++ b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_set_curve.c @@ -23,8 +23,6 @@ int ecc_set_curve(const ltc_ecc_curve *cu, ecc_key *key) return err; } - key->rfc6979_hash_alg = NULL; - /* A, B, order, prime, Gx, Gy */ if ((err = ltc_mp_read_radix(key->dp.prime, cu->prime, 16)) != CRYPT_OK) { goto error; } if ((err = ltc_mp_read_radix(key->dp.order, cu->order, 16)) != CRYPT_OK) { goto error; } diff --git a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_set_key.c b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_set_key.c index b7204b8..2b47580 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_set_key.c +++ b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_set_key.c @@ -33,7 +33,7 @@ int ecc_set_key(const unsigned char *in, unsigned long inlen, int type, ecc_key else if (type == PK_PUBLIC) { /* load public key */ if ((err = ltc_ecc_import_point(in, inlen, prime, a, b, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto error; } - if ((err = ltc_mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; } + if ((err = ltc_mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; } } else { err = CRYPT_INVALID_PACKET; @@ -46,7 +46,6 @@ int ecc_set_key(const unsigned char *in, unsigned long inlen, int type, ecc_key } key->type = type; - key->rfc6979_hash_alg = NULL; return CRYPT_OK; error: diff --git a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_sign_hash_internal.c b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_sign_hash_internal.c index 5321dde..ef46281 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_sign_hash_internal.c +++ b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_sign_hash_internal.c @@ -57,12 +57,8 @@ int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, /* make up a key and export the public copy */ do { - if ((err = ecc_copy_curve(key, &pubkey)) != CRYPT_OK) { goto errnokey; } - if (key->rfc6979_hash_alg != NULL) { - if ((err = ecc_rfc6979_key(key, in, inlen, &pubkey)) != CRYPT_OK) { goto errnokey; } - } else { - if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { goto errnokey; } - } + if ((err = ecc_copy_curve(key, &pubkey)) != CRYPT_OK) { goto errnokey; } + if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { goto errnokey; } /* find r = x1 mod n */ if ((err = ltc_mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } @@ -82,7 +78,7 @@ int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, if (ltc_mp_iszero(r) == LTC_MP_YES) { ecc_free(&pubkey); } else { - if ((err = rand_bn_upto(b, p, prng, wprng)) != CRYPT_OK) { goto error; } /* b = blinding value */ + if ((err = rand_bn_upto(b, p, prng, wprng)) != CRYPT_OK) { goto error; } /* b = blinding value */ /* find s = (e + xr)/k */ if ((err = ltc_mp_mulmod(pubkey.k, b, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = kb */ if ((err = ltc_mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/kb */ diff --git a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_ssh_ecdsa_encode_name.c b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_ssh_ecdsa_encode_name.c index f10a2c6..4b8d554 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_ssh_ecdsa_encode_name.c +++ b/Sources/DataLiteC/libtomcrypt/pk/ecc/ecc_ssh_ecdsa_encode_name.c @@ -19,7 +19,7 @@ */ int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key) { - char oidstr[LTC_OID_MAX_STRLEN] = {0}; + char oidstr[64] = {0}; unsigned long oidlen = sizeof(oidstr); int err, size = 0; diff --git a/Sources/DataLiteC/libtomcrypt/pk/rsa/rsa_key.c b/Sources/DataLiteC/libtomcrypt/pk/rsa/rsa_key.c index 7eb21b8..12b88ce 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/rsa/rsa_key.c +++ b/Sources/DataLiteC/libtomcrypt/pk/rsa/rsa_key.c @@ -24,7 +24,7 @@ static void s_mpi_shrink_multi(void **a, ...) cur = a; va_start(args, a); while (cur != NULL) { - if (n >= LTC_ARRAY_SIZE(tmp)) { + if (n >= sizeof(tmp)/sizeof(tmp[0])) { goto out; } if (*cur != NULL) { @@ -49,8 +49,8 @@ out: * or after this was called with too many args */ if ((err != CRYPT_OK) || - (n >= LTC_ARRAY_SIZE(tmp))) { - for (n = 0; n < LTC_ARRAY_SIZE(tmp); ++n) { + (n >= sizeof(tmp)/sizeof(tmp[0]))) { + for (n = 0; n < sizeof(tmp)/sizeof(tmp[0]); ++n) { if (tmp[n] != NULL) { ltc_mp_clear(tmp[n]); } diff --git a/Sources/DataLiteC/libtomcrypt/pk/rsa/rsa_verify_hash.c b/Sources/DataLiteC/libtomcrypt/pk/rsa/rsa_verify_hash.c index 9ca1641..9b2577b 100644 --- a/Sources/DataLiteC/libtomcrypt/pk/rsa/rsa_verify_hash.c +++ b/Sources/DataLiteC/libtomcrypt/pk/rsa/rsa_verify_hash.c @@ -131,7 +131,7 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle hash OCTET STRING } */ - LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, LTC_ARRAY_SIZE(loid)); + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0])); LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); diff --git a/Sources/DataLiteC/sqlcipher/sqlite3.c b/Sources/DataLiteC/sqlcipher/sqlite3.c index e6600b4..1bcbc3b 100644 --- a/Sources/DataLiteC/sqlcipher/sqlite3.c +++ b/Sources/DataLiteC/sqlcipher/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.50.4. By combining all the individual C code files into this +** version 3.49.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,9 +18,8 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** 4d8adfb30e03f9cf27f800a2c1ba3c48fb4c with changes in files: +** 17144570b0d96ae63cd6f3edca39e27ebd74 with changes in files: ** -** .fossil-settings/binary-glob ** .fossil-settings/empty-dirs ** .fossil-settings/ignore-glob ** LICENSE.md @@ -29,12 +28,14 @@ ** main.mk ** src/attach.c ** src/backup.c +** src/ctime.c ** src/global.c ** src/main.c ** src/malloc.c ** src/pager.c ** src/pager.h ** src/pragma.c +** src/pragma.h ** src/shell.c.in ** src/sqlite.h.in ** src/sqliteInt.h @@ -486,7 +487,7 @@ extern "C" { ** ** Since [version 3.6.18] ([dateof:3.6.18]), ** SQLite source code has been stored in the -** Fossil configuration management +** Fossil configuration management ** system. ^The SQLITE_SOURCE_ID macro evaluates to ** a string which identifies a particular check-in of SQLite ** within its configuration management system. ^The SQLITE_SOURCE_ID @@ -499,9 +500,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.50.4" -#define SQLITE_VERSION_NUMBER 3050004 -#define SQLITE_SOURCE_ID "2025-07-30 19:33:53 4d8adfb30e03f9cf27f800a2c1ba3c48fb4ca1b08b0f5ed59a4d5ecbf45ealt1" +#define SQLITE_VERSION "3.49.2" +#define SQLITE_VERSION_NUMBER 3049002 +#define SQLITE_SOURCE_ID "2025-05-07 10:39:52 17144570b0d96ae63cd6f3edca39e27ebd74925252bbaf6723bcb2f6b486alt1" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -1516,12 +1517,6 @@ struct sqlite3_io_methods { ** the value that M is to be set to. Before returning, the 32-bit signed ** integer is overwritten with the previous value of M. ** -**
  • [[SQLITE_FCNTL_BLOCK_ON_CONNECT]] -** The [SQLITE_FCNTL_BLOCK_ON_CONNECT] opcode is used to configure the -** VFS to block when taking a SHARED lock to connect to a wal mode database. -** This is used to implement the functionality associated with -** SQLITE_SETLK_BLOCK_ON_CONNECT. -** **
  • [[SQLITE_FCNTL_DATA_VERSION]] ** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to ** a database file. The argument is a pointer to a 32-bit unsigned integer. @@ -1618,7 +1613,6 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 #define SQLITE_FCNTL_NULL_IO 43 -#define SQLITE_FCNTL_BLOCK_ON_CONNECT 44 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -2349,16 +2343,13 @@ struct sqlite3_mem_methods { ** ** [[SQLITE_CONFIG_LOOKASIDE]]
    SQLITE_CONFIG_LOOKASIDE
    **
    ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine -** the default size of [lookaside memory] on each [database connection]. +** the default size of lookaside memory on each [database connection]. ** The first argument is the -** size of each lookaside buffer slot ("sz") and the second is the number of -** slots allocated to each database connection ("cnt").)^ -** ^(SQLITE_CONFIG_LOOKASIDE sets the default lookaside size. -** The [SQLITE_DBCONFIG_LOOKASIDE] option to [sqlite3_db_config()] can -** be used to change the lookaside configuration on individual connections.)^ -** The [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to change the -** default lookaside configuration at compile-time. -**
    +** size of each lookaside buffer slot and the second is the number of +** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE +** sets the default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** option to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections.)^ ** ** [[SQLITE_CONFIG_PCACHE2]]
    SQLITE_CONFIG_PCACHE2
    **
    ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is @@ -2595,50 +2586,31 @@ struct sqlite3_mem_methods { ** [[SQLITE_DBCONFIG_LOOKASIDE]] **
    SQLITE_DBCONFIG_LOOKASIDE
    **
    The SQLITE_DBCONFIG_LOOKASIDE option is used to adjust the -** configuration of the [lookaside memory allocator] within a database +** configuration of the lookaside memory allocator within a database ** connection. ** The arguments to the SQLITE_DBCONFIG_LOOKASIDE option are not ** in the [DBCONFIG arguments|usual format]. ** The SQLITE_DBCONFIG_LOOKASIDE option takes three arguments, not two, ** so that a call to [sqlite3_db_config()] that uses SQLITE_DBCONFIG_LOOKASIDE ** should have a total of five parameters. -**
      -**
    1. The first argument ("buf") is a +** ^The first argument (the third parameter to [sqlite3_db_config()] is a ** pointer to a memory buffer to use for lookaside memory. -** The first argument may be NULL in which case SQLite will allocate the -** lookaside buffer itself using [sqlite3_malloc()]. -**

    2. The second argument ("sz") is the -** size of each lookaside buffer slot. Lookaside is disabled if "sz" -** is less than 8. The "sz" argument should be a multiple of 8 less than -** 65536. If "sz" does not meet this constraint, it is reduced in size until -** it does. -**

    3. The third argument ("cnt") is the number of slots. Lookaside is disabled -** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so -** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt" -** parameter is usually chosen so that the product of "sz" and "cnt" is less -** than 1,000,000. -**

    -**

    If the "buf" argument is not NULL, then it must -** point to a memory buffer with a size that is greater than -** or equal to the product of "sz" and "cnt". -** The buffer must be aligned to an 8-byte boundary. -** The lookaside memory +** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb +** may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the +** size of each lookaside buffer slot. ^The third argument is the number of +** slots. The size of the buffer in the first argument must be greater than +** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. ^If the second argument to +** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally +** rounded down to the next smaller multiple of 8. ^(The lookaside memory ** configuration for a database connection can only be changed when that ** connection is not currently using lookaside memory, or in other words -** when the value returned by [SQLITE_DBSTATUS_LOOKASIDE_USED] is zero. +** when the "current value" returned by +** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero. ** Any attempt to change the lookaside memory configuration when lookaside ** memory is in use leaves the configuration unchanged and returns -** [SQLITE_BUSY]. -** If the "buf" argument is NULL and an attempt -** to allocate memory based on "sz" and "cnt" fails, then -** lookaside is silently disabled. -**

    -** The [SQLITE_CONFIG_LOOKASIDE] configuration option can be used to set the -** default lookaside configuration at initialization. The -** [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to set the default lookaside -** configuration at compile-time. Typical values for lookaside are 1200 for -** "sz" and 40 to 100 for "cnt". -**

    +** [SQLITE_BUSY].)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FKEY]] **
    SQLITE_DBCONFIG_ENABLE_FKEY
    @@ -3375,44 +3347,6 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); */ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); -/* -** CAPI3REF: Set the Setlk Timeout -** METHOD: sqlite3 -** -** This routine is only useful in SQLITE_ENABLE_SETLK_TIMEOUT builds. If -** the VFS supports blocking locks, it sets the timeout in ms used by -** eligible locks taken on wal mode databases by the specified database -** handle. In non-SQLITE_ENABLE_SETLK_TIMEOUT builds, or if the VFS does -** not support blocking locks, this function is a no-op. -** -** Passing 0 to this function disables blocking locks altogether. Passing -** -1 to this function requests that the VFS blocks for a long time - -** indefinitely if possible. The results of passing any other negative value -** are undefined. -** -** Internally, each SQLite database handle store two timeout values - the -** busy-timeout (used for rollback mode databases, or if the VFS does not -** support blocking locks) and the setlk-timeout (used for blocking locks -** on wal-mode databases). The sqlite3_busy_timeout() method sets both -** values, this function sets only the setlk-timeout value. Therefore, -** to configure separate busy-timeout and setlk-timeout values for a single -** database handle, call sqlite3_busy_timeout() followed by this function. -** -** Whenever the number of connections to a wal mode database falls from -** 1 to 0, the last connection takes an exclusive lock on the database, -** then checkpoints and deletes the wal file. While it is doing this, any -** new connection that tries to read from the database fails with an -** SQLITE_BUSY error. Or, if the SQLITE_SETLK_BLOCK_ON_CONNECT flag is -** passed to this API, the new connection blocks until the exclusive lock -** has been released. -*/ -SQLITE_API int sqlite3_setlk_timeout(sqlite3*, int ms, int flags); - -/* -** CAPI3REF: Flags for sqlite3_setlk_timeout() -*/ -#define SQLITE_SETLK_BLOCK_ON_CONNECT 0x01 - /* ** CAPI3REF: Convenience Routines For Running Queries ** METHOD: sqlite3 @@ -4432,7 +4366,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** database filename D with corresponding journal file J and WAL file W and -** an array P of N URI Key/Value pairs. The result from +** with N URI parameters key/values pairs in the array P. The result from ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that ** is safe to pass to routines like: **
      @@ -5113,7 +5047,7 @@ typedef struct sqlite3_context sqlite3_context; ** METHOD: sqlite3_stmt ** ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, -** literals may be replaced by a [parameter] that matches one of the following +** literals may be replaced by a [parameter] that matches one of following ** templates: ** **
        @@ -5158,7 +5092,7 @@ typedef struct sqlite3_context sqlite3_context; ** ** [[byte-order determination rules]] ^The byte-order of ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) -** found in the first character, which is removed, or in the absence of a BOM +** found in first character, which is removed, or in the absence of a BOM ** the byte order is the native byte order of the host ** machine for sqlite3_bind_text16() or the byte order specified in ** the 6th parameter for sqlite3_bind_text64().)^ @@ -5178,7 +5112,7 @@ typedef struct sqlite3_context sqlite3_context; ** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL -** terminated. If any NUL characters occur at byte offsets less than +** terminated. If any NUL characters occurs at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. @@ -5390,7 +5324,7 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); ** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and -** table column that is the origin of a particular result column in a +** table column that is the origin of a particular result column in ** [SELECT] statement. ** ^The name of the database or table or column can be returned as ** either a UTF-8 or UTF-16 string. ^The _database_ routines return @@ -5528,7 +5462,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** other than [SQLITE_ROW] before any subsequent invocation of ** sqlite3_step(). Failure to reset the prepared statement using ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from -** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), +** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], ** sqlite3_step() began ** calling [sqlite3_reset()] automatically in this circumstance rather ** than returning [SQLITE_MISUSE]. This is not considered a compatibility @@ -5959,8 +5893,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be -** used inside of triggers, views, CHECK constraints, or other elements of -** the database schema. This flag is especially recommended for SQL +** used inside of triggers, view, CHECK constraints, or other elements of +** the database schema. This flags is especially recommended for SQL ** functions that have side effects or reveal internal application state. ** Without this flag, an attacker might be able to modify the schema of ** a database file to include invocations of the function with parameters @@ -5991,7 +5925,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** [user-defined window functions|available here]. ** ** ^(If the final parameter to sqlite3_create_function_v2() or -** sqlite3_create_window_function() is not NULL, then it is the destructor for +** sqlite3_create_window_function() is not NULL, then it is destructor for ** the application data pointer. The destructor is invoked when the function ** is deleted, either by being overloaded or when the database connection ** closes.)^ ^The destructor is also invoked if the call to @@ -6391,7 +6325,7 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); ** METHOD: sqlite3_value ** ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] -** object V and returns a pointer to that copy. ^The [sqlite3_value] returned +** object D and returns a pointer to that copy. ^The [sqlite3_value] returned ** is a [protected sqlite3_value] object even if the input is not. ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a ** memory allocation fails. ^If V is a [pointer value], then the result @@ -6429,7 +6363,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*); ** allocation error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is -** determined by the N parameter on the first successful call. Changing the +** determined by the N parameter on first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory ** allocation.)^ Within the xFinal callback, it is customary to set @@ -6591,7 +6525,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi ** ** Security Warning: These interfaces should not be exposed in scripting ** languages or in other circumstances where it might be possible for an -** attacker to invoke them. Any agent that can invoke these interfaces +** an attacker to invoke them. Any agent that can invoke these interfaces ** can probably also take control of the process. ** ** Database connection client data is only available for SQLite @@ -6705,7 +6639,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would -** appear if the string were NUL terminated. If any NUL characters occur +** appear if the string where NUL terminated. If any NUL characters occur ** in the string at a byte offset that is less than the value of the 3rd ** parameter, then the resulting string will contain embedded NULs and the ** result of expressions operating on strings with embedded NULs is undefined. @@ -6763,7 +6697,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** string and preferably a string literal. The sqlite3_result_pointer() ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** -** If these routines are called from within a different thread +** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ @@ -7229,7 +7163,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** METHOD: sqlite3 ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name -** for the N-th database on database connection D, or a NULL pointer if N is +** for the N-th database on database connection D, or a NULL pointer of N is ** out of range. An N value of 0 means the main database file. An N of 1 is ** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** databases. @@ -7324,7 +7258,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); **
        The SQLITE_TXN_READ state means that the database is currently ** in a read transaction. Content has been read from the database file ** but nothing in the database file has changed. The transaction state -** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are +** will advanced to SQLITE_TXN_WRITE if any changes occur and there are ** no other conflicting concurrent write transactions. The transaction ** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or ** [COMMIT].
        @@ -7333,7 +7267,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); **
        The SQLITE_TXN_WRITE state means that the database is currently ** in a write transaction. Content has been written to the database file ** but has not yet committed. The transaction state will change to -** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].
        +** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT]. */ #define SQLITE_TXN_NONE 0 #define SQLITE_TXN_READ 1 @@ -7484,8 +7418,6 @@ SQLITE_API int sqlite3_autovacuum_pages( ** ** ^The second argument is a pointer to the function to invoke when a ** row is updated, inserted or deleted in a rowid table. -** ^The update hook is disabled by invoking sqlite3_update_hook() -** with a NULL pointer as the second parameter. ** ^The first argument to the callback is a copy of the third argument ** to sqlite3_update_hook(). ** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], @@ -7614,7 +7546,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); ** CAPI3REF: Impose A Limit On Heap Size ** ** These interfaces impose limits on the amount of heap memory that will be -** used by all database connections within a single process. +** by all database connections within a single process. ** ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** soft limit on the amount of heap memory that may be allocated by SQLite. @@ -7672,7 +7604,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); **
      )^ ** ** The circumstances under which SQLite will enforce the heap limits may -** change in future releases of SQLite. +** changes in future releases of SQLite. */ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); @@ -7787,8 +7719,8 @@ SQLITE_API int sqlite3_table_column_metadata( ** ^The entry point is zProc. ** ^(zProc may be 0, in which case SQLite will try to come up with an ** entry point name on its own. It first tries "sqlite3_extension_init". -** If that does not work, it constructs a name "sqlite3_X_init" where -** X consists of the lower-case equivalent of all ASCII alphabetic +** If that does not work, it constructs a name "sqlite3_X_init" where the +** X is consists of the lower-case equivalent of all ASCII alphabetic ** characters in the filename from the last "/" to the first following ** "." and omitting any initial "lib".)^ ** ^The sqlite3_load_extension() interface returns @@ -7859,7 +7791,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** ^(Even though the function prototype shows that xEntryPoint() takes ** no arguments and returns void, SQLite invokes xEntryPoint() with three ** arguments and expects an integer result as if the signature of the -** entry point were as follows: +** entry point where as follows: ** **
       **    int xEntryPoint(
      @@ -8023,7 +7955,7 @@ struct sqlite3_module {
       ** virtual table and might not be checked again by the byte code.)^ ^(The
       ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag
       ** is left in its default setting of false, the constraint will always be
      -** checked separately in byte code.  If the omit flag is changed to true, then
      +** checked separately in byte code.  If the omit flag is change to true, then
       ** the constraint may or may not be checked in byte code.  In other words,
       ** when the omit flag is true there is no guarantee that the constraint will
       ** not be checked again using byte code.)^
      @@ -8049,7 +7981,7 @@ struct sqlite3_module {
       ** The xBestIndex method may optionally populate the idxFlags field with a
       ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
       ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
      -** output to show the idxNum as hex instead of as decimal.  Another flag is
      +** output to show the idxNum has hex instead of as decimal.  Another flag is
       ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
       ** return at most one row.
       **
      @@ -8190,7 +8122,7 @@ struct sqlite3_index_info {
       ** the implementation of the [virtual table module].   ^The fourth
       ** parameter is an arbitrary client data pointer that is passed through
       ** into the [xCreate] and [xConnect] methods of the virtual table module
      -** when a new virtual table is being created or reinitialized.
      +** when a new virtual table is be being created or reinitialized.
       **
       ** ^The sqlite3_create_module_v2() interface has a fifth parameter which
       ** is a pointer to a destructor for the pClientData.  ^SQLite will
      @@ -8355,7 +8287,7 @@ typedef struct sqlite3_blob sqlite3_blob;
       ** in *ppBlob. Otherwise an [error code] is returned and, unless the error
       ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
       ** the API is not misused, it is always safe to call [sqlite3_blob_close()]
      -** on *ppBlob after this function returns.
      +** on *ppBlob after this function it returns.
       **
       ** This function fails with SQLITE_ERROR if any of the following are true:
       ** 
        @@ -8475,7 +8407,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The -** incremental blob I/O routines can only read or overwrite existing +** incremental blob I/O routines can only read or overwriting existing ** blob content; they cannot change the size of a blob. ** ** This routine only works on a [BLOB handle] which has been created @@ -8625,7 +8557,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ^The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** routine returns NULL if it is unable to allocate the requested -** mutex. The argument to sqlite3_mutex_alloc() must be one of these +** mutex. The argument to sqlite3_mutex_alloc() must one of these ** integer constants: ** **
          @@ -8858,7 +8790,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** -** ^This interface returns a pointer to the [sqlite3_mutex] object that +** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this @@ -8981,7 +8913,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); ** CAPI3REF: SQL Keyword Checking ** ** These routines provide access to the set of SQL language keywords -** recognized by SQLite. Applications can use these routines to determine +** recognized by SQLite. Applications can uses these routines to determine ** whether or not a specific identifier needs to be escaped (for example, ** by enclosing in double-quotes) so as not to confuse the parser. ** @@ -9149,7 +9081,7 @@ SQLITE_API void sqlite3_str_reset(sqlite3_str*); ** content of the dynamic string under construction in X. The value ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** and might be freed or altered by any subsequent method on the same -** [sqlite3_str] object. Applications must not use the pointer returned by +** [sqlite3_str] object. Applications must not used the pointer returned ** [sqlite3_str_value(X)] after any subsequent method call on the same ** object. ^Applications may change the content of the string returned ** by [sqlite3_str_value(X)] as long as they do not write into any bytes @@ -9235,7 +9167,7 @@ SQLITE_API int sqlite3_status64( ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** buffer and where forced to overflow to [sqlite3_malloc()]. The ** returned value includes allocations that overflowed because they -** were too large (they were larger than the "sz" parameter to +** where too large (they were larger than the "sz" parameter to ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because ** no space was left in the page cache.)^ ** @@ -9319,29 +9251,28 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
          SQLITE_DBSTATUS_LOOKASIDE_HIT
          **
          This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; -** the current value is always zero.
          )^ +** the current value is always zero.)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] ** ^(
          SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
          -**
          This parameter returns the number of malloc attempts that might have +**
          This parameter returns the number malloc attempts that might have ** been satisfied using lookaside memory but failed due to the amount of ** memory requested being larger than the lookaside slot size. ** Only the high-water value is meaningful; -** the current value is always zero.
          )^ +** the current value is always zero.)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] ** ^(
          SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
          -**
          This parameter returns the number of malloc attempts that might have +**
          This parameter returns the number malloc attempts that might have ** been satisfied using lookaside memory but failed due to all lookaside ** memory already being in use. ** Only the high-water value is meaningful; -** the current value is always zero.
          )^ +** the current value is always zero.)^ ** ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
          SQLITE_DBSTATUS_CACHE_USED
          **
          This parameter returns the approximate number of bytes of heap ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. -**
          ** ** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] ** ^(
          SQLITE_DBSTATUS_CACHE_USED_SHARED
          @@ -9350,10 +9281,10 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** memory used by that pager cache is divided evenly between the attached ** connections.)^ In other words, if none of the pager caches associated ** with the database connection are shared, this request returns the same -** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are +** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are ** shared, the value returned by this call will be smaller than that returned ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with -** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. +** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. ** ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
          SQLITE_DBSTATUS_SCHEMA_USED
          **
          This parameter returns the approximate number of bytes of heap @@ -9363,7 +9294,6 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** schema memory is shared with other database connections due to ** [shared cache mode] being enabled. ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. -**
          ** ** [[SQLITE_DBSTATUS_STMT_USED]] ^(
          SQLITE_DBSTATUS_STMT_USED
          **
          This parameter returns the approximate number of bytes of heap @@ -9400,7 +9330,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces -** additional overhead. This parameter can be used to help identify +** additional overhead. This parameter can be used help identify ** inefficiencies that can be resolved by increasing the cache size. **
          ** @@ -9471,13 +9401,13 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** [[SQLITE_STMTSTATUS_SORT]]
          SQLITE_STMTSTATUS_SORT
          **
          ^This is the number of sort operations that have occurred. ** A non-zero value in this counter may indicate an opportunity to -** improve performance through careful use of indices.
          +** improvement performance through careful use of indices. ** ** [[SQLITE_STMTSTATUS_AUTOINDEX]]
          SQLITE_STMTSTATUS_AUTOINDEX
          **
          ^This is the number of rows inserted into transient indices that ** were created automatically in order to help joins run faster. ** A non-zero value in this counter may indicate an opportunity to -** improve performance by adding permanent indices that do not +** improvement performance by adding permanent indices that do not ** need to be reinitialized each time the statement is run.
          ** ** [[SQLITE_STMTSTATUS_VM_STEP]]
          SQLITE_STMTSTATUS_VM_STEP
          @@ -9486,19 +9416,19 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** to 2147483647. The number of virtual machine operations can be ** used as a proxy for the total work done by the prepared statement. ** If the number of virtual machine operations exceeds 2147483647 -** then the value returned by this statement status code is undefined. +** then the value returned by this statement status code is undefined. ** ** [[SQLITE_STMTSTATUS_REPREPARE]]
          SQLITE_STMTSTATUS_REPREPARE
          **
          ^This is the number of times that the prepare statement has been ** automatically regenerated due to schema changes or changes to -** [bound parameters] that might affect the query plan.
          +** [bound parameters] that might affect the query plan. ** ** [[SQLITE_STMTSTATUS_RUN]]
          SQLITE_STMTSTATUS_RUN
          **
          ^This is the number of times that the prepared statement has ** been run. A single "run" for the purposes of this counter is one ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. ** The counter is incremented on the first [sqlite3_step()] call of each -** cycle.
          +** cycle. ** ** [[SQLITE_STMTSTATUS_FILTER_MISS]] ** [[SQLITE_STMTSTATUS_FILTER HIT]] @@ -9508,7 +9438,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** step was bypassed because a Bloom filter returned not-found. The ** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of ** times that the Bloom filter returned a find, and thus the join step -** had to be processed as normal. +** had to be processed as normal. ** ** [[SQLITE_STMTSTATUS_MEMUSED]]
          SQLITE_STMTSTATUS_MEMUSED
          **
          ^This is the approximate number of bytes of heap memory @@ -9613,9 +9543,9 @@ struct sqlite3_pcache_page { ** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must -** be allocated by the cache. ^szPage will always be a power of two. ^The +** be allocated by the cache. ^szPage will always a power of two. ^The ** second parameter szExtra is a number of bytes of extra storage -** associated with each page cache entry. ^The szExtra parameter will be +** associated with each page cache entry. ^The szExtra parameter will ** a number less than 250. SQLite will use the ** extra szExtra bytes on each page to store metadata about the underlying ** database page on disk. The value passed into szExtra depends @@ -9623,17 +9553,17 @@ struct sqlite3_pcache_page { ** ^The third argument to xCreate(), bPurgeable, is true if the cache being ** created will be used to cache database pages of a file stored on disk, or ** false if it is used for an in-memory database. The cache implementation -** does not have to do anything special based upon the value of bPurgeable; +** does not have to do anything special based with the value of bPurgeable; ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will ** never invoke xUnpin() except to deliberately delete a page. ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to ** false will always have the "discard" flag set to true. -** ^Hence, a cache created with bPurgeable set to false will +** ^Hence, a cache created with bPurgeable false will ** never contain any unpinned pages. ** ** [[the xCachesize() page cache method]] ** ^(The xCachesize() method may be called at any time by SQLite to set the -** suggested maximum cache-size (number of pages stored) for the cache +** suggested maximum cache-size (number of pages stored by) the cache ** instance passed as the first argument. This is the value configured using ** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable ** parameter, the implementation is not required to do anything with this @@ -9660,12 +9590,12 @@ struct sqlite3_pcache_page { ** implementation must return a pointer to the page buffer with its content ** intact. If the requested page is not already in the cache, then the ** cache implementation should use the value of the createFlag -** parameter to help it determine what action to take: +** parameter to help it determined what action to take: ** ** **
          createFlag Behavior when page is not already in cache **
          0 Do not allocate a new page. Return NULL. -**
          1 Allocate a new page if it is easy and convenient to do so. +**
          1 Allocate a new page if it easy and convenient to do so. ** Otherwise return NULL. **
          2 Make every effort to allocate a new page. Only return ** NULL if allocating a new page is effectively impossible. @@ -9682,7 +9612,7 @@ struct sqlite3_pcache_page { ** as its second argument. If the third parameter, discard, is non-zero, ** then the page must be evicted from the cache. ** ^If the discard parameter is -** zero, then the page may be discarded or retained at the discretion of the +** zero, then the page may be discarded or retained at the discretion of ** page cache implementation. ^The page cache implementation ** may choose to evict unpinned pages at any time. ** @@ -9700,7 +9630,7 @@ struct sqlite3_pcache_page { ** When SQLite calls the xTruncate() method, the cache must discard all ** existing cache entries with page numbers (keys) greater than or equal ** to the value of the iLimit parameter passed to xTruncate(). If any -** of these pages are pinned, they become implicitly unpinned, meaning that +** of these pages are pinned, they are implicitly unpinned, meaning that ** they can be safely discarded. ** ** [[the xDestroy() page cache method]] @@ -9880,7 +9810,7 @@ typedef struct sqlite3_backup sqlite3_backup; ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically ** restarted by the next call to sqlite3_backup_step(). ^If the source -** database is modified by using the same database connection as is used +** database is modified by the using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** @@ -9897,7 +9827,7 @@ typedef struct sqlite3_backup sqlite3_backup; ** and may not be used following a call to sqlite3_backup_finish(). ** ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no -** sqlite3_backup_step() errors occurred, regardless of whether or not +** sqlite3_backup_step() errors occurred, regardless or whether or not ** sqlite3_backup_step() completed. ** ^If an out-of-memory condition or IO error occurred during any prior ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then @@ -9999,7 +9929,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** application receives an SQLITE_LOCKED error, it may call the ** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked -** when the blocking connection's current transaction is concluded. ^The +** when the blocking connections current transaction is concluded. ^The ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] ** call that concludes the blocking connection's transaction. ** @@ -10019,7 +9949,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is canceled. ^The blocked connection's +** unlock-notify callback is canceled. ^The blocked connections ** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** @@ -10417,7 +10347,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** support constraints. In this configuration (which is the default) if ** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire ** statement is rolled back as if [ON CONFLICT | OR ABORT] had been -** specified as part of the user's SQL statement, regardless of the actual +** specified as part of the users SQL statement, regardless of the actual ** ON CONFLICT mode specified. ** ** If X is non-zero, then the virtual table implementation guarantees @@ -10451,7 +10381,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** [[SQLITE_VTAB_INNOCUOUS]]
          SQLITE_VTAB_INNOCUOUS
          **
          Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the -** [xConnect] or [xCreate] methods of a [virtual table] implementation +** the [xConnect] or [xCreate] methods of a [virtual table] implementation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a @@ -10619,7 +10549,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); **
          ** ** ^For the purposes of comparing virtual table output values to see if the -** values are the same value for sorting purposes, two NULL values are considered +** values are same value for sorting purposes, two NULL values are considered ** to be the same. In other words, the comparison operator is "IS" ** (or "IS NOT DISTINCT FROM") and not "==". ** @@ -10629,7 +10559,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** ** ^A virtual table implementation is always free to return rows in any order ** it wants, as long as the "orderByConsumed" flag is not set. ^When the -** "orderByConsumed" flag is unset, the query planner will add extra +** the "orderByConsumed" flag is unset, the query planner will add extra ** [bytecode] to ensure that the final results returned by the SQL query are ** ordered correctly. The use of the "orderByConsumed" flag and the ** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful @@ -10726,7 +10656,7 @@ SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); ** sqlite3_vtab_in_next(X,P) should be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint -** processing using the [sqlite3_vtab_in()] interface in the +** processing use the [sqlite3_vtab_in()] interface in the ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not ** an xFilter argument that was selected for all-at-once IN constraint ** processing, then these routines return [SQLITE_ERROR].)^ @@ -10781,7 +10711,7 @@ SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface -** can return a result code other than SQLITE_OK or SQLITE_NOTFOUND if +** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if ** something goes wrong. ** ** The sqlite3_vtab_rhs_value() interface is usually only successful if @@ -10809,8 +10739,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** ** KEYWORDS: {conflict resolution mode} ** ** These constants are returned by [sqlite3_vtab_on_conflict()] to -** inform a [virtual table] implementation of the [ON CONFLICT] mode -** for the SQL statement being evaluated. +** inform a [virtual table] implementation what the [ON CONFLICT] mode +** is for the SQL statement being evaluated. ** ** Note that the [SQLITE_IGNORE] constant is also used as a potential ** return value from the [sqlite3_set_authorizer()] callback and that @@ -10850,39 +10780,39 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** ** [[SQLITE_SCANSTAT_EST]]
          SQLITE_SCANSTAT_EST
          **
          ^The "double" variable pointed to by the V parameter will be set to the ** query planner's estimate for the average number of rows output from each -** iteration of the X-th loop. If the query planner's estimate was accurate, +** iteration of the X-th loop. If the query planner's estimates was accurate, ** then this value will approximate the quotient NVISIT/NLOOP and the ** product of this value for all prior loops with the same SELECTID will -** be the NLOOP value for the current loop.
          +** be the NLOOP value for the current loop. ** ** [[SQLITE_SCANSTAT_NAME]]
          SQLITE_SCANSTAT_NAME
          **
          ^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the name of the index or table -** used for the X-th loop.
          +** used for the X-th loop. ** ** [[SQLITE_SCANSTAT_EXPLAIN]]
          SQLITE_SCANSTAT_EXPLAIN
          **
          ^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] -** description for the X-th loop.
          +** description for the X-th loop. ** ** [[SQLITE_SCANSTAT_SELECTID]]
          SQLITE_SCANSTAT_SELECTID
          **
          ^The "int" variable pointed to by the V parameter will be set to the ** id for the X-th query plan element. The id value is unique within the ** statement. The select-id is the same value as is output in the first -** column of an [EXPLAIN QUERY PLAN] query.
          +** column of an [EXPLAIN QUERY PLAN] query. ** ** [[SQLITE_SCANSTAT_PARENTID]]
          SQLITE_SCANSTAT_PARENTID
          **
          The "int" variable pointed to by the V parameter will be set to the -** id of the parent of the current query element, if applicable, or +** the id of the parent of the current query element, if applicable, or ** to zero if the query element has no parent. This is the same value as -** returned in the second column of an [EXPLAIN QUERY PLAN] query.
          +** returned in the second column of an [EXPLAIN QUERY PLAN] query. ** ** [[SQLITE_SCANSTAT_NCYCLE]]
          SQLITE_SCANSTAT_NCYCLE
          **
          The sqlite3_int64 output value is set to the number of cycles, ** according to the processor time-stamp counter, that elapsed while the ** query element was being processed. This value is not available for ** all query elements - if it is unavailable the output variable is -** set to -1.
          +** set to -1. ** */ #define SQLITE_SCANSTAT_NLOOP 0 @@ -10923,8 +10853,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. ** ** Parameter "idx" identifies the specific query element to retrieve statistics -** for. Query elements are numbered starting from zero. A value of -1 may -** retrieve statistics for the entire query. ^If idx is out of range +** for. Query elements are numbered starting from zero. A value of -1 may be +** to query for statistics regarding the entire query. ^If idx is out of range ** - less than -1 or greater than or equal to the total number of query ** elements used to implement the statement - a non-zero value is returned and ** the variable that pOut points to is unchanged. @@ -10967,7 +10897,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); ** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the -** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty +** [sqlite3_db_cacheflush(D)] interface invoked, any dirty ** pages in the pager-cache that are not currently in use are written out ** to disk. A dirty page may be in use if a database cursor created by an ** active SQL statement is reading from it, or if it is page 1 of a database @@ -11081,8 +11011,8 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** triggers; and so forth. ** ** When the [sqlite3_blob_write()] API is used to update a blob column, -** the pre-update hook is invoked with SQLITE_DELETE, because -** the new values are not yet available. In this case, when a +** the pre-update hook is invoked with SQLITE_DELETE. This is because the +** in this case the new values are not available. In this case, when a ** callback made with op==SQLITE_DELETE is actually a write using the ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns ** the index of the column being written. In other cases, where the @@ -11335,7 +11265,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written -** to disk if that database were backed up to disk. +** to disk if that database where backed up to disk. ** ** The usual case is that sqlite3_serialize() copies the serialization of ** the database into memory obtained from [sqlite3_malloc64()] and returns @@ -11344,7 +11274,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations ** are made, and the sqlite3_serialize() function will return a pointer ** to the contiguous memory representation of the database that SQLite -** is currently using for that database, or NULL if no such contiguous +** is currently using for that database, or NULL if the no such contiguous ** memory representation of the database exists. A contiguous memory ** representation of the database will usually only exist if there has ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same @@ -11415,7 +11345,7 @@ SQLITE_API unsigned char *sqlite3_serialize( ** database is currently in a read transaction or is involved in a backup ** operation. ** -** It is not possible to deserialize into the TEMP database. If the +** It is not possible to deserialized into the TEMP database. If the ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** @@ -11437,7 +11367,7 @@ SQLITE_API int sqlite3_deserialize( sqlite3 *db, /* The database connection */ const char *zSchema, /* Which DB to reopen with the deserialization */ unsigned char *pData, /* The serialized database content */ - sqlite3_int64 szDb, /* Number of bytes in the deserialization */ + sqlite3_int64 szDb, /* Number bytes in the deserialization */ sqlite3_int64 szBuf, /* Total size of buffer pData[] */ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ ); @@ -11445,7 +11375,7 @@ SQLITE_API int sqlite3_deserialize( /* ** CAPI3REF: Flags for sqlite3_deserialize() ** -** The following are allowed values for the 6th argument (the F argument) to +** The following are allowed values for 6th argument (the F argument) to ** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. ** ** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization @@ -11970,10 +11900,9 @@ SQLITE_API void sqlite3session_table_filter( ** is inserted while a session object is enabled, then later deleted while ** the same session object is disabled, no INSERT record will appear in the ** changeset, even though the delete took place while the session was disabled. -** Or, if one field of a row is updated while a session is enabled, and -** then another field of the same row is updated while the session is disabled, -** the resulting changeset will contain an UPDATE change that updates both -** fields. +** Or, if one field of a row is updated while a session is disabled, and +** another field of the same row is updated while the session is enabled, the +** resulting changeset will contain an UPDATE change that updates both fields. */ SQLITE_API int sqlite3session_changeset( sqlite3_session *pSession, /* Session object */ @@ -12045,9 +11974,8 @@ SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession ** database zFrom the contents of the two compatible tables would be ** identical. ** -** Unless the call to this function is a no-op as described above, it is an -** error if database zFrom does not exist or does not contain the required -** compatible table. +** It an error if database zFrom does not exist or does not contain the +** required compatible table. ** ** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite ** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg @@ -12182,7 +12110,7 @@ SQLITE_API int sqlite3changeset_start_v2( ** The following flags may passed via the 4th parameter to ** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: ** -**
          SQLITE_CHANGESETSTART_INVERT
          +**
          SQLITE_CHANGESETAPPLY_INVERT
          ** Invert the changeset while iterating through it. This is equivalent to ** inverting a changeset using sqlite3changeset_invert() before applying it. ** It is an error to specify this flag with a patchset. @@ -12497,6 +12425,19 @@ SQLITE_API int sqlite3changeset_concat( void **ppOut /* OUT: Buffer containing output changeset */ ); + +/* +** CAPI3REF: Upgrade the Schema of a Changeset/Patchset +*/ +SQLITE_API int sqlite3changeset_upgrade( + sqlite3 *db, + const char *zDb, + int nIn, const void *pIn, /* Input changeset */ + int *pnOut, void **ppOut /* OUT: Inverse of input */ +); + + + /* ** CAPI3REF: Changegroup Handle ** @@ -14244,22 +14185,14 @@ struct fts5_api { ** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. ** * Terms in the VALUES clause of an INSERT statement ** -** The hard upper limit here is 32767. Most database people will +** The hard upper limit here is 32676. Most database people will ** tell you that in a well-normalized database, you usually should ** not have more than a dozen or so columns in any table. And if ** that is the case, there is no point in having more than a few ** dozen values in any of the other situations described above. -** -** An index can only have SQLITE_MAX_COLUMN columns from the user -** point of view, but the underlying b-tree that implements the index -** might have up to twice as many columns in a WITHOUT ROWID table, -** since must also store the primary key at the end. Hence the -** column count for Index is u16 instead of i16. */ -#if !defined(SQLITE_MAX_COLUMN) +#ifndef SQLITE_MAX_COLUMN # define SQLITE_MAX_COLUMN 2000 -#elif SQLITE_MAX_COLUMN>32767 -# error SQLITE_MAX_COLUMN may not exceed 32767 #endif /* @@ -14911,7 +14844,6 @@ struct HashElem { HashElem *next, *prev; /* Next and previous elements in the table */ void *data; /* Data associated with this element */ const char *pKey; /* Key associated with this element */ - unsigned int h; /* hash for pKey */ }; /* @@ -15272,17 +15204,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); ** ourselves. */ #ifndef offsetof -#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) -#endif - -/* -** Work around C99 "flex-array" syntax for pre-C99 compilers, so as -** to avoid complaints from -fsanitize=strict-bounds. -*/ -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define FLEXARRAY -#else -# define FLEXARRAY 1 +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) #endif /* @@ -15360,11 +15282,6 @@ typedef INT16_TYPE i16; /* 2-byte signed integer */ typedef UINT8_TYPE u8; /* 1-byte unsigned integer */ typedef INT8_TYPE i8; /* 1-byte signed integer */ -/* A bitfield type for use inside of structures. Always follow with :N where -** N is the number of bits. -*/ -typedef unsigned bft; /* Bit Field Type */ - /* ** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value ** that can be stored in a u32 without loss of data. The value @@ -15533,14 +15450,6 @@ typedef INT16_TYPE LogEst; #define LARGEST_UINT64 (0xffffffff|(((u64)0xffffffff)<<32)) #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) -/* -** Macro SMXV(n) return the maximum value that can be held in variable n, -** assuming n is a signed integer type. UMXV(n) is similar for unsigned -** integer types. -*/ -#define SMXV(n) ((((i64)1)<<(sizeof(n)*8-1))-1) -#define UMXV(n) ((((i64)1)<<(sizeof(n)*8))-1) - /* ** Round up a number to the next larger multiple of 8. This is used ** to force 8-byte alignment on 64-bit architectures. @@ -17528,8 +17437,8 @@ SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); #endif -/* Use SQLITE_ENABLE_EXPLAIN_COMMENTS to enable generation of extra -** comments on each VDBE opcode. +/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on +** each VDBE opcode. ** ** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op ** comments in VDBE programs that show key decision points in the code @@ -18252,10 +18161,6 @@ struct sqlite3 { Savepoint *pSavepoint; /* List of active savepoints */ int nAnalysisLimit; /* Number of index rows to ANALYZE */ int busyTimeout; /* Busy handler timeout, in msec */ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - int setlkTimeout; /* Blocking lock timeout, in msec. -1 -> inf. */ - int setlkFlags; /* Flags passed to setlk_timeout() */ -#endif int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ @@ -18810,7 +18715,6 @@ struct CollSeq { #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ #define SQLITE_AFF_REAL 0x45 /* 'E' */ #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ -#define SQLITE_AFF_DEFER 0x58 /* 'X' - defer computation until later */ #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) @@ -18935,7 +18839,6 @@ struct Table { } u; Trigger *pTrigger; /* List of triggers on this object */ Schema *pSchema; /* Schema that contains this table */ - u8 aHx[16]; /* Column aHt[K%sizeof(aHt)] might have hash K */ }; /* @@ -19069,13 +18972,9 @@ struct FKey { struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ int iFrom; /* Index of column in pFrom */ char *zCol; /* Name of column in zTo. If NULL use PRIMARY KEY */ - } aCol[FLEXARRAY]; /* One entry for each of nCol columns */ + } aCol[1]; /* One entry for each of nCol columns */ }; -/* The size (in bytes) of an FKey object holding N columns. The answer -** does NOT include space to hold the zTo name. */ -#define SZ_FKEY(N) (offsetof(FKey,aCol)+(N)*sizeof(struct sColMap)) - /* ** SQLite supports many different ways to resolve a constraint ** error. ROLLBACK processing means that a constraint violation @@ -19137,12 +19036,9 @@ struct KeyInfo { u16 nAllField; /* Total columns, including key plus others */ sqlite3 *db; /* The database connection */ u8 *aSortFlags; /* Sort order for each column. */ - CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ + CollSeq *aColl[1]; /* Collating sequence for each term of the key */ }; -/* The size (in bytes) of a KeyInfo object with up to N fields */ -#define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) - /* ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. */ @@ -19262,7 +19158,7 @@ struct Index { Pgno tnum; /* DB Page containing root of this index */ LogEst szIdxRow; /* Estimated average row size in bytes */ u16 nKeyCol; /* Number of columns forming the key */ - u16 nColumn; /* Nr columns in btree. Can be 2*Table.nCol */ + u16 nColumn; /* Number of columns stored in the index */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ unsigned idxType:2; /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */ unsigned bUnordered:1; /* Use this index for == or IN queries only */ @@ -19271,8 +19167,10 @@ struct Index { unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ + unsigned bLowQual:1; /* sqlite_stat1 says this is a low-quality index */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ + unsigned bIdxRowid:1; /* One or more of the index keys is the ROWID */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ unsigned bHasExpr:1; /* Index contains an expression, either a literal ** expression, or a reference to a VIRTUAL column */ @@ -19360,7 +19258,7 @@ struct AggInfo { ** from source tables rather than from accumulators */ u8 useSortingIdx; /* In direct mode, reference the sorting index rather ** than the source table */ - u32 nSortingColumn; /* Number of columns in the sorting index */ + u16 nSortingColumn; /* Number of columns in the sorting index */ int sortingIdx; /* Cursor number of the sorting index */ int sortingIdxPTab; /* Cursor number of pseudo-table */ int iFirstReg; /* First register in range for aCol[] and aFunc[] */ @@ -19369,8 +19267,8 @@ struct AggInfo { Table *pTab; /* Source table */ Expr *pCExpr; /* The original expression */ int iTable; /* Cursor number of the source table */ - int iColumn; /* Column number within the source table */ - int iSorterColumn; /* Column number in the sorting index */ + i16 iColumn; /* Column number within the source table */ + i16 iSorterColumn; /* Column number in the sorting index */ } *aCol; int nColumn; /* Number of used entries in aCol[] */ int nAccumulator; /* Number of columns that show through to the output. @@ -19545,7 +19443,6 @@ struct Expr { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL ** for a column of an index on an expression */ Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */ - int nReg; /* TK_NULLS: Number of registers to NULL out */ struct { /* TK_IN, TK_SELECT, and TK_EXISTS */ int iAddr; /* Subroutine entry address */ int regReturn; /* Register used to hold return address */ @@ -19600,10 +19497,10 @@ struct Expr { /* Macros can be used to test, set, or clear bits in the ** Expr.flags field. */ -#define ExprHasProperty(E,P) (((E)->flags&(u32)(P))!=0) -#define ExprHasAllProperty(E,P) (((E)->flags&(u32)(P))==(u32)(P)) -#define ExprSetProperty(E,P) (E)->flags|=(u32)(P) -#define ExprClearProperty(E,P) (E)->flags&=~(u32)(P) +#define ExprHasProperty(E,P) (((E)->flags&(P))!=0) +#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P)) +#define ExprSetProperty(E,P) (E)->flags|=(P) +#define ExprClearProperty(E,P) (E)->flags&=~(P) #define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue) #define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse) #define ExprIsFullSize(E) (((E)->flags&(EP_Reduced|EP_TokenOnly))==0) @@ -19715,14 +19612,9 @@ struct ExprList { int iConstExprReg; /* Register in which Expr value is cached. Used only ** by Parse.pConstExpr */ } u; - } a[FLEXARRAY]; /* One slot for each expression in the list */ + } a[1]; /* One slot for each expression in the list */ }; -/* The size (in bytes) of an ExprList object that is big enough to hold -** as many as N expressions. */ -#define SZ_EXPRLIST(N) \ - (offsetof(ExprList,a) + (N)*sizeof(struct ExprList_item)) - /* ** Allowed values for Expr.a.eEName */ @@ -19750,12 +19642,9 @@ struct IdList { int nId; /* Number of identifiers on the list */ struct IdList_item { char *zName; /* Name of the identifier */ - } a[FLEXARRAY]; + } a[1]; }; -/* The size (in bytes) of an IdList object that can hold up to N IDs. */ -#define SZ_IDLIST(N) (offsetof(IdList,a)+(N)*sizeof(struct IdList_item)) - /* ** Allowed values for IdList.eType, which determines which value of the a.u4 ** is valid. @@ -19875,19 +19764,11 @@ struct OnOrUsing { ** */ struct SrcList { - int nSrc; /* Number of tables or subqueries in the FROM clause */ - u32 nAlloc; /* Number of entries allocated in a[] below */ - SrcItem a[FLEXARRAY]; /* One entry for each identifier on the list */ + int nSrc; /* Number of tables or subqueries in the FROM clause */ + u32 nAlloc; /* Number of entries allocated in a[] below */ + SrcItem a[1]; /* One entry for each identifier on the list */ }; -/* Size (in bytes) of a SrcList object that can hold as many as N -** SrcItem objects. */ -#define SZ_SRCLIST(N) (offsetof(SrcList,a)+(N)*sizeof(SrcItem)) - -/* Size (in bytes( of a SrcList object that holds 1 SrcItem. This is a -** special case of SZ_SRCITEM(1) that comes up often. */ -#define SZ_SRCLIST_1 (offsetof(SrcList,a)+sizeof(SrcItem)) - /* ** Permitted values of the SrcList.a.jointype field */ @@ -20356,32 +20237,25 @@ struct Parse { char *zErrMsg; /* An error message */ Vdbe *pVdbe; /* An engine for executing database bytecode */ int rc; /* Return code from execution */ - LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ + u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ + u8 checkSchema; /* Causes schema cookie check after an error */ u8 nested; /* Number of nested calls to the parser/code generator */ u8 nTempReg; /* Number of temporary registers in aTempReg[] */ u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ u8 mayAbort; /* True if statement may throw an ABORT exception */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ + u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ + u8 bHasWith; /* True if statement contains WITH */ u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ - u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ - u8 bReturning; /* Coding a RETURNING trigger */ - u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ - u8 disableTriggers; /* True to disable triggers */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif #ifdef SQLITE_DEBUG u8 ifNotExists; /* Might be true if IF NOT EXISTS. Assert()s only */ - u8 isCreate; /* CREATE TABLE, INDEX, or VIEW (but not TRIGGER) - ** and ALTER TABLE ADD COLUMN. */ #endif - bft colNamesSet :1; /* TRUE after OP_ColumnName has been issued to pVdbe */ - bft bHasWith :1; /* True if statement contains WITH */ - bft okConstFactor :1; /* OK to factor out constants */ - bft checkSchema :1; /* Causes schema cookie check after an error */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ @@ -20396,9 +20270,12 @@ struct Parse { ExprList *pConstExpr;/* Constant expressions */ IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ IndexedExpr *pIdxPartExpr; /* Exprs constrained by index WHERE clauses */ + Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ - int nMaxArg; /* Max args to xUpdate and xFilter vtab methods */ + int regRowid; /* Register holding rowid of CREATE TABLE entry */ + int regRoot; /* Register holding root page number for new objects */ + int nMaxArg; /* Max args passed to user function by sub-program */ int nSelect; /* Number of SELECT stmts. Counter for Select.selId */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */ @@ -20412,6 +20289,17 @@ struct Parse { Table *pTriggerTab; /* Table triggers are being coded for */ TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ + union { + int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ + Returning *pReturning; /* The RETURNING clause */ + } u1; + u32 oldmask; /* Mask of old.* columns referenced */ + u32 newmask; /* Mask of new.* columns referenced */ + LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ + u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ + u8 bReturning; /* Coding a RETURNING trigger */ + u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ + u8 disableTriggers; /* True to disable triggers */ /************************************************************************** ** Fields above must be initialized to zero. The fields that follow, @@ -20423,19 +20311,6 @@ struct Parse { int aTempReg[8]; /* Holding area for temporary registers */ Parse *pOuterParse; /* Outer Parse object when nested */ Token sNameToken; /* Token with unqualified schema object name */ - u32 oldmask; /* Mask of old.* columns referenced */ - u32 newmask; /* Mask of new.* columns referenced */ - union { - struct { /* These fields available when isCreate is true */ - int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ - int regRowid; /* Register holding rowid of CREATE TABLE entry */ - int regRoot; /* Register holding root page for new objects */ - Token constraintName; /* Name of the constraint currently being parsed */ - } cr; - struct { /* These fields available to all other statements */ - Returning *pReturning; /* The RETURNING clause */ - } d; - } u1; /************************************************************************ ** Above is constant between recursions. Below is reset before and after @@ -20951,13 +20826,9 @@ struct With { int nCte; /* Number of CTEs in the WITH clause */ int bView; /* Belongs to the outermost Select of a view */ With *pOuter; /* Containing WITH clause, or NULL */ - Cte a[FLEXARRAY]; /* For each CTE in the WITH clause.... */ + Cte a[1]; /* For each CTE in the WITH clause.... */ }; -/* The size (in bytes) of a With object that can hold as many -** as N different CTEs. */ -#define SZ_WITH(N) (offsetof(With,a) + (N)*sizeof(Cte)) - /* ** The Cte object is not guaranteed to persist for the entire duration ** of code generation. (The query flattener or other parser tree @@ -20986,13 +20857,9 @@ struct DbClientData { DbClientData *pNext; /* Next in a linked list */ void *pData; /* The data */ void (*xDestructor)(void*); /* Destructor. Might be NULL */ - char zName[FLEXARRAY]; /* Name of this client data. MUST BE LAST */ + char zName[1]; /* Name of this client data. MUST BE LAST */ }; -/* The size (in bytes) of a DbClientData object that can has a name -** that is N bytes long, including the zero-terminator. */ -#define SZ_DBCLIENTDATA(N) (offsetof(DbClientData,zName)+(N)) - #ifdef SQLITE_DEBUG /* ** An instance of the TreeView object is used for printing the content of @@ -21435,7 +21302,7 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char); SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int); SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); -SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index*, int); +SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index*, i16); #ifdef SQLITE_OMIT_GENERATED_COLUMNS # define sqlite3TableColumnToStorage(T,X) (X) /* No-op pass-through */ # define sqlite3StorageColumnToTable(T,X) (X) /* No-op pass-through */ @@ -21539,7 +21406,7 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*); SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); -SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,int,int,char**); +SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**); SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Expr*, int, int, u8); SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); @@ -21586,7 +21453,6 @@ SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int) SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int); -SQLITE_PRIVATE void sqlite3ExprNullRegisterRange(Parse*, int, int); SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*); SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int); SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); @@ -21676,8 +21542,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,const Select*,int); SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*); SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); -SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*,int); -SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char*, u32); +SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void); @@ -22542,9 +22407,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_BUG_COMPATIBLE_20160819 "BUG_COMPATIBLE_20160819", #endif -#ifdef SQLITE_BUG_COMPATIBLE_20250510 - "BUG_COMPATIBLE_20250510", -#endif #ifdef SQLITE_CASE_SENSITIVE_LIKE "CASE_SENSITIVE_LIKE", #endif @@ -22781,9 +22643,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_SESSION "ENABLE_SESSION", #endif -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - "ENABLE_SETLK_TIMEOUT", -#endif #ifdef SQLITE_ENABLE_SNAPSHOT "ENABLE_SNAPSHOT", #endif @@ -22838,9 +22697,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_EXTRA_INIT "EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT), #endif -#ifdef SQLITE_EXTRA_INIT_MUTEXED - "EXTRA_INIT_MUTEXED=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT_MUTEXED), -#endif #ifdef SQLITE_EXTRA_SHUTDOWN "EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN), #endif @@ -22853,9 +22709,11 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_FTS5_NO_WITHOUT_ROWID "FTS5_NO_WITHOUT_ROWID", #endif -#ifdef SQLITE_HAS_CODEC +/* BEGIN SQLCIPHER */ +#if SQLITE_HAS_CODEC "HAS_CODEC", #endif +/* END SQLCIPHER */ #if HAVE_ISNAN || SQLITE_HAVE_ISNAN "HAVE_ISNAN", #endif @@ -23837,19 +23695,12 @@ struct VdbeCursor { #endif VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */ - /* Space is allocated for aType to hold at least 2*nField+1 entries: - ** nField slots for aType[] and nField+1 array slots for aOffset[] */ - u32 aType[FLEXARRAY]; /* Type values record decode. MUST BE LAST */ + /* 2*nField extra array elements allocated for aType[], beyond the one + ** static element declared in the structure. nField total array slots for + ** aType[] and nField+1 array slots for aOffset[] */ + u32 aType[1]; /* Type values record decode. MUST BE LAST */ }; -/* -** The size (in bytes) of a VdbeCursor object that has an nField value of N -** or less. The value of SZ_VDBECURSOR(n) is guaranteed to be a multiple -** of 8. -*/ -#define SZ_VDBECURSOR(N) \ - (ROUND8(offsetof(VdbeCursor,aType)) + ((N)+1)*sizeof(u64)) - /* Return true if P is a null-only cursor */ #define IsNullCursor(P) \ @@ -24106,16 +23957,13 @@ struct sqlite3_context { u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ u16 argc; /* Number of arguments */ - sqlite3_value *argv[FLEXARRAY]; /* Argument set */ + sqlite3_value *argv[1]; /* Argument set */ }; -/* -** The size (in bytes) of an sqlite3_context object that holds N -** argv[] arguments. +/* A bitfield type for use inside of structures. Always follow with :N where +** N is the number of bits. */ -#define SZ_CONTEXT(N) \ - (offsetof(sqlite3_context,argv)+(N)*sizeof(sqlite3_value*)) - +typedef unsigned bft; /* Bit Field Type */ /* The ScanStatus object holds a single value for the ** sqlite3_stmt_scanstatus() interface. @@ -24176,7 +24024,7 @@ struct Vdbe { i64 nStmtDefCons; /* Number of def. constraints when stmt started */ i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ Mem *aMem; /* The memory locations */ - Mem **apArg; /* Arguments xUpdate and xFilter vtab methods */ + Mem **apArg; /* Arguments to currently executing user function */ VdbeCursor **apCsr; /* One element of this array for each open cursor */ Mem *aVar; /* Values for the OP_Variable opcode. */ @@ -24196,7 +24044,6 @@ struct Vdbe { #ifdef SQLITE_DEBUG int rcApp; /* errcode set by sqlite3_result_error_code() */ u32 nWrite; /* Number of write operations that have occurred */ - int napArg; /* Size of the apArg[] array */ #endif u16 nResColumn; /* Number of columns in one row of the result set */ u16 nResAlloc; /* Column slots allocated to aColName[] */ @@ -24249,7 +24096,7 @@ struct PreUpdate { VdbeCursor *pCsr; /* Cursor to read old values from */ int op; /* One of SQLITE_INSERT, UPDATE, DELETE */ u8 *aRecord; /* old.* database record */ - KeyInfo *pKeyinfo; /* Key information */ + KeyInfo keyinfo; UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */ int iNewReg; /* Register for new.* values */ @@ -24261,7 +24108,6 @@ struct PreUpdate { Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ sqlite3_value **apDflt; /* Array of default values, if required */ - u8 keyinfoSpace[SZ_KEYINFO(0)]; /* Space to hold pKeyinfo[0] content */ }; /* @@ -24628,9 +24474,8 @@ SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ nInit += countLookasideSlots(db->lookaside.pSmallInit); nFree += countLookasideSlots(db->lookaside.pSmallFree); #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ - assert( db->lookaside.nSlot >= nInit+nFree ); - if( pHighwater ) *pHighwater = (int)(db->lookaside.nSlot - nInit); - return (int)(db->lookaside.nSlot - (nInit+nFree)); + if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit; + return db->lookaside.nSlot - (nInit+nFree); } /* @@ -24683,7 +24528,7 @@ SQLITE_API int sqlite3_db_status( assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); *pCurrent = 0; - *pHighwater = (int)db->lookaside.anStat[op-SQLITE_DBSTATUS_LOOKASIDE_HIT]; + *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT]; if( resetFlag ){ db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; } @@ -26195,7 +26040,7 @@ static int daysAfterMonday(DateTime *pDate){ ** In other words, return the day of the week according ** to this code: ** -** 0=Sunday, 1=Monday, 2=Tuesday, ..., 6=Saturday +** 0=Sunday, 1=Monday, 2=Tues, ..., 6=Saturday */ static int daysAfterSunday(DateTime *pDate){ assert( pDate->validJD ); @@ -30404,8 +30249,6 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ #ifdef __CYGWIN__ # include -# include /* amalgamator: dontcache */ -# include /* amalgamator: dontcache */ # include /* amalgamator: dontcache */ #endif @@ -31811,17 +31654,17 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ #define etPERCENT 7 /* Percent symbol. %% */ #define etCHARX 8 /* Characters. %c */ /* The rest are extensions, not normally found in printf() */ -#define etESCAPE_q 9 /* Strings with '\'' doubled. %q */ -#define etESCAPE_Q 10 /* Strings with '\'' doubled and enclosed in '', - NULL pointers replaced by SQL NULL. %Q */ -#define etTOKEN 11 /* a pointer to a Token structure */ -#define etSRCITEM 12 /* a pointer to a SrcItem */ -#define etPOINTER 13 /* The %p conversion */ -#define etESCAPE_w 14 /* %w -> Strings with '\"' doubled */ -#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ -#define etDECIMAL 16 /* %d or %u, but not %x, %o */ +#define etSQLESCAPE 9 /* Strings with '\'' doubled. %q */ +#define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '', + NULL pointers replaced by SQL NULL. %Q */ +#define etTOKEN 11 /* a pointer to a Token structure */ +#define etSRCITEM 12 /* a pointer to a SrcItem */ +#define etPOINTER 13 /* The %p conversion */ +#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */ +#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ +#define etDECIMAL 16 /* %d or %u, but not %x, %o */ -#define etINVALID 17 /* Any unrecognized conversion type */ +#define etINVALID 17 /* Any unrecognized conversion type */ /* @@ -31860,9 +31703,9 @@ static const et_info fmtinfo[] = { { 's', 0, 4, etSTRING, 0, 0 }, { 'g', 0, 1, etGENERIC, 30, 0 }, { 'z', 0, 4, etDYNSTRING, 0, 0 }, - { 'q', 0, 4, etESCAPE_q, 0, 0 }, - { 'Q', 0, 4, etESCAPE_Q, 0, 0 }, - { 'w', 0, 4, etESCAPE_w, 0, 0 }, + { 'q', 0, 4, etSQLESCAPE, 0, 0 }, + { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, + { 'w', 0, 4, etSQLESCAPE3, 0, 0 }, { 'c', 0, 0, etCHARX, 0, 0 }, { 'o', 8, 0, etRADIX, 0, 2 }, { 'u', 10, 0, etDECIMAL, 0, 0 }, @@ -32459,7 +32302,25 @@ SQLITE_API void sqlite3_str_vappendf( } }else{ unsigned int ch = va_arg(ap,unsigned int); - length = sqlite3AppendOneUtf8Character(buf, ch); + if( ch<0x00080 ){ + buf[0] = ch & 0xff; + length = 1; + }else if( ch<0x00800 ){ + buf[0] = 0xc0 + (u8)((ch>>6)&0x1f); + buf[1] = 0x80 + (u8)(ch & 0x3f); + length = 2; + }else if( ch<0x10000 ){ + buf[0] = 0xe0 + (u8)((ch>>12)&0x0f); + buf[1] = 0x80 + (u8)((ch>>6) & 0x3f); + buf[2] = 0x80 + (u8)(ch & 0x3f); + length = 3; + }else{ + buf[0] = 0xf0 + (u8)((ch>>18) & 0x07); + buf[1] = 0x80 + (u8)((ch>>12) & 0x3f); + buf[2] = 0x80 + (u8)((ch>>6) & 0x3f); + buf[3] = 0x80 + (u8)(ch & 0x3f); + length = 4; + } } if( precision>1 ){ i64 nPrior = 1; @@ -32539,31 +32400,22 @@ SQLITE_API void sqlite3_str_vappendf( while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; } break; - case etESCAPE_q: /* %q: Escape ' characters */ - case etESCAPE_Q: /* %Q: Escape ' and enclose in '...' */ - case etESCAPE_w: { /* %w: Escape " characters */ + case etSQLESCAPE: /* %q: Escape ' characters */ + case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */ + case etSQLESCAPE3: { /* %w: Escape " characters */ i64 i, j, k, n; - int needQuote = 0; + int needQuote, isnull; char ch; + char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ char *escarg; - char q; if( bArgList ){ escarg = getTextArg(pArgList); }else{ escarg = va_arg(ap,char*); } - if( escarg==0 ){ - escarg = (xtype==etESCAPE_Q ? "NULL" : "(NULL)"); - }else if( xtype==etESCAPE_Q ){ - needQuote = 1; - } - if( xtype==etESCAPE_w ){ - q = '"'; - flag_alternateform = 0; - }else{ - q = '\''; - } + isnull = escarg==0; + if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); /* For %q, %Q, and %w, the precision is the number of bytes (or ** characters if the ! flags is present) to use from the input. ** Because of the extra quoting characters inserted, the number @@ -32576,30 +32428,7 @@ SQLITE_API void sqlite3_str_vappendf( while( (escarg[i+1]&0xc0)==0x80 ){ i++; } } } - if( flag_alternateform ){ - /* For %#q, do unistr()-style backslash escapes for - ** all control characters, and for backslash itself. - ** For %#Q, do the same but only if there is at least - ** one control character. */ - u32 nBack = 0; - u32 nCtrl = 0; - for(k=0; ketBUFSIZE ){ bufpt = zExtra = printfTempBuf(pAccum, n); @@ -32608,41 +32437,13 @@ SQLITE_API void sqlite3_str_vappendf( bufpt = buf; } j = 0; - if( needQuote ){ - if( needQuote==2 ){ - memcpy(&bufpt[j], "unistr('", 8); - j += 8; - }else{ - bufpt[j++] = '\''; - } - } + if( needQuote ) bufpt[j++] = q; k = i; - if( flag_alternateform ){ - for(i=0; i=0x10 ? '1' : '0'; - bufpt[j++] = "0123456789abcdef"[ch&0xf]; - } - } - }else{ - for(i=0; imxAlloc>0 && !isMalloced(p) ); - zText = sqlite3DbMallocRaw(p->db, 1+(u64)p->nChar ); + zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); if( zText ){ memcpy(zText, p->zText, p->nChar+1); p->printfFlags |= SQLITE_PRINTF_MALLOCED; @@ -33130,15 +32931,6 @@ SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ return zBuf; } -/* Maximum size of an sqlite3_log() message. */ -#if defined(SQLITE_MAX_LOG_MESSAGE) - /* Leave the definition as supplied */ -#elif SQLITE_PRINT_BUF_SIZE*10>10000 -# define SQLITE_MAX_LOG_MESSAGE 10000 -#else -# define SQLITE_MAX_LOG_MESSAGE (SQLITE_PRINT_BUF_SIZE*10) -#endif - /* ** This is the routine that actually formats the sqlite3_log() message. ** We house it in a separate routine from sqlite3_log() to avoid using @@ -33155,7 +32947,7 @@ SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ */ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ - char zMsg[SQLITE_MAX_LOG_MESSAGE]; /* Complete log message */ + char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); sqlite3_str_vappendf(&acc, zFormat, ap); @@ -35150,35 +34942,6 @@ static const unsigned char sqlite3Utf8Trans1[] = { } \ } -/* -** Write a single UTF8 character whose value is v into the -** buffer starting at zOut. zOut must be sized to hold at -** least four bytes. Return the number of bytes needed -** to encode the new character. -*/ -SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ - if( v<0x00080 ){ - zOut[0] = (u8)(v & 0xff); - return 1; - } - if( v<0x00800 ){ - zOut[0] = 0xc0 + (u8)((v>>6) & 0x1f); - zOut[1] = 0x80 + (u8)(v & 0x3f); - return 2; - } - if( v<0x10000 ){ - zOut[0] = 0xe0 + (u8)((v>>12) & 0x0f); - zOut[1] = 0x80 + (u8)((v>>6) & 0x3f); - zOut[2] = 0x80 + (u8)(v & 0x3f); - return 3; - } - zOut[0] = 0xf0 + (u8)((v>>18) & 0x07); - zOut[1] = 0x80 + (u8)((v>>12) & 0x3f); - zOut[2] = 0x80 + (u8)((v>>6) & 0x3f); - zOut[3] = 0x80 + (u8)(v & 0x3f); - return 4; -} - /* ** Translate a single UTF-8 character. Return the unicode value. ** @@ -35600,7 +35363,7 @@ SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nByte, int nChar){ int n = 0; if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++; - while( n=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2; @@ -36775,11 +36538,7 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou } p->z = &p->zBuf[i+1]; assert( i+p->n < sizeof(p->zBuf) ); - assert( p->n>0 ); - while( p->z[p->n-1]=='0' ){ - p->n--; - assert( p->n>0 ); - } + while( ALWAYS(p->n>0) && p->z[p->n-1]=='0' ){ p->n--; } } /* @@ -37286,7 +37045,7 @@ SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){ } /* -** Compute the absolute value of a 32-bit signed integer, if possible. Or +** Compute the absolute value of a 32-bit signed integer, of possible. Or ** if the integer has a value of -2147483648, return +2147483647 */ SQLITE_PRIVATE int sqlite3AbsInt32(int x){ @@ -37567,19 +37326,12 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){ */ static unsigned int strHash(const char *z){ unsigned int h = 0; - while( z[0] ){ /*OPTIMIZATION-IF-TRUE*/ + unsigned char c; + while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/ /* Knuth multiplicative hashing. (Sorting & Searching, p. 510). ** 0x9e3779b1 is 2654435761 which is the closest prime number to - ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. - ** - ** Only bits 0xdf for ASCII and bits 0xbf for EBCDIC each octet are - ** hashed since the omitted bits determine the upper/lower case difference. - */ -#ifdef SQLITE_EBCDIC - h += 0xbf & (unsigned char)*(z++); -#else - h += 0xdf & (unsigned char)*(z++); -#endif + ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */ + h += sqlite3UpperToLower[c]; h *= 0x9e3779b1; } return h; @@ -37652,8 +37404,9 @@ static int rehash(Hash *pH, unsigned int new_size){ pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); memset(new_ht, 0, new_size*sizeof(struct _ht)); for(elem=pH->first, pH->first=0; elem; elem = next_elem){ + unsigned int h = strHash(elem->pKey) % new_size; next_elem = elem->next; - insertElement(pH, &new_ht[elem->h % new_size], elem); + insertElement(pH, &new_ht[h], elem); } return 1; } @@ -37671,22 +37424,23 @@ static HashElem *findElementWithHash( HashElem *elem; /* Used to loop thru the element list */ unsigned int count; /* Number of elements left to test */ unsigned int h; /* The computed hash */ - static HashElem nullElement = { 0, 0, 0, 0, 0 }; + static HashElem nullElement = { 0, 0, 0, 0 }; - h = strHash(pKey); if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/ struct _ht *pEntry; - pEntry = &pH->ht[h % pH->htsize]; + h = strHash(pKey) % pH->htsize; + pEntry = &pH->ht[h]; elem = pEntry->chain; count = pEntry->count; }else{ + h = 0; elem = pH->first; count = pH->count; } if( pHash ) *pHash = h; while( count ){ assert( elem!=0 ); - if( h==elem->h && sqlite3StrICmp(elem->pKey,pKey)==0 ){ + if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ return elem; } elem = elem->next; @@ -37698,9 +37452,10 @@ static HashElem *findElementWithHash( /* Remove a single entry from the hash table given a pointer to that ** element and a hash on the element's key. */ -static void removeElement( +static void removeElementGivenHash( Hash *pH, /* The pH containing "elem" */ - HashElem *elem /* The element to be removed from the pH */ + HashElem* elem, /* The element to be removed from the pH */ + unsigned int h /* Hash value for the element */ ){ struct _ht *pEntry; if( elem->prev ){ @@ -37712,7 +37467,7 @@ static void removeElement( elem->next->prev = elem->prev; } if( pH->ht ){ - pEntry = &pH->ht[elem->h % pH->htsize]; + pEntry = &pH->ht[h]; if( pEntry->chain==elem ){ pEntry->chain = elem->next; } @@ -37763,7 +37518,7 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ if( elem->data ){ void *old_data = elem->data; if( data==0 ){ - removeElement(pH,elem); + removeElementGivenHash(pH,elem,h); }else{ elem->data = data; elem->pKey = pKey; @@ -37774,13 +37529,15 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); if( new_elem==0 ) return data; new_elem->pKey = pKey; - new_elem->h = h; new_elem->data = data; pH->count++; - if( pH->count>=5 && pH->count > 2*pH->htsize ){ - rehash(pH, pH->count*3); + if( pH->count>=10 && pH->count > 2*pH->htsize ){ + if( rehash(pH, pH->count*2) ){ + assert( pH->htsize>0 ); + h = strHash(pKey) % pH->htsize; + } } - insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem); + insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem); return 0; } @@ -39263,7 +39020,6 @@ struct unixFile { #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT unsigned iBusyTimeout; /* Wait this many millisec on locks */ - int bBlockOnConnect; /* True to block for SHARED locks */ #endif #if OS_VXWORKS struct vxworksFileId *pId; /* Unique file ID */ @@ -40657,13 +40413,6 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){ rc = 0; } }else{ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - if( pFile->bBlockOnConnect && pLock->l_type==F_RDLCK - && pLock->l_start==SHARED_FIRST && pLock->l_len==SHARED_SIZE - ){ - rc = osFcntl(pFile->h, F_SETLKW, pLock); - }else -#endif rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile); } return rc; @@ -43025,9 +42774,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT case SQLITE_FCNTL_LOCK_TIMEOUT: { int iOld = pFile->iBusyTimeout; - int iNew = *(int*)pArg; #if SQLITE_ENABLE_SETLK_TIMEOUT==1 - pFile->iBusyTimeout = iNew<0 ? 0x7FFFFFFF : (unsigned)iNew; + pFile->iBusyTimeout = *(int*)pArg; #elif SQLITE_ENABLE_SETLK_TIMEOUT==2 pFile->iBusyTimeout = !!(*(int*)pArg); #else @@ -43036,12 +42784,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ *(int*)pArg = iOld; return SQLITE_OK; } - case SQLITE_FCNTL_BLOCK_ON_CONNECT: { - int iNew = *(int*)pArg; - pFile->bBlockOnConnect = iNew; - return SQLITE_OK; - } -#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ +#endif #if SQLITE_MAX_MMAP_SIZE>0 case SQLITE_FCNTL_MMAP_SIZE: { i64 newLimit = *(i64*)pArg; @@ -44014,20 +43757,21 @@ static int unixShmLock( /* Check that, if this to be a blocking lock, no locks that occur later ** in the following list than the lock being obtained are already held: ** - ** 1. Recovery lock (ofst==2). - ** 2. Checkpointer lock (ofst==1). - ** 3. Write lock (ofst==0). - ** 4. Read locks (ofst>=3 && ofst=3 && ofstexclMask|p->sharedMask); assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( - (ofst!=2 || lockMask==0) + (ofst!=2) /* not RECOVER */ && (ofst!=1 || lockMask==0 || lockMask==2) && (ofst!=0 || lockMask<3) && (ofst<3 || lockMask<(1<iBusyTimeout -#else -# define winFileBusyTimeout(pDbFd) 0 -#endif - /* ** The winVfsAppData structure is used for the pAppData member for all of the ** Win32 VFS variants. @@ -47883,7 +47617,7 @@ static struct win_syscall { { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, #endif -#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(const FILETIME*, \ +#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \ LPFILETIME))aSyscall[11].pCurrent) #if SQLITE_OS_WINCE @@ -47892,7 +47626,7 @@ static struct win_syscall { { "FileTimeToSystemTime", (SYSCALL)0, 0 }, #endif -#define osFileTimeToSystemTime ((BOOL(WINAPI*)(const FILETIME*, \ +#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \ LPSYSTEMTIME))aSyscall[12].pCurrent) { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, @@ -47998,12 +47732,6 @@ static struct win_syscall { #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ LPWSTR*))aSyscall[25].pCurrent) -/* -** For GetLastError(), MSDN says: -** -** Minimum supported client: Windows XP [desktop apps | UWP apps] -** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] -*/ { "GetLastError", (SYSCALL)GetLastError, 0 }, #define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) @@ -48172,7 +47900,7 @@ static struct win_syscall { { "LockFile", (SYSCALL)0, 0 }, #endif -#if !defined(osLockFile) && defined(SQLITE_WIN32_HAS_ANSI) +#ifndef osLockFile #define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ DWORD))aSyscall[47].pCurrent) #endif @@ -48236,7 +47964,7 @@ static struct win_syscall { { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, -#define osSystemTimeToFileTime ((BOOL(WINAPI*)(const SYSTEMTIME*, \ +#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ LPFILETIME))aSyscall[56].pCurrent) #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT @@ -48245,7 +47973,7 @@ static struct win_syscall { { "UnlockFile", (SYSCALL)0, 0 }, #endif -#if !defined(osUnlockFile) && defined(SQLITE_WIN32_HAS_ANSI) +#ifndef osUnlockFile #define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ DWORD))aSyscall[57].pCurrent) #endif @@ -48286,13 +48014,11 @@ static struct win_syscall { #define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ DWORD,DWORD))aSyscall[62].pCurrent) -/* -** For WaitForSingleObject(), MSDN says: -** -** Minimum supported client: Windows XP [desktop apps | UWP apps] -** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] -*/ +#if !SQLITE_OS_WINRT { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, +#else + { "WaitForSingleObject", (SYSCALL)0, 0 }, +#endif #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ DWORD))aSyscall[63].pCurrent) @@ -48439,97 +48165,6 @@ static struct win_syscall { #define osFlushViewOfFile \ ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) -/* -** If SQLITE_ENABLE_SETLK_TIMEOUT is defined, we require CreateEvent() -** to implement blocking locks with timeouts. MSDN says: -** -** Minimum supported client: Windows XP [desktop apps | UWP apps] -** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] -*/ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - { "CreateEvent", (SYSCALL)CreateEvent, 0 }, -#else - { "CreateEvent", (SYSCALL)0, 0 }, -#endif - -#define osCreateEvent ( \ - (HANDLE(WINAPI*) (LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR)) \ - aSyscall[80].pCurrent \ -) - -/* -** If SQLITE_ENABLE_SETLK_TIMEOUT is defined, we require CancelIo() -** for the case where a timeout expires and a lock request must be -** cancelled. -** -** Minimum supported client: Windows XP [desktop apps | UWP apps] -** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] -*/ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - { "CancelIo", (SYSCALL)CancelIo, 0 }, -#else - { "CancelIo", (SYSCALL)0, 0 }, -#endif - -#define osCancelIo ((BOOL(WINAPI*)(HANDLE))aSyscall[81].pCurrent) - -#if defined(SQLITE_WIN32_HAS_WIDE) && defined(_WIN32) - { "GetModuleHandleW", (SYSCALL)GetModuleHandleW, 0 }, -#else - { "GetModuleHandleW", (SYSCALL)0, 0 }, -#endif - -#define osGetModuleHandleW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[82].pCurrent) - -#ifndef _WIN32 - { "getenv", (SYSCALL)getenv, 0 }, -#else - { "getenv", (SYSCALL)0, 0 }, -#endif - -#define osGetenv ((const char *(*)(const char *))aSyscall[83].pCurrent) - -#ifndef _WIN32 - { "getcwd", (SYSCALL)getcwd, 0 }, -#else - { "getcwd", (SYSCALL)0, 0 }, -#endif - -#define osGetcwd ((char*(*)(char*,size_t))aSyscall[84].pCurrent) - -#ifndef _WIN32 - { "readlink", (SYSCALL)readlink, 0 }, -#else - { "readlink", (SYSCALL)0, 0 }, -#endif - -#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[85].pCurrent) - -#ifndef _WIN32 - { "lstat", (SYSCALL)lstat, 0 }, -#else - { "lstat", (SYSCALL)0, 0 }, -#endif - -#define osLstat ((int(*)(const char*,struct stat*))aSyscall[86].pCurrent) - -#ifndef _WIN32 - { "__errno", (SYSCALL)__errno, 0 }, -#else - { "__errno", (SYSCALL)0, 0 }, -#endif - -#define osErrno (*((int*(*)(void))aSyscall[87].pCurrent)()) - -#ifndef _WIN32 - { "cygwin_conv_path", (SYSCALL)cygwin_conv_path, 0 }, -#else - { "cygwin_conv_path", (SYSCALL)0, 0 }, -#endif - -#define osCygwin_conv_path ((size_t(*)(unsigned int, \ - const void *, void *, size_t))aSyscall[88].pCurrent) - }; /* End of the overrideable system calls */ /* @@ -48703,7 +48338,6 @@ SQLITE_API int sqlite3_win32_reset_heap(){ } #endif /* SQLITE_WIN32_MALLOC */ -#ifdef _WIN32 /* ** This function outputs the specified (ANSI) string to the Win32 debugger ** (if available). @@ -48746,7 +48380,6 @@ SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ } #endif } -#endif /* _WIN32 */ /* ** The following routine suspends the current thread for at least ms @@ -48830,9 +48463,7 @@ SQLITE_API int sqlite3_win32_is_nt(void){ } return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; #elif SQLITE_TEST - return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2 - || osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 - ; + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; #else /* ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are @@ -49047,7 +48678,6 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){ } #endif /* SQLITE_WIN32_MALLOC */ -#ifdef _WIN32 /* ** Convert a UTF-8 string to Microsoft Unicode. ** @@ -49073,7 +48703,6 @@ static LPWSTR winUtf8ToUnicode(const char *zText){ } return zWideText; } -#endif /* _WIN32 */ /* ** Convert a Microsoft Unicode string to UTF-8. @@ -49108,29 +48737,28 @@ static char *winUnicodeToUtf8(LPCWSTR zWideText){ ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ - int nWideChar; + int nByte; LPWSTR zMbcsText; int codepage = useAnsi ? CP_ACP : CP_OEMCP; - nWideChar = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, - 0); - if( nWideChar==0 ){ + nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, + 0)*sizeof(WCHAR); + if( nByte==0 ){ return 0; } - zMbcsText = sqlite3MallocZero( nWideChar*sizeof(WCHAR) ); + zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) ); if( zMbcsText==0 ){ return 0; } - nWideChar = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, - nWideChar); - if( nWideChar==0 ){ + nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, + nByte); + if( nByte==0 ){ sqlite3_free(zMbcsText); zMbcsText = 0; } return zMbcsText; } -#ifdef _WIN32 /* ** Convert a Microsoft Unicode string to a multi-byte character string, ** using the ANSI or OEM code page. @@ -49158,7 +48786,6 @@ static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ } return zText; } -#endif /* _WIN32 */ /* ** Convert a multi-byte character string to UTF-8. @@ -49178,7 +48805,6 @@ static char *winMbcsToUtf8(const char *zText, int useAnsi){ return zTextUtf8; } -#ifdef _WIN32 /* ** Convert a UTF-8 string to a multi-byte character string. ** @@ -49228,7 +48854,6 @@ SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ #endif return winUnicodeToUtf8(zWideText); } -#endif /* _WIN32 */ /* ** This is a public wrapper for the winMbcsToUtf8() function. @@ -49246,7 +48871,6 @@ SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){ return winMbcsToUtf8(zText, osAreFileApisANSI()); } -#ifdef _WIN32 /* ** This is a public wrapper for the winMbcsToUtf8() function. */ @@ -49371,7 +48995,6 @@ SQLITE_API int sqlite3_win32_set_directory( ){ return sqlite3_win32_set_directory16(type, zValue); } -#endif /* _WIN32 */ /* ** The return value of winGetLastErrorMsg @@ -49920,98 +49543,13 @@ static BOOL winLockFile( ovlp.Offset = offsetLow; ovlp.OffsetHigh = offsetHigh; return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); -#ifdef SQLITE_WIN32_HAS_ANSI }else{ return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow, numBytesHigh); -#endif } #endif } -/* -** Lock a region of nByte bytes starting at offset offset of file hFile. -** Take an EXCLUSIVE lock if parameter bExclusive is true, or a SHARED lock -** otherwise. If nMs is greater than zero and the lock cannot be obtained -** immediately, block for that many ms before giving up. -** -** This function returns SQLITE_OK if the lock is obtained successfully. If -** some other process holds the lock, SQLITE_BUSY is returned if nMs==0, or -** SQLITE_BUSY_TIMEOUT otherwise. Or, if an error occurs, SQLITE_IOERR. -*/ -static int winHandleLockTimeout( - HANDLE hFile, - DWORD offset, - DWORD nByte, - int bExcl, - DWORD nMs -){ - DWORD flags = LOCKFILE_FAIL_IMMEDIATELY | (bExcl?LOCKFILE_EXCLUSIVE_LOCK:0); - int rc = SQLITE_OK; - BOOL ret; - - if( !osIsNT() ){ - ret = winLockFile(&hFile, flags, offset, 0, nByte, 0); - }else{ - OVERLAPPED ovlp; - memset(&ovlp, 0, sizeof(OVERLAPPED)); - ovlp.Offset = offset; - -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - if( nMs!=0 ){ - flags &= ~LOCKFILE_FAIL_IMMEDIATELY; - } - ovlp.hEvent = osCreateEvent(NULL, TRUE, FALSE, NULL); - if( ovlp.hEvent==NULL ){ - return SQLITE_IOERR_LOCK; - } -#endif - - ret = osLockFileEx(hFile, flags, 0, nByte, 0, &ovlp); - -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - /* If SQLITE_ENABLE_SETLK_TIMEOUT is defined, then the file-handle was - ** opened with FILE_FLAG_OVERHEAD specified. In this case, the call to - ** LockFileEx() may fail because the request is still pending. This can - ** happen even if LOCKFILE_FAIL_IMMEDIATELY was specified. - ** - ** If nMs is 0, then LOCKFILE_FAIL_IMMEDIATELY was set in the flags - ** passed to LockFileEx(). In this case, if the operation is pending, - ** block indefinitely until it is finished. - ** - ** Otherwise, wait for up to nMs ms for the operation to finish. nMs - ** may be set to INFINITE. - */ - if( !ret && GetLastError()==ERROR_IO_PENDING ){ - DWORD nDelay = (nMs==0 ? INFINITE : nMs); - DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay); - if( res==WAIT_OBJECT_0 ){ - ret = TRUE; - }else if( res==WAIT_TIMEOUT ){ -#if SQLITE_ENABLE_SETLK_TIMEOUT==1 - rc = SQLITE_BUSY_TIMEOUT; -#else - rc = SQLITE_BUSY; -#endif - }else{ - /* Some other error has occurred */ - rc = SQLITE_IOERR_LOCK; - } - - /* If it is still pending, cancel the LockFileEx() call. */ - osCancelIo(hFile); - } - - osCloseHandle(ovlp.hEvent); -#endif - } - - if( rc==SQLITE_OK && !ret ){ - rc = SQLITE_BUSY; - } - return rc; -} - /* ** Unlock a file region. */ @@ -50036,23 +49574,13 @@ static BOOL winUnlockFile( ovlp.Offset = offsetLow; ovlp.OffsetHigh = offsetHigh; return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); -#ifdef SQLITE_WIN32_HAS_ANSI }else{ return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow, numBytesHigh); -#endif } #endif } -/* -** Remove an nByte lock starting at offset iOff from HANDLE h. -*/ -static int winHandleUnlock(HANDLE h, int iOff, int nByte){ - BOOL ret = winUnlockFile(&h, iOff, 0, nByte, 0); - return (ret ? SQLITE_OK : SQLITE_IOERR_UNLOCK); -} - /***************************************************************************** ** The next group of routines implement the I/O methods specified ** by the sqlite3_io_methods object. @@ -50066,69 +49594,65 @@ static int winHandleUnlock(HANDLE h, int iOff, int nByte){ #endif /* -** Seek the file handle h to offset nByte of the file. -** -** If successful, return SQLITE_OK. Or, if an error occurs, return an SQLite -** error code. +** Move the current position of the file handle passed as the first +** argument to offset iOffset within the file. If successful, return 0. +** Otherwise, set pFile->lastErrno and return non-zero. */ -static int winHandleSeek(HANDLE h, sqlite3_int64 iOffset){ - int rc = SQLITE_OK; /* Return value */ - +static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ #if !SQLITE_OS_WINRT LONG upperBits; /* Most sig. 32 bits of new offset */ LONG lowerBits; /* Least sig. 32 bits of new offset */ DWORD dwRet; /* Value returned by SetFilePointer() */ + DWORD lastErrno; /* Value returned by GetLastError() */ + + OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset)); upperBits = (LONG)((iOffset>>32) & 0x7fffffff); lowerBits = (LONG)(iOffset & 0xffffffff); - dwRet = osSetFilePointer(h, lowerBits, &upperBits, FILE_BEGIN); - /* API oddity: If successful, SetFilePointer() returns a dword ** containing the lower 32-bits of the new file-offset. Or, if it fails, ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine ** whether an error has actually occurred, it is also necessary to call - ** GetLastError(). */ - if( dwRet==INVALID_SET_FILE_POINTER ){ - DWORD lastErrno = osGetLastError(); - if( lastErrno!=NO_ERROR ){ - rc = SQLITE_IOERR_SEEK; - } + ** GetLastError(). + */ + dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); + + if( (dwRet==INVALID_SET_FILE_POINTER + && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, + "winSeekFile", pFile->zPath); + OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); + return 1; } + + OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); + return 0; #else - /* This implementation works for WinRT. */ + /* + ** Same as above, except that this implementation works for WinRT. + */ + LARGE_INTEGER x; /* The new offset */ BOOL bRet; /* Value returned by SetFilePointerEx() */ x.QuadPart = iOffset; - bRet = osSetFilePointerEx(h, x, 0, FILE_BEGIN); + bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); if(!bRet){ - rc = SQLITE_IOERR_SEEK; - } -#endif - - OSTRACE(("SEEK file=%p, offset=%lld rc=%s\n", h, iOffset, sqlite3ErrName(rc))); - return rc; -} - -/* -** Move the current position of the file handle passed as the first -** argument to offset iOffset within the file. If successful, return 0. -** Otherwise, set pFile->lastErrno and return non-zero. -*/ -static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ - int rc; - - rc = winHandleSeek(pFile->h, iOffset); - if( rc!=SQLITE_OK ){ pFile->lastErrno = osGetLastError(); - winLogError(rc, pFile->lastErrno, "winSeekFile", pFile->zPath); + winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, + "winSeekFile", pFile->zPath); + OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); + return 1; } - return rc; -} + OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); + return 0; +#endif +} #if SQLITE_MAX_MMAP_SIZE>0 /* Forward references to VFS helper methods used for memory mapped files */ @@ -50389,60 +49913,6 @@ static int winWrite( return SQLITE_OK; } -/* -** Truncate the file opened by handle h to nByte bytes in size. -*/ -static int winHandleTruncate(HANDLE h, sqlite3_int64 nByte){ - int rc = SQLITE_OK; /* Return code */ - rc = winHandleSeek(h, nByte); - if( rc==SQLITE_OK ){ - if( 0==osSetEndOfFile(h) ){ - rc = SQLITE_IOERR_TRUNCATE; - } - } - return rc; -} - -/* -** Determine the size in bytes of the file opened by the handle passed as -** the first argument. -*/ -static int winHandleSize(HANDLE h, sqlite3_int64 *pnByte){ - int rc = SQLITE_OK; - -#if SQLITE_OS_WINRT - FILE_STANDARD_INFO info; - BOOL b; - b = osGetFileInformationByHandleEx(h, FileStandardInfo, &info, sizeof(info)); - if( b ){ - *pnByte = info.EndOfFile.QuadPart; - }else{ - rc = SQLITE_IOERR_FSTAT; - } -#else - DWORD upperBits = 0; - DWORD lowerBits = 0; - - assert( pnByte ); - lowerBits = osGetFileSize(h, &upperBits); - *pnByte = (((sqlite3_int64)upperBits)<<32) + lowerBits; - if( lowerBits==INVALID_FILE_SIZE && osGetLastError()!=NO_ERROR ){ - rc = SQLITE_IOERR_FSTAT; - } -#endif - - return rc; -} - -/* -** Close the handle passed as the only argument. -*/ -static void winHandleClose(HANDLE h){ - if( h!=INVALID_HANDLE_VALUE ){ - osCloseHandle(h); - } -} - /* ** Truncate an open file to a specified size */ @@ -50698,9 +50168,8 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ ** Different API routines are called depending on whether or not this ** is Win9x or WinNT. */ -static int winGetReadLock(winFile *pFile, int bBlock){ +static int winGetReadLock(winFile *pFile){ int res; - DWORD mask = ~(bBlock ? LOCKFILE_FAIL_IMMEDIATELY : 0); OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); if( osIsNT() ){ #if SQLITE_OS_WINCE @@ -50710,7 +50179,7 @@ static int winGetReadLock(winFile *pFile, int bBlock){ */ res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); #else - res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS&mask, SHARED_FIRST, 0, + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0, SHARED_SIZE, 0); #endif } @@ -50719,7 +50188,7 @@ static int winGetReadLock(winFile *pFile, int bBlock){ int lk; sqlite3_randomness(sizeof(lk), &lk); pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); - res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS&mask, + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); } #endif @@ -50814,62 +50283,46 @@ static int winLock(sqlite3_file *id, int locktype){ assert( locktype!=PENDING_LOCK ); assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); - /* Lock the PENDING_LOCK byte if we need to acquire an EXCLUSIVE lock or + /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of ** the PENDING_LOCK byte is temporary. */ newLocktype = pFile->locktype; - if( locktype==SHARED_LOCK - || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) + if( pFile->locktype==NO_LOCK + || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK) ){ int cnt = 3; - - /* Flags for the LockFileEx() call. This should be an exclusive lock if - ** this call is to obtain EXCLUSIVE, or a shared lock if this call is to - ** obtain SHARED. */ - int flags = LOCKFILE_FAIL_IMMEDIATELY; - if( locktype==EXCLUSIVE_LOCK ){ - flags |= LOCKFILE_EXCLUSIVE_LOCK; - } - while( cnt>0 ){ + while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, + PENDING_BYTE, 0, 1, 0))==0 ){ /* Try 3 times to get the pending lock. This is needed to work ** around problems caused by indexing and/or anti-virus software on ** Windows systems. - ** ** If you are using this code as a model for alternative VFSes, do not - ** copy this retry logic. It is a hack intended for Windows only. */ - res = winLockFile(&pFile->h, flags, PENDING_BYTE, 0, 1, 0); - if( res ) break; - + ** copy this retry logic. It is a hack intended for Windows only. + */ lastErrno = osGetLastError(); OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", - pFile->h, cnt, res - )); - + pFile->h, cnt, res)); if( lastErrno==ERROR_INVALID_HANDLE ){ pFile->lastErrno = lastErrno; rc = SQLITE_IOERR_LOCK; OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n", - pFile->h, cnt, sqlite3ErrName(rc) - )); + pFile->h, cnt, sqlite3ErrName(rc))); return rc; } - - cnt--; - if( cnt>0 ) sqlite3_win32_sleep(1); + if( cnt ) sqlite3_win32_sleep(1); } gotPendingLock = res; + if( !res ){ + lastErrno = osGetLastError(); + } } /* Acquire a shared lock */ if( locktype==SHARED_LOCK && res ){ assert( pFile->locktype==NO_LOCK ); -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - res = winGetReadLock(pFile, pFile->bBlockOnConnect); -#else - res = winGetReadLock(pFile, 0); -#endif + res = winGetReadLock(pFile); if( res ){ newLocktype = SHARED_LOCK; }else{ @@ -50907,7 +50360,7 @@ static int winLock(sqlite3_file *id, int locktype){ newLocktype = EXCLUSIVE_LOCK; }else{ lastErrno = osGetLastError(); - winGetReadLock(pFile, 0); + winGetReadLock(pFile); } } @@ -50987,7 +50440,7 @@ static int winUnlock(sqlite3_file *id, int locktype){ type = pFile->locktype; if( type>=EXCLUSIVE_LOCK ){ winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); - if( locktype==SHARED_LOCK && !winGetReadLock(pFile, 0) ){ + if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ /* This should never happen. We should always be able to ** reacquire the read lock */ rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), @@ -51197,28 +50650,6 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ return rc; } #endif - -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - case SQLITE_FCNTL_LOCK_TIMEOUT: { - int iOld = pFile->iBusyTimeout; - int iNew = *(int*)pArg; -#if SQLITE_ENABLE_SETLK_TIMEOUT==1 - pFile->iBusyTimeout = (iNew < 0) ? INFINITE : (DWORD)iNew; -#elif SQLITE_ENABLE_SETLK_TIMEOUT==2 - pFile->iBusyTimeout = (DWORD)(!!iNew); -#else -# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" -#endif - *(int*)pArg = iOld; - return SQLITE_OK; - } - case SQLITE_FCNTL_BLOCK_ON_CONNECT: { - int iNew = *(int*)pArg; - pFile->bBlockOnConnect = iNew; - return SQLITE_OK; - } -#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ - } OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); return SQLITE_NOTFOUND; @@ -51299,27 +50730,23 @@ static int winShmMutexHeld(void) { ** ** The following fields are read-only after the object is created: ** +** fid ** zFilename ** ** Either winShmNode.mutex must be held or winShmNode.nRef==0 and ** winShmMutexHeld() is true when reading or writing any other field ** in this structure. ** -** File-handle hSharedShm is used to (a) take the DMS lock, (b) truncate -** the *-shm file if the DMS-locking protocol demands it, and (c) map -** regions of the *-shm file into memory using MapViewOfFile() or -** similar. Other locks are taken by individual clients using the -** winShm.hShm handles. */ struct winShmNode { sqlite3_mutex *mutex; /* Mutex to access this object */ char *zFilename; /* Name of the file */ - HANDLE hSharedShm; /* File handle open on zFilename */ + winFile hFile; /* File handle from winOpen */ - int isUnlocked; /* DMS lock has not yet been obtained */ - int isReadonly; /* True if read-only */ int szRegion; /* Size of shared-memory regions */ int nRegion; /* Size of array apRegion */ + u8 isReadonly; /* True if read-only */ + u8 isUnlocked; /* True if no DMS lock held */ struct ShmRegion { HANDLE hMap; /* File handle from CreateFileMapping */ @@ -51328,6 +50755,7 @@ struct winShmNode { DWORD lastErrno; /* The Windows errno from the last I/O error */ int nRef; /* Number of winShm objects pointing to this */ + winShm *pFirst; /* All winShm objects pointing to this */ winShmNode *pNext; /* Next in list of all winShmNode objects */ #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) u8 nextShmId; /* Next available winShm.id value */ @@ -51343,15 +50771,23 @@ static winShmNode *winShmNodeList = 0; /* ** Structure used internally by this VFS to record the state of an -** open shared memory connection. There is one such structure for each -** winFile open on a wal mode database. +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** winShm.pShmNode +** winShm.id +** +** All other fields are read/write. The winShm.pShmNode->mutex must be held +** while accessing any read/write fields. */ struct winShm { winShmNode *pShmNode; /* The underlying winShmNode object */ + winShm *pNext; /* Next winShm with the same winShmNode */ + u8 hasMutex; /* True if holding the winShmNode mutex */ u16 sharedMask; /* Mask of shared locks held */ u16 exclMask; /* Mask of exclusive locks held */ - HANDLE hShm; /* File-handle on *-shm file. For locking. */ - int bReadonly; /* True if hShm is opened read-only */ #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) u8 id; /* Id of this connection with its winShmNode */ #endif @@ -51363,6 +50799,50 @@ struct winShm { #define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ #define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ +/* +** Apply advisory locks for all n bytes beginning at ofst. +*/ +#define WINSHM_UNLCK 1 +#define WINSHM_RDLCK 2 +#define WINSHM_WRLCK 3 +static int winShmSystemLock( + winShmNode *pFile, /* Apply locks to this open shared-memory segment */ + int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ + int ofst, /* Offset to first byte to be locked/unlocked */ + int nByte /* Number of bytes to lock or unlock */ +){ + int rc = 0; /* Result code form Lock/UnlockFileEx() */ + + /* Access to the winShmNode object is serialized by the caller */ + assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) ); + + OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", + pFile->hFile.h, lockType, ofst, nByte)); + + /* Release/Acquire the system-level lock */ + if( lockType==WINSHM_UNLCK ){ + rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); + }else{ + /* Initialize the locking parameters */ + DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; + if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; + rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); + } + + if( rc!= 0 ){ + rc = SQLITE_OK; + }else{ + pFile->lastErrno = osGetLastError(); + rc = SQLITE_BUSY; + } + + OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", + pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" : + "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); + + return rc; +} + /* Forward references to VFS methods */ static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); static int winDelete(sqlite3_vfs *,const char*,int); @@ -51394,7 +50874,11 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); UNUSED_VARIABLE_VALUE(bRc); } - winHandleClose(p->hSharedShm); + if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ + SimulateIOErrorBenign(1); + winClose((sqlite3_file *)&p->hFile); + SimulateIOErrorBenign(0); + } if( deleteFlag ){ SimulateIOErrorBenign(1); sqlite3BeginBenignMalloc(); @@ -51412,239 +50896,42 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ } /* -** The DMS lock has not yet been taken on the shm file associated with -** pShmNode. Take the lock. Truncate the *-shm file if required. -** Return SQLITE_OK if successful, or an SQLite error code otherwise. +** The DMS lock has not yet been taken on shm file pShmNode. Attempt to +** take it now. Return SQLITE_OK if successful, or an SQLite error +** code otherwise. +** +** If the DMS cannot be locked because this is a readonly_shm=1 +** connection and no other process already holds a lock, return +** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. */ -static int winLockSharedMemory(winShmNode *pShmNode, DWORD nMs){ - HANDLE h = pShmNode->hSharedShm; - int rc = SQLITE_OK; +static int winLockSharedMemory(winShmNode *pShmNode){ + int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1); - assert( sqlite3_mutex_held(pShmNode->mutex) ); - rc = winHandleLockTimeout(h, WIN_SHM_DMS, 1, 1, 0); if( rc==SQLITE_OK ){ - /* We have an EXCLUSIVE lock on the DMS byte. This means that this - ** is the first process to open the file. Truncate it to zero bytes - ** in this case. */ if( pShmNode->isReadonly ){ - rc = SQLITE_READONLY_CANTINIT; - }else{ - rc = winHandleTruncate(h, 0); + pShmNode->isUnlocked = 1; + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + return SQLITE_READONLY_CANTINIT; + }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){ + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), + "winLockSharedMemory", pShmNode->zFilename); } - - /* Release the EXCLUSIVE lock acquired above. */ - winUnlockFile(&h, WIN_SHM_DMS, 0, 1, 0); - }else if( (rc & 0xFF)==SQLITE_BUSY ){ - rc = SQLITE_OK; } if( rc==SQLITE_OK ){ - /* Take a SHARED lock on the DMS byte. */ - rc = winHandleLockTimeout(h, WIN_SHM_DMS, 1, 0, nMs); - if( rc==SQLITE_OK ){ - pShmNode->isUnlocked = 0; - } + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); } - return rc; + return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); } - -/* -** Convert a UTF-8 filename into whatever form the underlying -** operating system wants filenames in. Space to hold the result -** is obtained from malloc and must be freed by the calling -** function -** -** On Cygwin, 3 possible input forms are accepted: -** - If the filename starts with ":/" or ":\", -** it is converted to UTF-16 as-is. -** - If the filename contains '/', it is assumed to be a -** Cygwin absolute path, it is converted to a win32 -** absolute path in UTF-16. -** - Otherwise it must be a filename only, the win32 filename -** is returned in UTF-16. -** Note: If the function cygwin_conv_path() fails, only -** UTF-8 -> UTF-16 conversion will be done. This can only -** happen when the file path >32k, in which case winUtf8ToUnicode() -** will fail too. -*/ -static void *winConvertFromUtf8Filename(const char *zFilename){ - void *zConverted = 0; - if( osIsNT() ){ -#ifdef __CYGWIN__ - int nChar; - LPWSTR zWideFilename; - - if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) - && winIsDirSep(zFilename[2])) ){ - i64 nByte; - int convertflag = CCP_POSIX_TO_WIN_W; - if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; - nByte = (i64)osCygwin_conv_path(convertflag, - zFilename, 0, 0); - if( nByte>0 ){ - zConverted = sqlite3MallocZero(12+(u64)nByte); - if ( zConverted==0 ){ - return zConverted; - } - zWideFilename = zConverted; - /* Filenames should be prefixed, except when converted - * full path already starts with "\\?\". */ - if( osCygwin_conv_path(convertflag, zFilename, - zWideFilename+4, nByte)==0 ){ - if( (convertflag&CCP_RELATIVE) ){ - memmove(zWideFilename, zWideFilename+4, nByte); - }else if( memcmp(zWideFilename+4, L"\\\\", 4) ){ - memcpy(zWideFilename, L"\\\\?\\", 8); - }else if( zWideFilename[6]!='?' ){ - memmove(zWideFilename+6, zWideFilename+4, nByte); - memcpy(zWideFilename, L"\\\\?\\UNC", 14); - }else{ - memmove(zWideFilename, zWideFilename+4, nByte); - } - return zConverted; - } - sqlite3_free(zConverted); - } - } - nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); - if( nChar==0 ){ - return 0; - } - zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); - if( zWideFilename==0 ){ - return 0; - } - nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, - zWideFilename, nChar); - if( nChar==0 ){ - sqlite3_free(zWideFilename); - zWideFilename = 0; - }else if( nChar>MAX_PATH - && winIsDriveLetterAndColon(zFilename) - && winIsDirSep(zFilename[2]) ){ - memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); - zWideFilename[2] = '\\'; - memcpy(zWideFilename, L"\\\\?\\", 8); - }else if( nChar>MAX_PATH - && winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) - && zFilename[2] != '?' ){ - memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); - memcpy(zWideFilename, L"\\\\?\\UNC", 14); - } - zConverted = zWideFilename; -#else - zConverted = winUtf8ToUnicode(zFilename); -#endif /* __CYGWIN__ */ - } -#if defined(SQLITE_WIN32_HAS_ANSI) && defined(_WIN32) - else{ - zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); - } -#endif - /* caller will handle out of memory */ - return zConverted; -} - -/* -** This function is used to open a handle on a *-shm file. -** -** If SQLITE_ENABLE_SETLK_TIMEOUT is defined at build time, then the file -** is opened with FILE_FLAG_OVERLAPPED specified. If not, it is not. -*/ -static int winHandleOpen( - const char *zUtf8, /* File to open */ - int *pbReadonly, /* IN/OUT: True for readonly handle */ - HANDLE *ph /* OUT: New HANDLE for file */ -){ - int rc = SQLITE_OK; - void *zConverted = 0; - int bReadonly = *pbReadonly; - HANDLE h = INVALID_HANDLE_VALUE; - -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - const DWORD flag_overlapped = FILE_FLAG_OVERLAPPED; -#else - const DWORD flag_overlapped = 0; -#endif - - /* Convert the filename to the system encoding. */ - zConverted = winConvertFromUtf8Filename(zUtf8); - if( zConverted==0 ){ - OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8)); - rc = SQLITE_IOERR_NOMEM_BKPT; - goto winopenfile_out; - } - - /* Ensure the file we are trying to open is not actually a directory. */ - if( winIsDir(zConverted) ){ - OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8)); - rc = SQLITE_CANTOPEN_ISDIR; - goto winopenfile_out; - } - - /* TODO: platforms. - ** TODO: retry-on-ioerr. - */ - if( osIsNT() ){ -#if SQLITE_OS_WINRT - CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; - memset(&extendedParameters, 0, sizeof(extendedParameters)); - extendedParameters.dwSize = sizeof(extendedParameters); - extendedParameters.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; - extendedParameters.dwFileFlags = flag_overlapped; - extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; - h = osCreateFile2((LPCWSTR)zConverted, - (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)),/* dwDesiredAccess */ - FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ - OPEN_ALWAYS, /* dwCreationDisposition */ - &extendedParameters - ); -#else - h = osCreateFileW((LPCWSTR)zConverted, /* lpFileName */ - (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)), /* dwDesiredAccess */ - FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ - NULL, /* lpSecurityAttributes */ - OPEN_ALWAYS, /* dwCreationDisposition */ - FILE_ATTRIBUTE_NORMAL|flag_overlapped, - NULL - ); -#endif - }else{ - /* Due to pre-processor directives earlier in this file, - ** SQLITE_WIN32_HAS_ANSI is always defined if osIsNT() is false. */ -#ifdef SQLITE_WIN32_HAS_ANSI - h = osCreateFileA((LPCSTR)zConverted, - (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)), /* dwDesiredAccess */ - FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ - NULL, /* lpSecurityAttributes */ - OPEN_ALWAYS, /* dwCreationDisposition */ - FILE_ATTRIBUTE_NORMAL|flag_overlapped, - NULL - ); -#endif - } - - if( h==INVALID_HANDLE_VALUE ){ - if( bReadonly==0 ){ - bReadonly = 1; - rc = winHandleOpen(zUtf8, &bReadonly, &h); - }else{ - rc = SQLITE_CANTOPEN_BKPT; - } - } - - winopenfile_out: - sqlite3_free(zConverted); - *pbReadonly = bReadonly; - *ph = h; - return rc; -} - - /* ** Open the shared-memory area associated with database file pDbFd. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. */ static int winOpenSharedMemory(winFile *pDbFd){ struct winShm *p; /* The connection to be opened */ @@ -51656,83 +50943,98 @@ static int winOpenSharedMemory(winFile *pDbFd){ assert( pDbFd->pShm==0 ); /* Not previously opened */ /* Allocate space for the new sqlite3_shm object. Also speculatively - ** allocate space for a new winShmNode and filename. */ + ** allocate space for a new winShmNode and filename. + */ p = sqlite3MallocZero( sizeof(*p) ); if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; nName = sqlite3Strlen30(pDbFd->zPath); - pNew = sqlite3MallocZero( sizeof(*pShmNode) + (i64)nName + 17 ); + pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); if( pNew==0 ){ sqlite3_free(p); return SQLITE_IOERR_NOMEM_BKPT; } pNew->zFilename = (char*)&pNew[1]; - pNew->hSharedShm = INVALID_HANDLE_VALUE; - pNew->isUnlocked = 1; sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); - /* Open a file-handle on the *-shm file for this connection. This file-handle - ** is only used for locking. The mapping of the *-shm file is created using - ** the shared file handle in winShmNode.hSharedShm. */ - p->bReadonly = sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0); - rc = winHandleOpen(pNew->zFilename, &p->bReadonly, &p->hShm); - /* Look to see if there is an existing winShmNode that can be used. - ** If no matching winShmNode currently exists, then create a new one. */ + ** If no matching winShmNode currently exists, create a new one. + */ winShmEnterMutex(); for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ /* TBD need to come up with better match here. Perhaps - ** use FILE_ID_BOTH_DIR_INFO Structure. */ + ** use FILE_ID_BOTH_DIR_INFO Structure. + */ if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; } - if( pShmNode==0 ){ - pShmNode = pNew; + if( pShmNode ){ + sqlite3_free(pNew); + }else{ + int inFlags = SQLITE_OPEN_WAL; + int outFlags = 0; + + pShmNode = pNew; + pNew = 0; + ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; + pShmNode->pNext = winShmNodeList; + winShmNodeList = pShmNode; - /* Allocate a mutex for this winShmNode object, if one is required. */ if( sqlite3GlobalConfig.bCoreMutex ){ pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( pShmNode->mutex==0 ) rc = SQLITE_IOERR_NOMEM_BKPT; - } - - /* Open a file-handle to use for mappings, and for the DMS lock. */ - if( rc==SQLITE_OK ){ - HANDLE h = INVALID_HANDLE_VALUE; - pShmNode->isReadonly = p->bReadonly; - rc = winHandleOpen(pNew->zFilename, &pShmNode->isReadonly, &h); - pShmNode->hSharedShm = h; - } - - /* If successful, link the new winShmNode into the global list. If an - ** error occurred, free the object. */ - if( rc==SQLITE_OK ){ - pShmNode->pNext = winShmNodeList; - winShmNodeList = pShmNode; - pNew = 0; - }else{ - sqlite3_mutex_free(pShmNode->mutex); - if( pShmNode->hSharedShm!=INVALID_HANDLE_VALUE ){ - osCloseHandle(pShmNode->hSharedShm); + if( pShmNode->mutex==0 ){ + rc = SQLITE_IOERR_NOMEM_BKPT; + goto shm_open_err; } } + + if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ + inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + }else{ + inFlags |= SQLITE_OPEN_READONLY; + } + rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, + (sqlite3_file*)&pShmNode->hFile, + inFlags, &outFlags); + if( rc!=SQLITE_OK ){ + rc = winLogError(rc, osGetLastError(), "winOpenShm", + pShmNode->zFilename); + goto shm_open_err; + } + if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1; + + rc = winLockSharedMemory(pShmNode); + if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; } - /* If no error has occurred, link the winShm object to the winShmNode and - ** the winShm to pDbFd. */ - if( rc==SQLITE_OK ){ - p->pShmNode = pShmNode; - pShmNode->nRef++; + /* Make the new connection a child of the winShmNode */ + p->pShmNode = pShmNode; #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) - p->id = pShmNode->nextShmId++; + p->id = pShmNode->nextShmId++; #endif - pDbFd->pShm = p; - }else if( p ){ - winHandleClose(p->hShm); - sqlite3_free(p); - } - - assert( rc!=SQLITE_OK || pShmNode->isUnlocked==0 || pShmNode->nRegion==0 ); + pShmNode->nRef++; + pDbFd->pShm = p; winShmLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the winShmEnterMutex() mutex and the pointer from the + ** new (struct winShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex + ** mutex. + */ + sqlite3_mutex_enter(pShmNode->mutex); + p->pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + sqlite3_mutex_leave(pShmNode->mutex); + return rc; + + /* Jump here on any error */ +shm_open_err: + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ + sqlite3_free(p); sqlite3_free(pNew); + winShmLeaveMutex(); return rc; } @@ -51747,19 +51049,27 @@ static int winShmUnmap( winFile *pDbFd; /* Database holding shared-memory */ winShm *p; /* The connection to be closed */ winShmNode *pShmNode; /* The underlying shared-memory file */ + winShm **pp; /* For looping over sibling connections */ pDbFd = (winFile*)fd; p = pDbFd->pShm; if( p==0 ) return SQLITE_OK; - if( p->hShm!=INVALID_HANDLE_VALUE ){ - osCloseHandle(p->hShm); - } - pShmNode = p->pShmNode; - winShmEnterMutex(); + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->mutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->mutex); /* If pShmNode->nRef has reached 0, then close the underlying - ** shared-memory file, too. */ + ** shared-memory file, too */ + winShmEnterMutex(); assert( pShmNode->nRef>0 ); pShmNode->nRef--; if( pShmNode->nRef==0 ){ @@ -51767,9 +51077,6 @@ static int winShmUnmap( } winShmLeaveMutex(); - /* Free the connection p */ - sqlite3_free(p); - pDbFd->pShm = 0; return SQLITE_OK; } @@ -51784,9 +51091,10 @@ static int winShmLock( ){ winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ winShm *p = pDbFd->pShm; /* The shared memory being locked */ + winShm *pX; /* For looping over all siblings */ winShmNode *pShmNode; int rc = SQLITE_OK; /* Result code */ - u16 mask = (u16)((1U<<(ofst+n)) - (1U<pShmNode; @@ -51800,81 +51108,85 @@ static int winShmLock( || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); - /* Check that, if this to be a blocking lock, no locks that occur later - ** in the following list than the lock being obtained are already held: - ** - ** 1. Recovery lock (ofst==2). - ** 2. Checkpointer lock (ofst==1). - ** 3. Write lock (ofst==0). - ** 4. Read locks (ofst>=3 && ofstexclMask|p->sharedMask); - assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( - (ofst!=2 || lockMask==0) - && (ofst!=1 || lockMask==0 || lockMask==2) - && (ofst!=0 || lockMask<3) - && (ofst<3 || lockMask<(1<1 || mask==(1<mutex); + if( flags & SQLITE_SHM_UNLOCK ){ + u16 allMask = 0; /* Mask of locks held by siblings */ - /* Check if there is any work to do. There are three cases: - ** - ** a) An unlock operation where there are locks to unlock, - ** b) An shared lock where the requested lock is not already held - ** c) An exclusive lock where the requested lock is not already held - ** - ** The SQLite core never requests an exclusive lock that it already holds. - ** This is assert()ed immediately below. */ - assert( flags!=(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK) - || 0==(p->exclMask & mask) - ); - if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask)) - || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask)) - || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)) - ){ + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( pX==p ) continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->sharedMask; + } - if( flags & SQLITE_SHM_UNLOCK ){ - /* Case (a) - unlock. */ - - assert( (p->exclMask & p->sharedMask)==0 ); - assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask ); - assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask ); - - rc = winHandleUnlock(p->hShm, ofst+WIN_SHM_BASE, n); - - /* If successful, also clear the bits in sharedMask/exclMask */ - if( rc==SQLITE_OK ){ - p->exclMask = (p->exclMask & ~mask); - p->sharedMask = (p->sharedMask & ~mask); - } + /* Unlock the system-level locks */ + if( (mask & allMask)==0 ){ + rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n); }else{ - int bExcl = ((flags & SQLITE_SHM_EXCLUSIVE) ? 1 : 0); - DWORD nMs = winFileBusyTimeout(pDbFd); - rc = winHandleLockTimeout(p->hShm, ofst+WIN_SHM_BASE, n, bExcl, nMs); + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } + }else if( flags & SQLITE_SHM_SHARED ){ + u16 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + allShared |= pX->sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if( rc==SQLITE_OK ){ + if( (allShared & mask)==0 ){ + rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + } + }else{ + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if( rc==SQLITE_OK ){ + rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n); if( rc==SQLITE_OK ){ - if( bExcl ){ - p->exclMask = (p->exclMask | mask); - }else{ - p->sharedMask = (p->sharedMask | mask); - } + assert( (p->sharedMask & mask)==0 ); + p->exclMask |= mask; } } } - - OSTRACE(( - "SHM-LOCK(%d,%d,%d) pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x," - " rc=%s\n", - ofst, n, flags, - osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, - sqlite3ErrName(rc)) - ); + sqlite3_mutex_leave(pShmNode->mutex); + OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", + osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, + sqlite3ErrName(rc))); return rc; } @@ -51936,15 +51248,13 @@ static int winShmMap( sqlite3_mutex_enter(pShmNode->mutex); if( pShmNode->isUnlocked ){ - /* Take the DMS lock. */ - assert( pShmNode->nRegion==0 ); - rc = winLockSharedMemory(pShmNode, winFileBusyTimeout(pDbFd)); + rc = winLockSharedMemory(pShmNode); if( rc!=SQLITE_OK ) goto shmpage_out; + pShmNode->isUnlocked = 0; } - assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + if( pShmNode->nRegion<=iRegion ){ - HANDLE hShared = pShmNode->hSharedShm; struct ShmRegion *apNew; /* New aRegion[] array */ int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ sqlite3_int64 sz; /* Current size of wal-index file */ @@ -51955,9 +51265,10 @@ static int winShmMap( ** Check to see if it has been allocated (i.e. if the wal-index file is ** large enough to contain the requested region). */ - rc = winHandleSize(hShared, &sz); + rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); if( rc!=SQLITE_OK ){ - rc = winLogError(rc, osGetLastError(), "winShmMap1", pDbFd->zPath); + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), + "winShmMap1", pDbFd->zPath); goto shmpage_out; } @@ -51966,17 +51277,19 @@ static int winShmMap( ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned. ** ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate - ** the requested memory region. */ + ** the requested memory region. + */ if( !isWrite ) goto shmpage_out; - rc = winHandleTruncate(hShared, nByte); + rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); if( rc!=SQLITE_OK ){ - rc = winLogError(rc, osGetLastError(), "winShmMap2", pDbFd->zPath); + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), + "winShmMap2", pDbFd->zPath); goto shmpage_out; } } /* Map the requested memory region into this processes address space. */ - apNew = (struct ShmRegion*)sqlite3_realloc64( + apNew = (struct ShmRegion *)sqlite3_realloc64( pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) ); if( !apNew ){ @@ -51995,13 +51308,18 @@ static int winShmMap( void *pMap = 0; /* Mapped memory region */ #if SQLITE_OS_WINRT - hMap = osCreateFileMappingFromApp(hShared, NULL, protect, nByte, NULL); + hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, + NULL, protect, nByte, NULL + ); #elif defined(SQLITE_WIN32_HAS_WIDE) - hMap = osCreateFileMappingW(hShared, NULL, protect, 0, nByte, NULL); + hMap = osCreateFileMappingW(pShmNode->hFile.h, + NULL, protect, 0, nByte, NULL + ); #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA - hMap = osCreateFileMappingA(hShared, NULL, protect, 0, nByte, NULL); + hMap = osCreateFileMappingA(pShmNode->hFile.h, + NULL, protect, 0, nByte, NULL + ); #endif - OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", osGetCurrentProcessId(), pShmNode->nRegion, nByte, hMap ? "ok" : "failed")); @@ -52044,9 +51362,7 @@ shmpage_out: }else{ *pp = 0; } - if( pShmNode->isReadonly && rc==SQLITE_OK ){ - rc = SQLITE_READONLY; - } + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; sqlite3_mutex_leave(pShmNode->mutex); return rc; } @@ -52366,6 +51682,47 @@ static winVfsAppData winNolockAppData = { ** sqlite3_vfs object. */ +#if defined(__CYGWIN__) +/* +** Convert a filename from whatever the underlying operating system +** supports for filenames into UTF-8. Space to hold the result is +** obtained from malloc and must be freed by the calling function. +*/ +static char *winConvertToUtf8Filename(const void *zFilename){ + char *zConverted = 0; + if( osIsNT() ){ + zConverted = winUnicodeToUtf8(zFilename); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); + } +#endif + /* caller will handle out of memory */ + return zConverted; +} +#endif + +/* +** Convert a UTF-8 filename into whatever form the underlying +** operating system wants filenames in. Space to hold the result +** is obtained from malloc and must be freed by the calling +** function. +*/ +static void *winConvertFromUtf8Filename(const char *zFilename){ + void *zConverted = 0; + if( osIsNT() ){ + zConverted = winUtf8ToUnicode(zFilename); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); + } +#endif + /* caller will handle out of memory */ + return zConverted; +} + /* ** This function returns non-zero if the specified UTF-8 string buffer ** ends with a directory separator character or one was successfully @@ -52378,14 +51735,7 @@ static int winMakeEndInDirSep(int nBuf, char *zBuf){ if( winIsDirSep(zBuf[nLen-1]) ){ return 1; }else if( nLen+1mxPathname; - nBuf = 2 + (i64)nMax; + nMax = pVfs->mxPathname; nBuf = nMax + 2; zBuf = sqlite3MallocZero( nBuf ); if( !zBuf ){ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); @@ -52463,7 +51812,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ } #if defined(__CYGWIN__) - else if( osGetenv!=NULL ){ + else{ static const char *azDirs[] = { 0, /* getenv("SQLITE_TMPDIR") */ 0, /* getenv("TMPDIR") */ @@ -52479,11 +51828,11 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ unsigned int i; const char *zDir = 0; - if( !azDirs[0] ) azDirs[0] = osGetenv("SQLITE_TMPDIR"); - if( !azDirs[1] ) azDirs[1] = osGetenv("TMPDIR"); - if( !azDirs[2] ) azDirs[2] = osGetenv("TMP"); - if( !azDirs[3] ) azDirs[3] = osGetenv("TEMP"); - if( !azDirs[4] ) azDirs[4] = osGetenv("USERPROFILE"); + if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); + if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); + if( !azDirs[2] ) azDirs[2] = getenv("TMP"); + if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); + if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); for(i=0; inOut ){ - /* SQLite assumes that xFullPathname() nul-terminates the output buffer - ** even if it returns an error. */ - zOut[iOff] = '\0'; - return SQLITE_CANTOPEN_BKPT; - } - sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); - return SQLITE_OK; -} -#endif /* __CYGWIN__ */ /* ** Turn a relative pathname into a full pathname. Write the full @@ -53315,8 +52615,8 @@ static int winFullPathnameNoMutex( int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT - int nByte; +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) + DWORD nByte; void *zConverted; char *zOut; #endif @@ -53329,82 +52629,64 @@ static int winFullPathnameNoMutex( zRelative++; } +#if defined(__CYGWIN__) SimulateIOError( return SQLITE_ERROR ); - -#ifdef __CYGWIN__ - if( osGetcwd ){ - zFull[nFull-1] = '\0'; - if( !winIsDriveLetterAndColon(zRelative) || !winIsDirSep(zRelative[2]) ){ - int rc = SQLITE_OK; - int nLink = 1; /* Number of symbolic links followed so far */ - const char *zIn = zRelative; /* Input path for each iteration of loop */ - char *zDel = 0; - struct stat buf; - - UNUSED_PARAMETER(pVfs); - - do { - /* Call lstat() on path zIn. Set bLink to true if the path is a symbolic - ** link, or false otherwise. */ - int bLink = 0; - if( osLstat && osReadlink ) { - if( osLstat(zIn, &buf)!=0 ){ - int myErrno = osErrno; - if( myErrno!=ENOENT ){ - rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)myErrno, "lstat", zIn); - } - }else{ - bLink = ((buf.st_mode & 0170000) == 0120000); - } - - if( bLink ){ - if( zDel==0 ){ - zDel = sqlite3MallocZero(nFull); - if( zDel==0 ) rc = SQLITE_NOMEM; - }else if( ++nLink>SQLITE_MAX_SYMLINKS ){ - rc = SQLITE_CANTOPEN_BKPT; - } - - if( rc==SQLITE_OK ){ - nByte = osReadlink(zIn, zDel, nFull-1); - if( nByte ==(DWORD)-1 ){ - rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)osErrno, "readlink", zIn); - }else{ - if( zDel[0]!='/' ){ - int n; - for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); - if( nByte+n+1>nFull ){ - rc = SQLITE_CANTOPEN_BKPT; - }else{ - memmove(&zDel[n], zDel, nByte+1); - memcpy(zDel, zIn, n); - nByte += n; - } - } - zDel[nByte] = '\0'; - } - } - - zIn = zDel; - } - } - - assert( rc!=SQLITE_OK || zIn!=zFull || zIn[0]=='/' ); - if( rc==SQLITE_OK && zIn!=zFull ){ - rc = mkFullPathname(zIn, zFull, nFull); - } - if( bLink==0 ) break; - zIn = zFull; - }while( rc==SQLITE_OK ); - - sqlite3_free(zDel); - winSimplifyName(zFull); - return rc; + UNUSED_PARAMETER(nFull); + assert( nFull>=pVfs->mxPathname ); + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + /* + ** NOTE: We are dealing with a relative path name and the data + ** directory has been set. Therefore, use it as the basis + ** for converting the relative path name to an absolute + ** one by prepending the data directory and a slash. + */ + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); + if( !zOut ){ + return SQLITE_IOERR_NOMEM_BKPT; + } + if( cygwin_conv_path( + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | + CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ + sqlite3_free(zOut); + return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, + "winFullPathname1", zRelative); + }else{ + char *zUtf8 = winConvertToUtf8Filename(zOut); + if( !zUtf8 ){ + sqlite3_free(zOut); + return SQLITE_IOERR_NOMEM_BKPT; + } + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zOut); + } + }else{ + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); + if( !zOut ){ + return SQLITE_IOERR_NOMEM_BKPT; + } + if( cygwin_conv_path( + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), + zRelative, zOut, pVfs->mxPathname+1)<0 ){ + sqlite3_free(zOut); + return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, + "winFullPathname2", zRelative); + }else{ + char *zUtf8 = winConvertToUtf8Filename(zOut); + if( !zUtf8 ){ + sqlite3_free(zOut); + return SQLITE_IOERR_NOMEM_BKPT; + } + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zOut); } } -#endif /* __CYGWIN__ */ + return SQLITE_OK; +#endif -#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32) +#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) SimulateIOError( return SQLITE_ERROR ); /* WinCE has no concept of a relative pathname, or so I am told. */ /* WinRT has no way to convert a relative path to an absolute one. */ @@ -53423,8 +52705,7 @@ static int winFullPathnameNoMutex( return SQLITE_OK; #endif -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT -#if defined(_WIN32) +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the @@ -53442,7 +52723,6 @@ static int winFullPathnameNoMutex( sqlite3_data_directory, winGetDirSep(), zRelative); return SQLITE_OK; } -#endif zConverted = winConvertFromUtf8Filename(zRelative); if( zConverted==0 ){ return SQLITE_IOERR_NOMEM_BKPT; @@ -53481,12 +52761,13 @@ static int winFullPathnameNoMutex( return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), "winFullPathname3", zRelative); } - zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) + 3*sizeof(zTemp[0]) ); + nByte += 3; + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ sqlite3_free(zConverted); return SQLITE_IOERR_NOMEM_BKPT; } - nByte = osGetFullPathNameA((char*)zConverted, nByte+3, zTemp, 0); + nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); if( nByte==0 ){ sqlite3_free(zConverted); sqlite3_free(zTemp); @@ -53499,26 +52780,7 @@ static int winFullPathnameNoMutex( } #endif if( zOut ){ -#ifdef __CYGWIN__ - if( memcmp(zOut, "\\\\?\\", 4) ){ - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); - }else if( memcmp(zOut+4, "UNC\\", 4) ){ - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut+4); - }else{ - char *p = zOut+6; - *p = '\\'; - if( osGetcwd ){ - /* On Cygwin, UNC paths use forward slashes */ - while( *p ){ - if( *p=='\\' ) *p = '/'; - ++p; - } - } - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut+6); - } -#else sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); -#endif /* __CYGWIN__ */ sqlite3_free(zOut); return SQLITE_OK; }else{ @@ -53548,8 +52810,25 @@ static int winFullPathname( */ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ HANDLE h; +#if defined(__CYGWIN__) + int nFull = pVfs->mxPathname+1; + char *zFull = sqlite3MallocZero( nFull ); + void *zConverted = 0; + if( zFull==0 ){ + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); + return 0; + } + if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ + sqlite3_free(zFull); + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); + return 0; + } + zConverted = winConvertFromUtf8Filename(zFull); + sqlite3_free(zFull); +#else void *zConverted = winConvertFromUtf8Filename(zFilename); UNUSED_PARAMETER(pVfs); +#endif if( zConverted==0 ){ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); return 0; @@ -53898,7 +53177,7 @@ SQLITE_API int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==89 ); + assert( ArraySize(aSyscall)==80 ); /* get memory map allocation granularity */ memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); @@ -54517,13 +53796,13 @@ static int memdbOpen( } if( p==0 ){ MemStore **apNew; - p = sqlite3Malloc( sizeof(*p) + (i64)szName + 3 ); + p = sqlite3Malloc( sizeof(*p) + szName + 3 ); if( p==0 ){ sqlite3_mutex_leave(pVfsMutex); return SQLITE_NOMEM; } apNew = sqlite3Realloc(memdb_g.apMemStore, - sizeof(apNew[0])*(1+(i64)memdb_g.nMemStore) ); + sizeof(apNew[0])*(memdb_g.nMemStore+1) ); if( apNew==0 ){ sqlite3_free(p); sqlite3_mutex_leave(pVfsMutex); @@ -54956,7 +54235,7 @@ SQLITE_PRIVATE int sqlite3MemdbInit(void){ ** no fewer collisions than the no-op *1. */ #define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT) -#define BITVEC_NPTR ((u32)(BITVEC_USIZE/sizeof(Bitvec *))) +#define BITVEC_NPTR (BITVEC_USIZE/sizeof(Bitvec *)) /* @@ -55105,9 +54384,7 @@ bitvec_set_rehash: }else{ memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); memset(p->u.apSub, 0, sizeof(p->u.apSub)); - p->iDivisor = p->iSize/BITVEC_NPTR; - if( (p->iSize%BITVEC_NPTR)!=0 ) p->iDivisor++; - if( p->iDivisoriDivisor = BITVEC_NBIT; + p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; rc = sqlite3BitvecSet(p, i); for(j=0; jiSize<=BITVEC_NBIT ){ - p->u.aBitmap[i/BITVEC_SZELEM] &= ~(BITVEC_TELEM)(1<<(i&(BITVEC_SZELEM-1))); + p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1))); }else{ unsigned int j; u32 *aiValues = pBuf; @@ -55192,7 +54469,7 @@ SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ ** individual bits within V. */ #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) -#define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) +#define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7)) #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 /* @@ -55235,7 +54512,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ /* Allocate the Bitvec to be tested and a linear array of ** bits to act as the reference */ pBitvec = sqlite3BitvecCreate( sz ); - pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); + pV = sqlite3MallocZero( (sz+7)/8 + 1 ); pTmpSpace = sqlite3_malloc64(BITVEC_SZ); if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; @@ -56476,6 +55753,10 @@ static SQLITE_WSD struct PCacheGlobal { sqlite3_mutex *mutex; /* Mutex for accessing the following: */ PgFreeslot *pFree; /* Free page blocks */ int nFreeSlot; /* Number of unused pcache slots */ + /* The following value requires a mutex to change. We skip the mutex on + ** reading because (1) most platforms read a 32-bit integer atomically and + ** (2) even if an incorrect value is read, no great harm is done since this + ** is really just an optimization. */ int bUnderPressure; /* True if low on PAGECACHE memory */ } pcache1_g; @@ -56523,7 +55804,7 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ pcache1.nReserve = n>90 ? 10 : (n/10 + 1); pcache1.pStart = pBuf; pcache1.pFree = 0; - AtomicStore(&pcache1.bUnderPressure,0); + pcache1.bUnderPressure = 0; while( n-- ){ p = (PgFreeslot*)pBuf; p->pNext = pcache1.pFree; @@ -56591,7 +55872,7 @@ static void *pcache1Alloc(int nByte){ if( p ){ pcache1.pFree = pcache1.pFree->pNext; pcache1.nFreeSlot--; - AtomicStore(&pcache1.bUnderPressure,pcache1.nFreeSlot=0 ); sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); @@ -56630,7 +55911,7 @@ static void pcache1Free(void *p){ pSlot->pNext = pcache1.pFree; pcache1.pFree = pSlot; pcache1.nFreeSlot++; - AtomicStore(&pcache1.bUnderPressure,pcache1.nFreeSlotszPage+pCache->szExtra)<=pcache1.szSlot ){ - return AtomicLoad(&pcache1.bUnderPressure); + return pcache1.bUnderPressure; }else{ return sqlite3HeapNearlyFull(); } @@ -56778,12 +56059,12 @@ static int pcache1UnderMemoryPressure(PCache1 *pCache){ */ static void pcache1ResizeHash(PCache1 *p){ PgHdr1 **apNew; - u64 nNew; - u32 i; + unsigned int nNew; + unsigned int i; assert( sqlite3_mutex_held(p->pGroup->mutex) ); - nNew = 2*(u64)p->nHash; + nNew = p->nHash*2; if( nNew<256 ){ nNew = 256; } @@ -57006,7 +56287,7 @@ static void pcache1Destroy(sqlite3_pcache *p); static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ PCache1 *pCache; /* The newly created page cache */ PGroup *pGroup; /* The group the new page cache will belong to */ - i64 sz; /* Bytes of memory required to allocate the new cache */ + int sz; /* Bytes of memory required to allocate the new cache */ assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); assert( szExtra < 300 ); @@ -58918,9 +58199,6 @@ struct Pager { Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ char *zWal; /* File name for write-ahead log */ #endif -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - sqlite3 *dbWal; -#endif }; /* @@ -59523,7 +58801,7 @@ static void checkPage(PgHdr *pPg){ ** If an error occurs while reading from the journal file, an SQLite ** error code is returned. */ -static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u64 nSuper){ +static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u32 nSuper){ int rc; /* Return code */ u32 len; /* Length in bytes of super-journal name */ i64 szJ; /* Total size in bytes of journal file pJrnl */ @@ -60078,15 +59356,6 @@ static void pager_unlock(Pager *pPager){ if( pagerUseWal(pPager) ){ assert( !isOpen(pPager->jfd) ); - if( pPager->eState==PAGER_ERROR ){ - /* If an IO error occurs in wal.c while attempting to wrap the wal file, - ** then the Wal object may be holding a write-lock but no read-lock. - ** This call ensures that the write-lock is dropped as well. We cannot - ** have sqlite3WalEndReadTransaction() drop the write-lock, as it once - ** did, because this would break "BEGIN EXCLUSIVE" handling for - ** SQLITE_ENABLE_SETLK_TIMEOUT builds. */ - sqlite3WalEndWriteTransaction(pPager->pWal); - } sqlite3WalEndReadTransaction(pPager->pWal); pPager->eState = PAGER_OPEN; }else if( !pPager->exclusiveMode ){ @@ -60834,12 +60103,12 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ char *zJournal; /* Pointer to one journal within MJ file */ char *zSuperPtr; /* Space to hold super-journal filename */ char *zFree = 0; /* Free this buffer */ - i64 nSuperPtr; /* Amount of space allocated to zSuperPtr[] */ + int nSuperPtr; /* Amount of space allocated to zSuperPtr[] */ /* Allocate space for both the pJournal and pSuper file descriptors. ** If successful, open the super-journal file for reading. */ - pSuper = (sqlite3_file *)sqlite3MallocZero(2 * (i64)pVfs->szOsFile); + pSuper = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); if( !pSuper ){ rc = SQLITE_NOMEM_BKPT; pJournal = 0; @@ -60857,14 +60126,11 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ */ rc = sqlite3OsFileSize(pSuper, &nSuperJournal); if( rc!=SQLITE_OK ) goto delsuper_out; - nSuperPtr = 1 + (i64)pVfs->mxPathname; - assert( nSuperJournal>=0 && nSuperPtr>0 ); + nSuperPtr = pVfs->mxPathname+1; zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2); if( !zFree ){ rc = SQLITE_NOMEM_BKPT; goto delsuper_out; - }else{ - assert( nSuperJournal<=0x7fffffff ); } zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0; zSuperJournal = &zFree[4]; @@ -61125,7 +60391,7 @@ static int pager_playback(Pager *pPager, int isHot){ ** for pageSize. */ zSuper = pPager->pTmpSpace; - rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname); + rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1); if( rc==SQLITE_OK && zSuper[0] ){ rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res); } @@ -61264,7 +60530,7 @@ end_playback: ** which case it requires 4 0x00 bytes in memory immediately before ** the filename. */ zSuper = &pPager->pTmpSpace[4]; - rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname); + rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1); testcase( rc!=SQLITE_OK ); } if( rc==SQLITE_OK @@ -63054,7 +62320,6 @@ SQLITE_PRIVATE int sqlite3PagerOpen( const char *zUri = 0; /* URI args to copy */ int nUriByte = 1; /* Number of bytes of URI args at *zUri */ - /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). */ journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); @@ -63080,8 +62345,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen( */ if( zFilename && zFilename[0] ){ const char *z; - nPathname = pVfs->mxPathname + 1; - zPathname = sqlite3DbMallocRaw(0, 2*(i64)nPathname); + nPathname = pVfs->mxPathname+1; + zPathname = sqlite3DbMallocRaw(0, nPathname*2); if( zPathname==0 ){ return SQLITE_NOMEM_BKPT; } @@ -63168,14 +62433,14 @@ SQLITE_PRIVATE int sqlite3PagerOpen( ROUND8(sizeof(*pPager)) + /* Pager structure */ ROUND8(pcacheSize) + /* PCache object */ ROUND8(pVfs->szOsFile) + /* The main db file */ - (u64)journalFileSize * 2 + /* The two journal files */ + journalFileSize * 2 + /* The two journal files */ SQLITE_PTRSIZE + /* Space to hold a pointer */ 4 + /* Database prefix */ - (u64)nPathname + 1 + /* database filename */ - (u64)nUriByte + /* query parameters */ - (u64)nPathname + 8 + 1 + /* Journal filename */ + nPathname + 1 + /* database filename */ + nUriByte + /* query parameters */ + nPathname + 8 + 1 + /* Journal filename */ #ifndef SQLITE_OMIT_WAL - (u64)nPathname + 4 + 1 + /* WAL filename */ + nPathname + 4 + 1 + /* WAL filename */ #endif 3 /* Terminator */ ); @@ -65946,11 +65211,6 @@ static int pagerOpenWal(Pager *pPager){ pPager->fd, pPager->zWal, pPager->exclusiveMode, pPager->journalSizeLimit, &pPager->pWal ); -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - if( rc==SQLITE_OK ){ - sqlite3WalDb(pPager->pWal, pPager->dbWal); - } -#endif } pagerFixMaplimit(pPager); @@ -66070,7 +65330,6 @@ SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){ ** blocking locks are required. */ SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ - pPager->dbWal = db; if( pagerUseWal(pPager) ){ sqlite3WalDb(pPager->pWal, db); } @@ -66705,11 +65964,6 @@ struct WalCkptInfo { /* ** An open write-ahead log file is represented by an instance of the ** following object. -** -** writeLock: -** This is usually set to 1 whenever the WRITER lock is held. However, -** if it is set to 2, then the WRITER lock is held but must be released -** by walHandleException() if a SEH exception is thrown. */ struct Wal { sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ @@ -66800,13 +66054,9 @@ struct WalIterator { u32 *aPgno; /* Array of page numbers. */ int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ int iZero; /* Frame number associated with aPgno[0] */ - } aSegment[FLEXARRAY]; /* One for every 32KB page in the wal-index */ + } aSegment[1]; /* One for every 32KB page in the wal-index */ }; -/* Size (in bytes) of a WalIterator object suitable for N or fewer segments */ -#define SZ_WALITERATOR(N) \ - (offsetof(WalIterator,aSegment)*(N)*sizeof(struct WalSegment)) - /* ** Define the parameters of the hash tables in the wal-index file. There ** is a hash-table following every HASHTABLE_NPAGE page numbers in the @@ -66965,7 +66215,7 @@ static SQLITE_NOINLINE int walIndexPageRealloc( /* Enlarge the pWal->apWiData[] array if required */ if( pWal->nWiData<=iPage ){ - sqlite3_int64 nByte = sizeof(u32*)*(1+(i64)iPage); + sqlite3_int64 nByte = sizeof(u32*)*(iPage+1); volatile u32 **apNew; apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte); if( !apNew ){ @@ -67074,8 +66324,10 @@ static void walChecksumBytes( s1 = s2 = 0; } - /* nByte is a multiple of 8 between 8 and 65536 */ - assert( nByte>=8 && (nByte&7)==0 && nByte<=65536 ); + assert( nByte>=8 ); + assert( (nByte&0x00000007)==0 ); + assert( nByte<=65536 ); + assert( nByte%4==0 ); if( !nativeCksum ){ do { @@ -68165,7 +67417,8 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ /* Allocate space for the WalIterator object. */ nSegment = walFramePage(iLast) + 1; - nByte = SZ_WALITERATOR(nSegment) + nByte = sizeof(WalIterator) + + (nSegment-1)*sizeof(struct WalSegment) + iLast*sizeof(ht_slot); p = (WalIterator *)sqlite3_malloc64(nByte + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) @@ -68236,7 +67489,7 @@ static int walEnableBlockingMs(Wal *pWal, int nMs){ static int walEnableBlocking(Wal *pWal){ int res = 0; if( pWal->db ){ - int tmout = pWal->db->setlkTimeout; + int tmout = pWal->db->busyTimeout; if( tmout ){ res = walEnableBlockingMs(pWal, tmout); } @@ -68622,9 +67875,7 @@ static int walHandleException(Wal *pWal){ static const int S = 1; static const int E = (1<writeLock==2 ) pWal->writeLock = 0; - mUnlock = pWal->lockMask & ~( + u32 mUnlock = pWal->lockMask & ~( (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) @@ -68896,12 +68147,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ if( bWriteLock || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ - /* If the write-lock was just obtained, set writeLock to 2 instead of - ** the usual 1. This causes walIndexPage() to behave as if the - ** write-lock were held (so that it allocates new pages as required), - ** and walHandleException() to unlock the write-lock if a SEH exception - ** is thrown. */ - if( !bWriteLock ) pWal->writeLock = 2; + pWal->writeLock = 1; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); if( badHdr ){ @@ -69265,6 +68511,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ rc = walIndexReadHdr(pWal, pChanged); } #ifdef SQLITE_ENABLE_SETLK_TIMEOUT + walDisableBlocking(pWal); if( rc==SQLITE_BUSY_TIMEOUT ){ rc = SQLITE_BUSY; *pCnt |= WAL_RETRY_BLOCKED_MASK; @@ -69279,7 +68526,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ ** WAL_RETRY this routine will be called again and will probably be ** right on the second iteration. */ - (void)walEnableBlocking(pWal); if( pWal->apWiData[0]==0 ){ /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. ** We assume this is a transient condition, so return WAL_RETRY. The @@ -69296,7 +68542,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ rc = SQLITE_BUSY_RECOVERY; } } - walDisableBlocking(pWal); if( rc!=SQLITE_OK ){ return rc; } @@ -69687,11 +68932,8 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ ** read-lock. */ SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ -#ifndef SQLITE_ENABLE_SETLK_TIMEOUT - assert( pWal->writeLock==0 || pWal->readLock<0 ); -#endif + sqlite3WalEndWriteTransaction(pWal); if( pWal->readLock>=0 ){ - sqlite3WalEndWriteTransaction(pWal); walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); pWal->readLock = -1; } @@ -69884,7 +69126,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ ** read-transaction was even opened, making this call a no-op. ** Return early. */ if( pWal->writeLock ){ - assert( !memcmp(&pWal->hdr,(void*)pWal->apWiData[0],sizeof(WalIndexHdr)) ); + assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) ); return SQLITE_OK; } #endif @@ -69984,7 +69226,6 @@ SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *p if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); } SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) - pWal->iReCksum = 0; } return rc; } @@ -70032,9 +69273,6 @@ SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ walCleanupHash(pWal); } SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) - if( pWal->iReCksum>pWal->hdr.mxFrame ){ - pWal->iReCksum = 0; - } } return rc; @@ -71345,12 +70583,6 @@ struct CellInfo { */ #define BTCURSOR_MAX_DEPTH 20 -/* -** Maximum amount of storage local to a database page, regardless of -** page size. -*/ -#define BT_MAX_LOCAL 65501 /* 65536 - 35 */ - /* ** A cursor is a pointer to a particular entry within a particular ** b-tree within a database file. @@ -71759,7 +70991,7 @@ SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){ */ static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){ int i; - u8 skipOk = 1; + int skipOk = 1; Btree *p; assert( sqlite3_mutex_held(db->mutex) ); for(i=0; inDb; i++){ @@ -72615,7 +71847,7 @@ static int saveCursorKey(BtCursor *pCur){ ** below. */ void *pKey; pCur->nKey = sqlite3BtreePayloadSize(pCur); - pKey = sqlite3Malloc( ((i64)pCur->nKey) + 9 + 8 ); + pKey = sqlite3Malloc( pCur->nKey + 9 + 8 ); if( pKey ){ rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey); if( rc==SQLITE_OK ){ @@ -72905,7 +72137,7 @@ SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ */ SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 ); - pCur->hints = (u8)x; + pCur->hints = x; } @@ -73099,15 +72331,14 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( static int btreePayloadToLocal(MemPage *pPage, i64 nPayload){ int maxLocal; /* Maximum amount of payload held locally */ maxLocal = pPage->maxLocal; - assert( nPayload>=0 ); if( nPayload<=maxLocal ){ - return (int)nPayload; + return nPayload; }else{ int minLocal; /* Minimum amount of payload held locally */ int surplus; /* Overflow payload available for local storage */ minLocal = pPage->minLocal; - surplus = (int)(minLocal +(nPayload - minLocal)%(pPage->pBt->usableSize-4)); - return (surplus <= maxLocal) ? surplus : minLocal; + surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize-4); + return ( surplus <= maxLocal ) ? surplus : minLocal; } } @@ -73217,13 +72448,11 @@ static void btreeParseCellPtr( pInfo->pPayload = pIter; testcase( nPayload==pPage->maxLocal ); testcase( nPayload==(u32)pPage->maxLocal+1 ); - assert( nPayload>=0 ); - assert( pPage->maxLocal <= BT_MAX_LOCAL ); if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. */ - pInfo->nSize = (u16)nPayload + (u16)(pIter - pCell); + pInfo->nSize = nPayload + (u16)(pIter - pCell); if( pInfo->nSize<4 ) pInfo->nSize = 4; pInfo->nLocal = (u16)nPayload; }else{ @@ -73256,13 +72485,11 @@ static void btreeParseCellPtrIndex( pInfo->pPayload = pIter; testcase( nPayload==pPage->maxLocal ); testcase( nPayload==(u32)pPage->maxLocal+1 ); - assert( nPayload>=0 ); - assert( pPage->maxLocal <= BT_MAX_LOCAL ); if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. */ - pInfo->nSize = (u16)nPayload + (u16)(pIter - pCell); + pInfo->nSize = nPayload + (u16)(pIter - pCell); if( pInfo->nSize<4 ) pInfo->nSize = 4; pInfo->nLocal = (u16)nPayload; }else{ @@ -73801,14 +73028,14 @@ static SQLITE_INLINE int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ ** at the end of the page. So do additional corruption checks inside this ** routine and return SQLITE_CORRUPT if any problems are found. */ -static int freeSpace(MemPage *pPage, int iStart, int iSize){ - int iPtr; /* Address of ptr to next freeblock */ - int iFreeBlk; /* Address of the next freeblock */ +static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ + u16 iPtr; /* Address of ptr to next freeblock */ + u16 iFreeBlk; /* Address of the next freeblock */ u8 hdr; /* Page header size. 0 or 100 */ - int nFrag = 0; /* Reduction in fragmentation */ - int iOrigSize = iSize; /* Original value of iSize */ - int x; /* Offset to cell content area */ - int iEnd = iStart + iSize; /* First byte past the iStart buffer */ + u8 nFrag = 0; /* Reduction in fragmentation */ + u16 iOrigSize = iSize; /* Original value of iSize */ + u16 x; /* Offset to cell content area */ + u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ unsigned char *data = pPage->aData; /* Page content */ u8 *pTmp; /* Temporary ptr into data[] */ @@ -73835,7 +73062,7 @@ static int freeSpace(MemPage *pPage, int iStart, int iSize){ } iPtr = iFreeBlk; } - if( iFreeBlk>(int)pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */ + if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */ return SQLITE_CORRUPT_PAGE(pPage); } assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB ); @@ -73850,7 +73077,7 @@ static int freeSpace(MemPage *pPage, int iStart, int iSize){ nFrag = iFreeBlk - iEnd; if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage); iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); - if( iEnd > (int)pPage->pBt->usableSize ){ + if( iEnd > pPage->pBt->usableSize ){ return SQLITE_CORRUPT_PAGE(pPage); } iSize = iEnd - iStart; @@ -73871,7 +73098,7 @@ static int freeSpace(MemPage *pPage, int iStart, int iSize){ } } if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage); - data[hdr+7] -= (u8)nFrag; + data[hdr+7] -= nFrag; } pTmp = &data[hdr+5]; x = get2byte(pTmp); @@ -73892,8 +73119,7 @@ static int freeSpace(MemPage *pPage, int iStart, int iSize){ /* Insert the new freeblock into the freelist */ put2byte(&data[iPtr], iStart); put2byte(&data[iStart], iFreeBlk); - assert( iSize>=0 && iSize<=0xffff ); - put2byte(&data[iStart+2], (u16)iSize); + put2byte(&data[iStart+2], iSize); } pPage->nFree += iOrigSize; return SQLITE_OK; @@ -74119,7 +73345,7 @@ static int btreeInitPage(MemPage *pPage){ assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nOverflow = 0; - pPage->cellOffset = (u16)(pPage->hdrOffset + 8 + pPage->childPtrSize); + pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize; pPage->aCellIdx = data + pPage->childPtrSize + 8; pPage->aDataEnd = pPage->aData + pBt->pageSize; pPage->aDataOfst = pPage->aData + pPage->childPtrSize; @@ -74153,8 +73379,8 @@ static int btreeInitPage(MemPage *pPage){ static void zeroPage(MemPage *pPage, int flags){ unsigned char *data = pPage->aData; BtShared *pBt = pPage->pBt; - int hdr = pPage->hdrOffset; - int first; + u8 hdr = pPage->hdrOffset; + u16 first; assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB ); assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); @@ -74171,7 +73397,7 @@ static void zeroPage(MemPage *pPage, int flags){ put2byte(&data[hdr+5], pBt->usableSize); pPage->nFree = (u16)(pBt->usableSize - first); decodeFlags(pPage, flags); - pPage->cellOffset = (u16)first; + pPage->cellOffset = first; pPage->aDataEnd = &data[pBt->pageSize]; pPage->aCellIdx = &data[first]; pPage->aDataOfst = &data[pPage->childPtrSize]; @@ -74957,7 +74183,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, BtShared *pBt = p->pBt; assert( nReserve>=0 && nReserve<=255 ); sqlite3BtreeEnter(p); - pBt->nReserveWanted = (u8)nReserve; + pBt->nReserveWanted = nReserve; x = pBt->pageSize - pBt->usableSize; if( nReservebtsFlags & BTS_PAGESIZE_FIXED ){ @@ -75063,7 +74289,7 @@ SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) ); if( newFlag>=0 ){ p->pBt->btsFlags &= ~BTS_FAST_SECURE; - p->pBt->btsFlags |= (u16)(BTS_SECURE_DELETE*newFlag); + p->pBt->btsFlags |= BTS_SECURE_DELETE*newFlag; } b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE; sqlite3BtreeLeave(p); @@ -75583,13 +74809,6 @@ static SQLITE_NOINLINE int btreeBeginTrans( (void)sqlite3PagerWalWriteLock(pPager, 0); unlockBtreeIfUnused(pBt); } -#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) - if( rc==SQLITE_BUSY_TIMEOUT ){ - /* If a blocking lock timed out, break out of the loop here so that - ** the busy-handler is not invoked. */ - break; - } -#endif }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && btreeInvokeBusyHandler(pBt) ); sqlite3PagerWalDb(pPager, 0); @@ -77999,7 +77218,7 @@ bypass_moveto_root: rc = SQLITE_CORRUPT_PAGE(pPage); goto moveto_index_finish; } - pCellKey = sqlite3Malloc( (u64)nCell+(u64)nOverrun ); + pCellKey = sqlite3Malloc( nCell+nOverrun ); if( pCellKey==0 ){ rc = SQLITE_NOMEM_BKPT; goto moveto_index_finish; @@ -79518,8 +78737,7 @@ static int rebuildPage( } /* The pPg->nFree field is now set incorrectly. The caller will fix it. */ - assert( nCell < 10922 ); - pPg->nCell = (u16)nCell; + pPg->nCell = nCell; pPg->nOverflow = 0; put2byte(&aData[hdr+1], 0); @@ -79766,13 +78984,9 @@ static int editPage( if( pageInsertArray( pPg, pBegin, &pData, pCellptr, iNew+nCell, nNew-nCell, pCArray - ) - ){ - goto editpage_fail; - } + ) ) goto editpage_fail; - assert( nNew < 10922 ); - pPg->nCell = (u16)nNew; + pPg->nCell = nNew; pPg->nOverflow = 0; put2byte(&aData[hdr+3], pPg->nCell); @@ -80081,7 +79295,7 @@ static int balance_nonroot( int pageFlags; /* Value of pPage->aData[0] */ int iSpace1 = 0; /* First unused byte of aSpace1[] */ int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ - u64 szScratch; /* Size of scratch memory requested */ + int szScratch; /* Size of scratch memory requested */ MemPage *apOld[NB]; /* pPage and up to two siblings */ MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ u8 *pRight; /* Location in parent of right-sibling pointer */ @@ -81366,7 +80580,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( if( pCur->info.nKey==pX->nKey ){ BtreePayload x2; x2.pData = pX->pKey; - x2.nData = (int)pX->nKey; assert( pX->nKey<=0x7fffffff ); + x2.nData = pX->nKey; x2.nZero = 0; return btreeOverwriteCell(pCur, &x2); } @@ -81547,7 +80761,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 getCellInfo(pSrc); if( pSrc->info.nPayload<0x80 ){ - *(aOut++) = (u8)pSrc->info.nPayload; + *(aOut++) = pSrc->info.nPayload; }else{ aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload); } @@ -81560,7 +80774,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 nRem = pSrc->info.nPayload; if( nIn==nRem && nInpPage->maxLocal ){ memcpy(aOut, aIn, nIn); - pBt->nPreformatSize = nIn + (int)(aOut - pBt->pTmpSpace); + pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); return SQLITE_OK; }else{ int rc = SQLITE_OK; @@ -81572,7 +80786,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 u32 nOut; /* Size of output buffer aOut[] */ nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); - pBt->nPreformatSize = (int)nOut + (int)(aOut - pBt->pTmpSpace); + pBt->nPreformatSize = nOut + (aOut - pBt->pTmpSpace); if( nOutinfo.nPayload ){ pPgnoOut = &aOut[nOut]; pBt->nPreformatSize += 4; @@ -83193,7 +82407,6 @@ SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){ */ SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ BtShared *pBt = p->pBt; - assert( nBytes==0 || nBytes==sizeof(Schema) ); sqlite3BtreeEnter(p); if( !pBt->pSchema && nBytes ){ pBt->pSchema = sqlite3DbMallocZero(0, nBytes); @@ -84371,7 +83584,7 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ ** corresponding string value, then it is important that the string be ** derived from the numeric value, not the other way around, to ensure ** that the index and table are consistent. See ticket -** https://sqlite.org/src/info/343634942dd54ab (2018-01-31) for +** https://www.sqlite.org/src/info/343634942dd54ab (2018-01-31) for ** an example. ** ** This routine looks at pMem to verify that if it has both a numeric @@ -84557,7 +83770,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ return; } if( pMem->enc!=SQLITE_UTF8 ) return; - assert( pMem->z!=0 ); + if( NEVER(pMem->z==0) ) return; if( pMem->flags & MEM_Dyn ){ if( pMem->xDel==sqlite3_free && sqlite3_msize(pMem->z) >= (u64)(pMem->n+1) @@ -85670,7 +84883,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ if( pRec==0 ){ Index *pIdx = p->pIdx; /* Index being probed */ - i64 nByte; /* Bytes of space to allocate */ + int nByte; /* Bytes of space to allocate */ int i; /* Counter variable */ int nCol = pIdx->nColumn; /* Number of index columns including rowid */ @@ -85736,7 +84949,7 @@ static int valueFromFunction( ){ sqlite3_context ctx; /* Context object for function invocation */ sqlite3_value **apVal = 0; /* Function arguments */ - int nVal = 0; /* Number of function arguments */ + int nVal = 0; /* Size of apVal[] array */ FuncDef *pFunc = 0; /* Function definition */ sqlite3_value *pVal = 0; /* New value */ int rc = SQLITE_OK; /* Return code */ @@ -86734,10 +85947,12 @@ SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall( int eCallCtx /* Calling context */ ){ Vdbe *v = pParse->pVdbe; + int nByte; int addr; sqlite3_context *pCtx; assert( v ); - pCtx = sqlite3DbMallocRawNN(pParse->db, SZ_CONTEXT(nArg)); + nByte = sizeof(*pCtx) + (nArg-1)*sizeof(sqlite3_value*); + pCtx = sqlite3DbMallocRawNN(pParse->db, nByte); if( pCtx==0 ){ assert( pParse->db->mallocFailed ); freeEphemeralFunction(pParse->db, (FuncDef*)pFunc); @@ -87013,7 +86228,7 @@ static Op *opIterNext(VdbeOpIter *p){ } if( pRet->p4type==P4_SUBPROGRAM ){ - i64 nByte = (1+(u64)p->nSub)*sizeof(SubProgram*); + int nByte = (p->nSub+1)*sizeof(SubProgram*); int j; for(j=0; jnSub; j++){ if( p->apSub[j]==pRet->p4.pProgram ) break; @@ -87143,8 +86358,8 @@ SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){ ** (1) For each jump instruction with a negative P2 value (a label) ** resolve the P2 value to an actual address. ** -** (2) Compute the maximum number of arguments used by the xUpdate/xFilter -** methods of any virtual table and store that value in *pMaxVtabArgs. +** (2) Compute the maximum number of arguments used by any SQL function +** and store that value in *pMaxFuncArgs. ** ** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately ** indicate what the prepared statement actually does. @@ -87157,8 +86372,8 @@ SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){ ** script numbers the opcodes correctly. Changes to this routine must be ** coordinated with changes to mkopcodeh.tcl. */ -static void resolveP2Values(Vdbe *p, int *pMaxVtabArgs){ - int nMaxVtabArgs = *pMaxVtabArgs; +static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ + int nMaxArgs = *pMaxFuncArgs; Op *pOp; Parse *pParse = p->pParse; int *aLabel = pParse->aLabel; @@ -87203,19 +86418,15 @@ static void resolveP2Values(Vdbe *p, int *pMaxVtabArgs){ } #ifndef SQLITE_OMIT_VIRTUALTABLE case OP_VUpdate: { - if( pOp->p2>nMaxVtabArgs ) nMaxVtabArgs = pOp->p2; + if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; break; } case OP_VFilter: { int n; - /* The instruction immediately prior to VFilter will be an - ** OP_Integer that sets the "argc" value for the VFilter. See - ** the code where OP_VFilter is generated at tag-20250207a. */ assert( (pOp - p->aOp) >= 3 ); assert( pOp[-1].opcode==OP_Integer ); - assert( pOp[-1].p2==pOp->p3+1 ); n = pOp[-1].p1; - if( n>nMaxVtabArgs ) nMaxVtabArgs = n; + if( n>nMaxArgs ) nMaxArgs = n; /* Fall through into the default case */ /* no break */ deliberate_fall_through } @@ -87256,7 +86467,7 @@ resolve_p2_values_loop_exit: pParse->aLabel = 0; } pParse->nLabel = 0; - *pMaxVtabArgs = nMaxVtabArgs; + *pMaxFuncArgs = nMaxArgs; assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); } @@ -87485,7 +86696,7 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus( const char *zName /* Name of table or index being scanned */ ){ if( IS_STMT_SCANSTATUS(p->db) ){ - i64 nByte = (1+(i64)p->nScan) * sizeof(ScanStatus); + sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); ScanStatus *aNew; aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); if( aNew ){ @@ -87595,9 +86806,6 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ */ SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){ VdbeOp *pOp = sqlite3VdbeGetLastOp(p); -#ifdef SQLITE_DEBUG - while( pOp->opcode==OP_ReleaseReg ) pOp--; -#endif if( pOp->p3==iDest && pOp->opcode==OP_Column ){ pOp->p5 |= OPFLAG_TYPEOFARG; } @@ -88937,7 +88145,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( int nVar; /* Number of parameters */ int nMem; /* Number of VM memory registers */ int nCursor; /* Number of cursors required */ - int nArg; /* Max number args to xFilter or xUpdate */ + int nArg; /* Number of arguments in subprograms */ int n; /* Loop counter */ struct ReusableSpace x; /* Reusable bulk memory */ @@ -89009,9 +88217,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); } } -#ifdef SQLITE_DEBUG - p->napArg = nArg; -#endif if( db->mallocFailed ){ p->nVar = 0; @@ -90509,7 +89714,6 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( ){ UnpackedRecord *p; /* Unpacked record to return */ int nByte; /* Number of bytes required for *p */ - assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff ); nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( !p ) return 0; @@ -91816,11 +91020,10 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( preupdate.pCsr = pCsr; preupdate.op = op; preupdate.iNewReg = iReg; - preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; - preupdate.pKeyinfo->db = db; - preupdate.pKeyinfo->enc = ENC(db); - preupdate.pKeyinfo->nKeyField = pTab->nCol; - preupdate.pKeyinfo->aSortFlags = (u8*)&fakeSortOrder; + preupdate.keyinfo.db = db; + preupdate.keyinfo.enc = ENC(db); + preupdate.keyinfo.nKeyField = pTab->nCol; + preupdate.keyinfo.aSortFlags = (u8*)&fakeSortOrder; preupdate.iKey1 = iKey1; preupdate.iKey2 = iKey2; preupdate.pTab = pTab; @@ -91830,8 +91033,8 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); db->pPreUpdate = 0; sqlite3DbFree(db, preupdate.aRecord); - vdbeFreeUnpacked(db, preupdate.pKeyinfo->nKeyField+1,preupdate.pUnpacked); - vdbeFreeUnpacked(db, preupdate.pKeyinfo->nKeyField+1,preupdate.pNewUnpacked); + vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); + vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); sqlite3VdbeMemRelease(&preupdate.oldipk); if( preupdate.aNew ){ int i; @@ -93662,7 +92865,7 @@ SQLITE_API int sqlite3_bind_text64( assert( xDel!=SQLITE_DYNAMIC ); if( enc!=SQLITE_UTF8 ){ if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; - nData &= ~(u64)1; + nData &= ~(u16)1; } return bindText(pStmt, i, zData, nData, xDel, enc); } @@ -94070,7 +93273,7 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa if( !aRec ) goto preupdate_old_out; rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); if( rc==SQLITE_OK ){ - p->pUnpacked = vdbeUnpackRecord(p->pKeyinfo, nRec, aRec); + p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); if( !p->pUnpacked ) rc = SQLITE_NOMEM; } if( rc!=SQLITE_OK ){ @@ -94087,9 +93290,7 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa Column *pCol = &p->pTab->aCol[iIdx]; if( pCol->iDflt>0 ){ if( p->apDflt==0 ){ - int nByte; - assert( sizeof(sqlite3_value*)*UMXV(p->pTab->nCol) < 0x7fffffff ); - nByte = sizeof(sqlite3_value*)*p->pTab->nCol; + int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); if( p->apDflt==0 ) goto preupdate_old_out; } @@ -94135,7 +93336,7 @@ SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ #else p = db->pPreUpdate; #endif - return (p ? p->pKeyinfo->nKeyField : 0); + return (p ? p->keyinfo.nKeyField : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -94218,7 +93419,7 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppVa Mem *pData = &p->v->aMem[p->iNewReg]; rc = ExpandBlob(pData); if( rc!=SQLITE_OK ) goto preupdate_new_out; - pUnpack = vdbeUnpackRecord(p->pKeyinfo, pData->n, pData->z); + pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z); if( !pUnpack ){ rc = SQLITE_NOMEM; goto preupdate_new_out; @@ -94239,8 +93440,7 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppVa */ assert( p->op==SQLITE_UPDATE ); if( !p->aNew ){ - assert( sizeof(Mem)*UMXV(p->pCsr->nField) < 0x7fffffff ); - p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem)*p->pCsr->nField); + p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField); if( !p->aNew ){ rc = SQLITE_NOMEM; goto preupdate_new_out; @@ -95010,11 +94210,11 @@ static VdbeCursor *allocateCursor( */ Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; - i64 nByte; + int nByte; VdbeCursor *pCx = 0; - nByte = SZ_VDBECURSOR(nField); - assert( ROUND8(nByte)==nByte ); - if( eCurType==CURTYPE_BTREE ) nByte += sqlite3BtreeCursorSize(); + nByte = + ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + + (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); assert( iCur>=0 && iCurnCursor ); if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ @@ -95038,7 +94238,7 @@ static VdbeCursor *allocateCursor( pMem->szMalloc = 0; return 0; } - pMem->szMalloc = (int)nByte; + pMem->szMalloc = nByte; } p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc; @@ -95047,8 +94247,8 @@ static VdbeCursor *allocateCursor( pCx->nField = nField; pCx->aOffset = &pCx->aType[nField]; if( eCurType==CURTYPE_BTREE ){ - assert( ROUND8(SZ_VDBECURSOR(nField))==SZ_VDBECURSOR(nField) ); - pCx->uc.pCursor = (BtCursor*)&pMem->z[SZ_VDBECURSOR(nField)]; + pCx->uc.pCursor = (BtCursor*) + &pMem->z[ROUND8P(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; sqlite3BtreeCursorZero(pCx->uc.pCursor); } return pCx; @@ -96052,7 +95252,7 @@ case OP_Halt: { sqlite3VdbeError(p, "%s", pOp->p4.z); } pcx = (int)(pOp - aOp); - sqlite3_log(pOp->p1, "abort at %d: %s; [%s]", pcx, p->zErrMsg, p->zSql); + sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg); } rc = sqlite3VdbeHalt(p); assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); @@ -97378,7 +96578,7 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ break; } -/* Opcode: Once P1 P2 P3 * * +/* Opcode: Once P1 P2 * * * ** ** Fall through to the next instruction the first time this opcode is ** encountered on each invocation of the byte-code program. Jump to P2 @@ -97394,12 +96594,6 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ ** whether or not the jump should be taken. The bitmask is necessary ** because the self-altering code trick does not work for recursive ** triggers. -** -** The P3 operand is not used directly by this opcode. However P3 is -** used by the code generator as follows: If this opcode is the start -** of a subroutine and that subroutine uses a Bloom filter, then P3 will -** be the register that holds that Bloom filter. See tag-202407032019 -** in the source code for implementation details. */ case OP_Once: { /* jump */ u32 iAddr; /* Address of this instruction */ @@ -100797,7 +99991,7 @@ case OP_RowData: { /* The OP_RowData opcodes always follow OP_NotExists or ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions ** that might invalidate the cursor. - ** If this were not the case, one of the following assert()s + ** If this where not the case, on of the following assert()s ** would fail. Should this ever change (because of changes in the code ** generator) then the fix would be to insert a call to ** sqlite3VdbeCursorMoveto(). @@ -102066,7 +101260,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */ */ case OP_Program: { /* jump0 */ int nMem; /* Number of memory registers for sub-program */ - i64 nByte; /* Bytes of runtime space required for sub-program */ + int nByte; /* Bytes of runtime space required for sub-program */ Mem *pRt; /* Register to allocate runtime space */ Mem *pMem; /* Used to iterate through memory cells */ Mem *pEnd; /* Last memory cell in new array */ @@ -102117,7 +101311,7 @@ case OP_Program: { /* jump0 */ nByte = ROUND8(sizeof(VdbeFrame)) + nMem * sizeof(Mem) + pProgram->nCsr * sizeof(VdbeCursor*) - + (7 + (i64)pProgram->nOp)/8; + + (pProgram->nOp + 7)/8; pFrame = sqlite3DbMallocZero(db, nByte); if( !pFrame ){ goto no_mem; @@ -102125,7 +101319,7 @@ case OP_Program: { /* jump0 */ sqlite3VdbeMemRelease(pRt); pRt->flags = MEM_Blob|MEM_Dyn; pRt->z = (char*)pFrame; - pRt->n = (int)nByte; + pRt->n = nByte; pRt->xDel = sqlite3VdbeFrameMemDel; pFrame->v = p; @@ -102224,14 +101418,12 @@ case OP_Param: { /* out2 */ ** statement counter is incremented (immediate foreign key constraints). */ case OP_FkCounter: { - if( pOp->p1 ){ + if( db->flags & SQLITE_DeferFKs ){ + db->nDeferredImmCons += pOp->p2; + }else if( pOp->p1 ){ db->nDeferredCons += pOp->p2; }else{ - if( db->flags & SQLITE_DeferFKs ){ - db->nDeferredImmCons += pOp->p2; - }else{ - p->nFkConstraint += pOp->p2; - } + p->nFkConstraint += pOp->p2; } break; } @@ -102446,7 +101638,7 @@ case OP_AggStep: { ** ** Note: We could avoid this by using a regular memory cell from aMem[] for ** the accumulator, instead of allocating one here. */ - nAlloc = ROUND8P( SZ_CONTEXT(n) ); + nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) ); pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); if( pCtx==0 ) goto no_mem; pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); @@ -103106,7 +102298,6 @@ case OP_VFilter: { /* jump, ncycle */ /* Invoke the xFilter method */ apArg = p->apArg; - assert( nArg<=p->napArg ); for(i = 0; ivtabOnConflict; apArg = p->apArg; pX = &aMem[pOp->p3]; - assert( nArg<=p->napArg ); for(i=0; irc = rc; sqlite3SystemError(db, rc); testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(rc, "statement aborts at %d: %s; [%s]", - (int)(pOp - aOp), p->zErrMsg, p->zSql); + sqlite3_log(rc, "statement aborts at %d: [%s] %s", + (int)(pOp - aOp), p->zSql, p->zErrMsg); if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){ @@ -104104,7 +103294,6 @@ SQLITE_API int sqlite3_blob_open( char *zErr = 0; Table *pTab; Incrblob *pBlob = 0; - int iDb; Parse sParse; #ifdef SQLITE_ENABLE_API_ARMOR @@ -104150,10 +103339,7 @@ SQLITE_API int sqlite3_blob_open( sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); } #endif - if( pTab==0 - || ((iDb = sqlite3SchemaToIndex(db, pTab->pSchema))==1 && - sqlite3OpenTempDatabase(&sParse)) - ){ + if( !pTab ){ if( sParse.zErrMsg ){ sqlite3DbFree(db, zErr); zErr = sParse.zErrMsg; @@ -104164,11 +103350,15 @@ SQLITE_API int sqlite3_blob_open( goto blob_open_out; } pBlob->pTab = pTab; - pBlob->zDb = db->aDb[iDb].zDbSName; + pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; /* Now search pTab for the exact column. */ - iCol = sqlite3ColumnIndex(pTab, zColumn); - if( iCol<0 ){ + for(iCol=0; iColnCol; iCol++) { + if( sqlite3StrICmp(pTab->aCol[iCol].zCnName, zColumn)==0 ){ + break; + } + } + if( iCol==pTab->nCol ){ sqlite3DbFree(db, zErr); zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn); rc = SQLITE_ERROR; @@ -104248,6 +103438,7 @@ SQLITE_API int sqlite3_blob_open( {OP_Halt, 0, 0, 0}, /* 5 */ }; Vdbe *v = (Vdbe *)pBlob->pStmt; + int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); VdbeOp *aOp; sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, @@ -104825,12 +104016,9 @@ struct VdbeSorter { u8 iPrev; /* Previous thread used to flush PMA */ u8 nTask; /* Size of aTask[] array */ u8 typeMask; - SortSubtask aTask[FLEXARRAY]; /* One or more subtasks */ + SortSubtask aTask[1]; /* One or more subtasks */ }; -/* Size (in bytes) of a VdbeSorter object that works with N or fewer subtasks */ -#define SZ_VDBESORTER(N) (offsetof(VdbeSorter,aTask)+(N)*sizeof(SortSubtask)) - #define SORTER_TYPE_INTEGER 0x01 #define SORTER_TYPE_TEXT 0x02 @@ -105432,7 +104620,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( VdbeSorter *pSorter; /* The new sorter */ KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */ int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */ - i64 sz; /* Size of pSorter in bytes */ + int sz; /* Size of pSorter in bytes */ int rc = SQLITE_OK; #if SQLITE_MAX_WORKER_THREADS==0 # define nWorker 0 @@ -105460,10 +104648,8 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( assert( pCsr->pKeyInfo ); assert( !pCsr->isEphemeral ); assert( pCsr->eCurType==CURTYPE_SORTER ); - assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) - < 0x7fffffff ); - szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField); - sz = SZ_VDBESORTER(nWorker+1); + szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*); + sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); pCsr->uc.pSorter = pSorter; @@ -105675,7 +104861,7 @@ static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){ */ static MergeEngine *vdbeMergeEngineNew(int nReader){ int N = 2; /* Smallest power of two >= nReader */ - i64 nByte; /* Total bytes of space to allocate */ + int nByte; /* Total bytes of space to allocate */ MergeEngine *pNew; /* Pointer to allocated object to return */ assert( nReader<=SORTER_MAX_MERGE_COUNT ); @@ -105927,10 +105113,6 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ p->u.pNext = 0; for(i=0; aSlot[i]; i++){ p = vdbeSorterMerge(pTask, p, aSlot[i]); - /* ,--Each aSlot[] holds twice as much as the previous. So we cannot use - ** | up all 64 aSlots[] with only a 64-bit address space. - ** v */ - assert( i @@ -108262,10 +107449,6 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ #define SQLCIPHER_H /* #include "sqlite3.h" */ -/* #include "sqliteInt.h" */ - -#define SQLCIPHER_DECRYPT 0 -#define SQLCIPHER_ENCRYPT 1 #define SQLCIPHER_HMAC_SHA1 0 #define SQLCIPHER_HMAC_SHA1_LABEL "HMAC_SHA1" @@ -108392,9 +107575,6 @@ void sqlcipher_log(unsigned int level, unsigned int source, const char *message, /************** End of sqlcipher.h *******************************************/ /************** Continuing where we left off in sqlcipher.c ******************/ -/* #include "btreeInt.h" */ -/* #include "pager.h" */ -/* #include "vdbeInt.h" */ #if !defined(SQLITE_EXTRA_INIT) || !defined(SQLITE_EXTRA_SHUTDOWN) #error "SQLCipher must be compiled with -DSQLITE_EXTRA_INIT=sqlcipher_extra_init -DSQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown" @@ -108430,13 +107610,16 @@ SQLITE_API void sqlite3pager_reset(Pager *pPager); #define CIPHER_STR(s) #s #ifndef CIPHER_VERSION_NUMBER -#define CIPHER_VERSION_NUMBER 4.11.0 +#define CIPHER_VERSION_NUMBER 4.9.0 #endif #ifndef CIPHER_VERSION_BUILD #define CIPHER_VERSION_BUILD community #endif +#define CIPHER_DECRYPT 0 +#define CIPHER_ENCRYPT 1 + #define CIPHER_READ_CTX 0 #define CIPHER_WRITE_CTX 1 #define CIPHER_READWRITE_CTX 2 @@ -108604,10 +107787,6 @@ static volatile sqlite3_mem_methods default_mem_methods; static sqlcipher_provider *default_provider = NULL; static sqlite3_mutex* sqlcipher_static_mutex[SQLCIPHER_MUTEX_COUNT]; - -#ifndef SQLCIPHER_LOG_LEVEL_DEFAULT -#define SQLCIPHER_LOG_LEVEL_DEFAULT SQLCIPHER_LOG_WARN -#endif static FILE* sqlcipher_log_file = NULL; static volatile int sqlcipher_log_device = 0; static volatile unsigned int sqlcipher_log_level = SQLCIPHER_LOG_NONE; @@ -108716,26 +107895,21 @@ static void sqlcipher_fini(void) { } #if defined(_WIN32) - #ifndef SQLCIPHER_OMIT_DLLMAIN - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - switch (fdwReason) { - case DLL_PROCESS_DETACH: - sqlcipher_log(SQLCIPHER_LOG_DEBUG, SQLCIPHER_LOG_CORE, "%s: calling sqlcipher_extra_shutdown()", __func__); - sqlcipher_extra_shutdown(); - break; - default: - break; - } - return TRUE; +#ifndef SQLCIPHER_OMIT_DLLMAIN +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + switch (fdwReason) { + case DLL_PROCESS_DETACH: + sqlcipher_log(SQLCIPHER_LOG_DEBUG, SQLCIPHER_LOG_CORE, "%s: calling sqlcipher_extra_shutdown()", __func__); + sqlcipher_extra_shutdown(); + break; + default: + break; } - #endif + return TRUE; +} +#endif #elif defined(__APPLE__) - #if defined(__has_feature) && __has_feature(address_sanitizer) - static void sqlcipher_cleanup_destructor(void) __attribute__((destructor)); - static void sqlcipher_cleanup_destructor(void) { sqlcipher_fini(); } - #else - static void (*const sqlcipher_fini_func)(void) __attribute__((used, section("__DATA,__mod_term_func"))) = sqlcipher_fini; - #endif +static void (*const sqlcipher_fini_func)(void) __attribute__((used, section("__DATA,__mod_term_func"))) = sqlcipher_fini; #else static void (*const sqlcipher_fini_func)(void) __attribute__((used, section(".fini_array"))) = sqlcipher_fini; #endif @@ -108777,7 +107951,7 @@ int sqlcipher_extra_init(const char* arg) { /* set log level if it is different than the uninitalized default value of NONE */ if(sqlcipher_log_level == SQLCIPHER_LOG_NONE) { - sqlcipher_log_level = SQLCIPHER_LOG_LEVEL_DEFAULT; + sqlcipher_log_level = SQLCIPHER_LOG_WARN; } /* set the default file or device if neither is already set */ @@ -108808,11 +107982,11 @@ int sqlcipher_extra_init(const char* arg) { while(private_heap_sz >= SQLCIPHER_PRIVATE_HEAP_SIZE_STEP) { /* attempt to allocate the private heap. If allocation fails, reduce the size and try again */ if((private_heap = sqlcipher_internal_malloc(private_heap_sz))) { - xoshiro_randomness(private_heap, (int) private_heap_sz); + xoshiro_randomness(private_heap, private_heap_sz); /* initialize the head block of the linked list at the start of the heap */ private_block *head = (private_block *) private_heap; head->is_used = 0; - head->size = (u32) private_heap_sz - sizeof(private_block); + head->size = private_heap_sz - sizeof(private_block); head->next = NULL; break; } @@ -108875,13 +108049,13 @@ int sqlcipher_extra_init(const char* arg) { sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_MEMORY, "%s: failed to allocate shield mask", __func__); goto error; } - if((rc = default_provider->random(provider_ctx, sqlcipher_shield_mask, (int) sqlcipher_shield_mask_sz)) != SQLITE_OK) { + if((rc = default_provider->random(provider_ctx, sqlcipher_shield_mask, sqlcipher_shield_mask_sz)) != SQLITE_OK) { sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_MEMORY, "%s: failed to generate requisite random mask data %d", __func__, rc); goto error; } } - default_provider->ctx_free(&provider_ctx); + default_provider->ctx_free(provider_ctx); sqlcipher_init = 1; sqlcipher_shutdown = 0; @@ -110001,14 +109175,14 @@ static int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mod goto error; } - if(mode == SQLCIPHER_ENCRYPT) { + if(mode == CIPHER_ENCRYPT) { /* start at front of the reserve block, write random data to the end */ if(ctx->provider->random(ctx->provider_ctx, iv_out, ctx->reserve_sz) != SQLITE_OK) goto error; - } else { /* SQLCIPHER_DECRYPT */ + } else { /* CIPHER_DECRYPT */ memcpy(iv_out, iv_in, ctx->iv_sz); /* copy the iv from the input to output buffer */ } - if(SQLCIPHER_FLAG_GET(ctx->flags, CIPHER_FLAG_HMAC) && (mode == SQLCIPHER_DECRYPT)) { + if(SQLCIPHER_FLAG_GET(ctx->flags, CIPHER_FLAG_HMAC) && (mode == CIPHER_DECRYPT)) { if(sqlcipher_page_hmac(ctx, c_ctx, pgno, in, size + ctx->iv_sz, hmac_out) != SQLITE_OK) { sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_CORE, "%s: hmac operation on decrypt failed for pgno=%d", __func__, pgno); goto error; @@ -110043,7 +109217,7 @@ static int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mod goto error; }; - if(SQLCIPHER_FLAG_GET(ctx->flags, CIPHER_FLAG_HMAC) && (mode == SQLCIPHER_ENCRYPT)) { + if(SQLCIPHER_FLAG_GET(ctx->flags, CIPHER_FLAG_HMAC) && (mode == CIPHER_ENCRYPT)) { if(sqlcipher_page_hmac(ctx, c_ctx, pgno, out_start, size + ctx->iv_sz, hmac_out) != SQLITE_OK) { sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_CORE, "%s: hmac operation on encrypt failed for pgno=%d", __func__, pgno); goto error; @@ -110594,43 +109768,6 @@ static int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight, int ra return SQLITE_ERROR; } -#if defined(_WIN32) -/* On windows convert to utf-16 when writing to stderr or stdout to avoid - * a potential exception when writing mixed context to those streams - * when using the shell. */ -static int sqlcipher_fprintf(FILE* stream, const char* format, ...) { - int sz; - va_list ap; - - if (stream == stderr || stream == stdout) { - char* buffer = NULL; - wchar_t* wbuffer = NULL; - - va_start(ap, format); - buffer = sqlite3_vmprintf(format, ap); - va_end(ap); - sz = (int)strlen(buffer); - - wbuffer = sqlite3_malloc((sz + 1) * sizeof(wchar_t)); - if (wbuffer == NULL) return -1; - - sz = MultiByteToWideChar(CP_UTF8, 0, buffer, sz, wbuffer, sz); - wbuffer[sz] = (wchar_t) 0; - fputws(wbuffer, stream); - - sqlite3_free(wbuffer); - sqlite3_free(buffer); - } else { - va_start(ap, format); - sz = vfprintf(stream, format, ap); - va_end(ap); - } - return sz; -} -#else -#define sqlcipher_fprintf fprintf -#endif - #if !defined(SQLITE_OMIT_TRACE) #define SQLCIPHER_PROFILE_FMT "Elapsed time:%.3f ms - %s\n" @@ -110648,7 +109785,7 @@ static int sqlcipher_profile_callback(unsigned int trace, void *file, void *stmt #endif #endif } else { - sqlcipher_fprintf(f, SQLCIPHER_PROFILE_FMT, elapsed, sqlite3_sql((sqlite3_stmt*)stmt)); + fprintf(f, SQLCIPHER_PROFILE_FMT, elapsed, sqlite3_sql((sqlite3_stmt*)stmt)); } return SQLITE_OK; } @@ -110752,9 +109889,8 @@ void sqlcipher_log(unsigned int level, unsigned int source, const char *message, #ifdef CODEC_DEBUG #if defined(SQLCIPHER_OMIT_LOG_DEVICE) || (!defined(__ANDROID__) && !defined(__APPLE__)) - sqlite3_vsnprintf(MAX_LOG_LEN, formatted, message, params); - sqlcipher_fprintf(stderr, formatted); - sqlcipher_fprintf(stderr, "\n"); + vfprintf(stderr, message, params); + fprintf(stderr, "\n"); goto end; #else #if defined(__ANDROID__) @@ -110813,7 +109949,7 @@ void sqlcipher_log(unsigned int level, unsigned int source, const char *message, localtime_r(&sec, &tt); #endif if(strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tt)) { - sqlcipher_fprintf((FILE*)sqlcipher_log_file, "%s.%03d: %s\n", buffer, ms, formatted); + fprintf((FILE*)sqlcipher_log_file, "%s.%03d: %s\n", buffer, ms, formatted); goto end; } } @@ -111596,7 +110732,7 @@ static void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) { if(pgno == 1) /* copy initial part of file header or SQLite magic to buffer */ memcpy(ctx->buffer, ctx->plaintext_header_sz ? pData : (void *) SQLITE_FILE_HEADER, offset); - rc = sqlcipher_page_cipher(ctx, cctx, pgno, SQLCIPHER_DECRYPT, ctx->page_sz - offset, pData + offset, (unsigned char*)ctx->buffer + offset); + rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_DECRYPT, ctx->page_sz - offset, pData + offset, (unsigned char*)ctx->buffer + offset); #ifdef SQLCIPHER_TEST if((cipher_test_flags & TEST_FAIL_DECRYPT) > 0 && sqlcipher_get_test_fail()) { rc = SQLITE_ERROR; @@ -111637,7 +110773,7 @@ static void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) { } memcpy(ctx->buffer, ctx->plaintext_header_sz ? pData : kdf_salt, offset); } - rc = sqlcipher_page_cipher(ctx, cctx, pgno, SQLCIPHER_ENCRYPT, ctx->page_sz - offset, pData + offset, (unsigned char*)ctx->buffer + offset); + rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_ENCRYPT, ctx->page_sz - offset, pData + offset, (unsigned char*)ctx->buffer + offset); #ifdef SQLCIPHER_TEST if((cipher_test_flags & TEST_FAIL_ENCRYPT) > 0 && sqlcipher_get_test_fail()) { rc = SQLITE_ERROR; @@ -112276,7 +111412,6 @@ static int sqlcipher_ltc_add_random(void *ctx, const void *buffer, int length) { static int sqlcipher_ltc_activate(void *ctx) { unsigned char random_buffer[FORTUNA_MAX_SZ]; - int bytes = 0; sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_ltc_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE"); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); @@ -112298,9 +111433,8 @@ static int sqlcipher_ltc_activate(void *ctx) { ltc_ref_count++; #ifndef SQLCIPHER_TEST - bytes = rng_get_bytes(random_buffer, FORTUNA_MAX_SZ, NULL); + sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer); #endif - sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_PROVIDER, "sqlcipher_ltc_activate: seeded fortuna with %d bytes from rng_get_bytes", bytes); if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) { return SQLITE_ERROR; @@ -112437,7 +111571,7 @@ static int sqlcipher_ltc_cipher( if((cipher_idx = find_cipher(LTC_CIPHER)) == -1) return SQLITE_ERROR; if((rc = cbc_start(cipher_idx, iv, key, key_sz, 0, &cbc)) != CRYPT_OK) return SQLITE_ERROR; - rc = mode == SQLCIPHER_ENCRYPT ? cbc_encrypt(in, out, in_sz, &cbc) : cbc_decrypt(in, out, in_sz, &cbc); + rc = mode == 1 ? cbc_encrypt(in, out, in_sz, &cbc) : cbc_decrypt(in, out, in_sz, &cbc); if(rc != CRYPT_OK) return SQLITE_ERROR; cbc_done(&cbc); return SQLITE_OK; @@ -112787,7 +111921,7 @@ static int sqlcipher_nss_cipher( CKA_ENCRYPT, &keyItem, NULL); if (symKey == NULL) goto error; SECStatus rv; - if (mode == SQLCIPHER_ENCRYPT) { + if (mode == CIPHER_ENCRYPT) { rv = PK11_Encrypt(symKey, CKM_AES_CBC, ¶ms, out, &outLen, in_sz + 16, in, in_sz); } else { @@ -113321,30 +112455,16 @@ static const char* sqlcipher_cc_get_provider_name(void *ctx) { static const char* sqlcipher_cc_get_provider_version(void *ctx) { #if TARGET_OS_MAC - /* macOS uses com.apple.security with a lowercase s */ + CFTypeRef version; CFBundleRef bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security")); - CFTypeRef bundle_ver; - const char *ver; - - /* if the bundle wasn't identified, try secrurity with a capial S (works for iOS) */ - if(!bundle) { - bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.Security")); + if(bundle == NULL) { + return "unknown"; } - - /* If the bundle was resolved, retrieve the bundle version key then attempt to convert it to a C string. - * Note that it is possible for CFStringGetCString to return NULL (this is warned against extensively in the - * header), so only return a value if the conversion was successful. */ - if( - bundle - && (bundle_ver = CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey)) - && (ver = CFStringGetCStringPtr(bundle_ver, kCFStringEncodingUTF8)) - ) { - return ver; - } - -#endif - /* unable to detect the CoreCrypto version, return a fixed string "unknown" */ + version = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString")); + return CFStringGetCStringPtr(version, kCFStringEncodingUTF8); +#else return "unknown"; +#endif } static int sqlcipher_cc_hmac( @@ -113407,7 +112527,7 @@ static int sqlcipher_cc_cipher( ) { CCCryptorRef cryptor; size_t tmp_csz, csz; - CCOperation op = mode == SQLCIPHER_ENCRYPT ? kCCEncrypt : kCCDecrypt; + CCOperation op = mode == CIPHER_ENCRYPT ? kCCEncrypt : kCCDecrypt; if(CCCryptorCreate(op, kCCAlgorithmAES128, 0, key, kCCKeySizeAES256, iv, &cryptor) != kCCSuccess) return SQLITE_ERROR; if(CCCryptorUpdate(cryptor, in, in_sz, out, in_sz, &tmp_csz) != kCCSuccess) return SQLITE_ERROR; @@ -114052,6 +113172,7 @@ static int lookupName( Schema *pSchema = 0; /* Schema of the expression */ int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ Table *pTab = 0; /* Table holding the row */ + Column *pCol; /* A column of pTab */ ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ const char *zCol = pRight->u.zToken; @@ -114102,6 +113223,7 @@ static int lookupName( if( pSrcList ){ for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ + u8 hCol; pTab = pItem->pSTab; assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 || pParse->nErr ); @@ -114189,38 +113311,43 @@ static int lookupName( sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); } } - j = sqlite3ColumnIndex(pTab, zCol); - if( j>=0 ){ - if( cnt>0 ){ - if( pItem->fg.isUsing==0 - || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 - ){ - /* Two or more tables have the same column name which is - ** not joined by USING. This is an error. Signal as much - ** by clearing pFJMatch and letting cnt go above 1. */ - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else - if( (pItem->fg.jointype & JT_RIGHT)==0 ){ - /* An INNER or LEFT JOIN. Use the left-most table */ - continue; - }else - if( (pItem->fg.jointype & JT_LEFT)==0 ){ - /* A RIGHT JOIN. Use the right-most table */ - cnt = 0; - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else{ - /* For a FULL JOIN, we must construct a coalesce() func */ - extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + hCol = sqlite3StrIHash(zCol); + for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ + if( pCol->hName==hCol + && sqlite3StrICmp(pCol->zCnName, zCol)==0 + ){ + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 + ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + } } - } - cnt++; - pMatch = pItem; - /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ - pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; - if( pItem->fg.isNestedFrom ){ - sqlite3SrcItemColumnUsed(pItem, j); + cnt++; + pMatch = pItem; + /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ + pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; + if( pItem->fg.isNestedFrom ){ + sqlite3SrcItemColumnUsed(pItem, j); + } + break; } } if( 0==cnt && VisibleRowid(pTab) ){ @@ -114310,18 +113437,23 @@ static int lookupName( if( pTab ){ int iCol; + u8 hCol = sqlite3StrIHash(zCol); pSchema = pTab->pSchema; cntTab++; - iCol = sqlite3ColumnIndex(pTab, zCol); - if( iCol>=0 ){ - if( pTab->iPKey==iCol ) iCol = -1; - }else{ - if( sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ - iCol = -1; - }else{ - iCol = pTab->nCol; + for(iCol=0, pCol=pTab->aCol; iColnCol; iCol++, pCol++){ + if( pCol->hName==hCol + && sqlite3StrICmp(pCol->zCnName, zCol)==0 + ){ + if( iCol==pTab->iPKey ){ + iCol = -1; + } + break; } } + if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ + /* IMP: R-51414-32910 */ + iCol = -1; + } if( iColnCol ){ cnt++; pMatch = 0; @@ -114960,12 +114092,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** sqlite_version() that might change over time cannot be used ** in an index or generated column. Curiously, they can be used ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all - ** allow this. */ + ** all this. */ sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr); }else{ assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */ pExpr->op2 = pNC->ncFlags & NC_SelfRef; + if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL); } if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 && pParse->nested==0 @@ -114981,7 +114114,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 && !IN_RENAME_OBJECT ){ - if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL); sqlite3ExprFunctionUsable(pParse, pExpr, pDef); } } @@ -116035,22 +115167,20 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference( Expr *pExpr, /* Expression to resolve. May be NULL. */ ExprList *pList /* Expression list to resolve. May be NULL. */ ){ - SrcList *pSrc; /* Fake SrcList for pParse->pNewTable */ + SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ NameContext sNC; /* Name context for pParse->pNewTable */ int rc; - u8 srcSpace[SZ_SRCLIST_1]; /* Memory space for the fake SrcList */ assert( type==0 || pTab!=0 ); assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || type==NC_GenCol || pTab==0 ); memset(&sNC, 0, sizeof(sNC)); - pSrc = (SrcList*)srcSpace; - memset(pSrc, 0, SZ_SRCLIST_1); + memset(&sSrc, 0, sizeof(sSrc)); if( pTab ){ - pSrc->nSrc = 1; - pSrc->a[0].zName = pTab->zName; - pSrc->a[0].pSTab = pTab; - pSrc->a[0].iCursor = -1; + sSrc.nSrc = 1; + sSrc.a[0].zName = pTab->zName; + sSrc.a[0].pSTab = pTab; + sSrc.a[0].iCursor = -1; if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP ** schema elements */ @@ -116058,7 +115188,7 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference( } } sNC.pParse = pParse; - sNC.pSrcList = pSrc; + sNC.pSrcList = &sSrc; sNC.ncFlags = type | NC_IsDDL; if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc; if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList); @@ -116142,9 +115272,7 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr ); } - if( op==TK_VECTOR - || (op==TK_FUNCTION && pExpr->affExpr==SQLITE_AFF_DEFER) - ){ + if( op==TK_VECTOR ){ assert( ExprUseXList(pExpr) ); return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); } @@ -116337,9 +115465,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ p = p->pLeft; continue; } - if( op==TK_VECTOR - || (op==TK_FUNCTION && p->affExpr==SQLITE_AFF_DEFER) - ){ + if( op==TK_VECTOR ){ assert( ExprUseXList(p) ); p = p->x.pList->a[0].pExpr; continue; @@ -117213,7 +116339,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ return pLeft; }else{ u32 f = pLeft->flags | pRight->flags; - if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse|EP_HasFunc))==EP_IsFalse + if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse && !IN_RENAME_OBJECT ){ sqlite3ExprDeferredDelete(pParse, pLeft); @@ -117811,7 +116937,7 @@ static Expr *exprDup( SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p){ With *pRet = 0; if( p ){ - sqlite3_int64 nByte = SZ_WITH(p->nCte); + sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); pRet = sqlite3DbMallocZero(db, nByte); if( pRet ){ int i; @@ -117922,6 +117048,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int } pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName); pItem->fg = pOldItem->fg; + pItem->fg.done = 0; pItem->u = pOldItem->u; } return pNew; @@ -117938,9 +117065,11 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){ SrcList *pNew; int i; + int nByte; assert( db!=0 ); if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, SZ_SRCLIST(p->nSrc) ); + nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); + pNew = sqlite3DbMallocRawNN(db, nByte ); if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; inSrc; i++){ @@ -118002,7 +117131,7 @@ SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ int i; assert( db!=0 ); if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, SZ_IDLIST(p->nId)); + pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) ); if( pNew==0 ) return 0; pNew->nId = p->nId; for(i=0; inId; i++){ @@ -118034,7 +117163,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int fla pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); pNew->iLimit = 0; pNew->iOffset = 0; - pNew->selFlags = p->selFlags & ~(u32)SF_UsesEphemeral; + pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; @@ -118086,7 +117215,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendNew( struct ExprList_item *pItem; ExprList *pList; - pList = sqlite3DbMallocRawNN(db, SZ_EXPRLIST(4)); + pList = sqlite3DbMallocRawNN(db, sizeof(ExprList)+sizeof(pList->a[0])*4 ); if( pList==0 ){ sqlite3ExprDelete(db, pExpr); return 0; @@ -118106,7 +117235,8 @@ SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendGrow( struct ExprList_item *pItem; ExprList *pNew; pList->nAlloc *= 2; - pNew = sqlite3DbRealloc(db, pList, SZ_EXPRLIST(pList->nAlloc)); + pNew = sqlite3DbRealloc(db, pList, + sizeof(*pList)+(pList->nAlloc-1)*sizeof(pList->a[0])); if( pNew==0 ){ sqlite3ExprListDelete(db, pList); sqlite3ExprDelete(db, pExpr); @@ -119035,7 +118165,13 @@ SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab){ int ii; assert( VisibleRowid(pTab) ); for(ii=0; iinCol; iCol++){ + if( sqlite3_stricmp(azOpt[ii], pTab->aCol[iCol].zCnName)==0 ) break; + } + if( iCol==pTab->nCol ){ + return azOpt[ii]; + } } return 0; } @@ -119439,7 +118575,7 @@ static char *exprINAffinity(Parse *pParse, const Expr *pExpr){ char *zRet; assert( pExpr->op==TK_IN ); - zRet = sqlite3DbMallocRaw(pParse->db, 1+(i64)nVal); + zRet = sqlite3DbMallocRaw(pParse->db, nVal+1); if( zRet ){ int i; for(i=0; idb, pCopy); sqlite3DbFree(pParse->db, dest.zAffSdst); if( addrBloom ){ - /* Remember that location of the Bloom filter in the P3 operand - ** of the OP_Once that began this subroutine. tag-202407032019 */ sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; if( dest.iSDParm2==0 ){ - /* If the Bloom filter won't actually be used, keep it small */ - sqlite3VdbeGetOp(v, addrBloom)->p1 = 10; + sqlite3VdbeChangeToNoop(v, addrBloom); + }else{ + sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; } } if( rc ){ @@ -120151,7 +119286,7 @@ static void sqlite3ExprCodeIN( if( ExprHasProperty(pExpr, EP_Subrtn) ){ const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); assert( pOp->opcode==OP_Once || pParse->nErr ); - if( pOp->opcode==OP_Once && pOp->p3>0 ){ /* tag-202407032019 */ + if( pOp->opcode==OP_Once && pOp->p3>0 ){ assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, rLhs, nVector); VdbeCoverage(v); @@ -120743,7 +119878,7 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup( /* -** Expression pExpr is guaranteed to be a TK_COLUMN or equivalent. This +** Expresion pExpr is guaranteed to be a TK_COLUMN or equivalent. This ** function checks the Parse.pIdxPartExpr list to see if this column ** can be replaced with a constant value. If so, it generates code to ** put the constant value in a register (ideally, but not necessarily, @@ -120967,12 +120102,6 @@ expr_code_doover: sqlite3VdbeLoadString(v, target, pExpr->u.zToken); return target; } - case TK_NULLS: { - /* Set a range of registers to NULL. pExpr->y.nReg registers starting - ** with target */ - sqlite3VdbeAddOp3(v, OP_Null, 0, target, target + pExpr->y.nReg - 1); - return target; - } default: { /* Make NULL the default case so that if a bug causes an illegal ** Expr node to be passed into this function, it will be handled @@ -121657,25 +120786,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce( return regDest; } -/* -** Make arrangements to invoke OP_Null on a range of registers -** during initialization. -*/ -SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3ExprNullRegisterRange( - Parse *pParse, /* Parsing context */ - int iReg, /* First register to set to NULL */ - int nReg /* Number of sequential registers to NULL out */ -){ - u8 okConstFactor = pParse->okConstFactor; - Expr t; - memset(&t, 0, sizeof(t)); - t.op = TK_NULLS; - t.y.nReg = nReg; - pParse->okConstFactor = 1; - sqlite3ExprCodeRunJustOnce(pParse, &t, iReg); - pParse->okConstFactor = okConstFactor; -} - /* ** Generate code to evaluate an expression and store the results ** into a register. Return the register number where the results @@ -123104,9 +122214,7 @@ static void findOrCreateAggInfoColumn( ){ struct AggInfo_col *pCol; int k; - int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; - assert( mxTerm <= SMXV(i16) ); assert( pAggInfo->iFirstReg==0 ); pCol = pAggInfo->aCol; for(k=0; knColumn; k++, pCol++){ @@ -123124,10 +122232,6 @@ static void findOrCreateAggInfoColumn( assert( pParse->db->mallocFailed ); return; } - if( k>mxTerm ){ - sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm); - k = mxTerm; - } pCol = &pAggInfo->aCol[k]; assert( ExprUseYTab(pExpr) ); pCol->pTab = pExpr->y.pTab; @@ -123161,7 +122265,6 @@ fix_up_expr: if( pExpr->op==TK_COLUMN ){ pExpr->op = TK_AGG_COLUMN; } - assert( k <= SMXV(pExpr->iAgg) ); pExpr->iAgg = (i16)k; } @@ -123246,19 +122349,13 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ ** function that is already in the pAggInfo structure */ struct AggInfo_func *pItem = pAggInfo->aFunc; - int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; - assert( mxTerm <= SMXV(i16) ); for(i=0; inFunc; i++, pItem++){ if( NEVER(pItem->pFExpr==pExpr) ) break; if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ break; } } - if( i>mxTerm ){ - sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm); - i = mxTerm; - assert( inFunc ); - }else if( i>=pAggInfo->nFunc ){ + if( i>=pAggInfo->nFunc ){ /* pExpr is original. Make a new entry in pAggInfo->aFunc[] */ u8 enc = ENC(pParse->db); @@ -123312,7 +122409,6 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ */ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pExpr, EP_NoReduce); - assert( i <= SMXV(pExpr->iAgg) ); pExpr->iAgg = (i16)i; pExpr->pAggInfo = pAggInfo; return WRC_Prune; @@ -124023,13 +123119,13 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); - pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*(u32)nAlloc); + pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); if( !pNew->aCol || !pNew->zName ){ assert( db->mallocFailed ); goto exit_begin_add_column; } - memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*(size_t)pNew->nCol); + memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); for(i=0; inCol; i++){ Column *pCol = &pNew->aCol[i]; pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName); @@ -124124,8 +123220,10 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( ** altered. Set iCol to be the index of the column being renamed */ zOld = sqlite3NameFromToken(db, pOld); if( !zOld ) goto exit_rename_column; - iCol = sqlite3ColumnIndex(pTab, zOld); - if( iCol<0 ){ + for(iCol=0; iColnCol; iCol++){ + if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break; + } + if( iCol==pTab->nCol ){ sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld); goto exit_rename_column; } @@ -124628,7 +123726,6 @@ static int renameParseSql( int bTemp /* True if SQL is from temp schema */ ){ int rc; - u64 flags; sqlite3ParseObjectInit(p, db); if( zSql==0 ){ @@ -124637,21 +123734,11 @@ static int renameParseSql( if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){ return SQLITE_CORRUPT_BKPT; } - if( bTemp ){ - db->init.iDb = 1; - }else{ - int iDb = sqlite3FindDbName(db, zDb); - assert( iDb>=0 && iDb<=0xff ); - db->init.iDb = (u8)iDb; - } + db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; - flags = db->flags; - testcase( (db->flags & SQLITE_Comments)==0 && strstr(zSql," /* ")!=0 ); - db->flags |= SQLITE_Comments; rc = sqlite3RunParser(p, zSql); - db->flags = flags; if( db->mallocFailed ) rc = SQLITE_NOMEM; if( rc==SQLITE_OK && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0) @@ -124714,11 +123801,10 @@ static int renameEditSql( nQuot = sqlite3Strlen30(zQuot)-1; } - assert( nQuot>=nNew && nSql>=0 && nNew>=0 ); - zOut = sqlite3DbMallocZero(db, (u64)nSql + pRename->nList*(u64)nQuot + 1); + assert( nQuot>=nNew ); + zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); }else{ - assert( nSql>0 ); - zOut = (char*)sqlite3DbMallocZero(db, (2*(u64)nSql + 1) * 3); + zOut = (char*)sqlite3DbMallocZero(db, (nSql*2+1) * 3); if( zOut ){ zBuf1 = &zOut[nSql*2+1]; zBuf2 = &zOut[nSql*4+2]; @@ -124730,17 +123816,16 @@ static int renameEditSql( ** with the new column name, or with single-quoted versions of themselves. ** All that remains is to construct and return the edited SQL string. */ if( zOut ){ - i64 nOut = nSql; - assert( nSql>0 ); - memcpy(zOut, zSql, (size_t)nSql); + int nOut = nSql; + memcpy(zOut, zSql, nSql); while( pRename->pList ){ int iOff; /* Offset of token to replace in zOut */ - i64 nReplace; + u32 nReplace; const char *zReplace; RenameToken *pBest = renameColumnTokenNext(pRename); if( zNew ){ - if( bQuote==0 && sqlite3IsIdChar(*(u8*)pBest->t.z) ){ + if( bQuote==0 && sqlite3IsIdChar(*pBest->t.z) ){ nReplace = nNew; zReplace = zNew; }else{ @@ -124758,15 +123843,14 @@ static int renameEditSql( memcpy(zBuf1, pBest->t.z, pBest->t.n); zBuf1[pBest->t.n] = 0; sqlite3Dequote(zBuf1); - assert( nSql < 0x15555554 /* otherwise malloc would have failed */ ); - sqlite3_snprintf((int)(nSql*2), zBuf2, "%Q%s", zBuf1, + sqlite3_snprintf(nSql*2, zBuf2, "%Q%s", zBuf1, pBest->t.z[pBest->t.n]=='\'' ? " " : "" ); zReplace = zBuf2; nReplace = sqlite3Strlen30(zReplace); } - iOff = (int)(pBest->t.z - zSql); + iOff = pBest->t.z - zSql; if( pBest->t.n!=nReplace ){ memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], nOut - (iOff + pBest->t.n) @@ -124792,12 +123876,11 @@ static int renameEditSql( ** Set all pEList->a[].fg.eEName fields in the expression-list to val. */ static void renameSetENames(ExprList *pEList, int val){ - assert( val==ENAME_NAME || val==ENAME_TAB || val==ENAME_SPAN ); if( pEList ){ int i; for(i=0; inExpr; i++){ assert( val==ENAME_NAME || pEList->a[i].fg.eEName==ENAME_NAME ); - pEList->a[i].fg.eEName = val&0x3; + pEList->a[i].fg.eEName = val; } } } @@ -125054,7 +124137,7 @@ static void renameColumnFunc( if( sParse.pNewTable ){ if( IsView(sParse.pNewTable) ){ Select *pSelect = sParse.pNewTable->u.view.pSelect; - pSelect->selFlags &= ~(u32)SF_View; + pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); @@ -125272,7 +124355,7 @@ static void renameTableFunc( sNC.pParse = &sParse; assert( pSelect->selFlags & SF_View ); - pSelect->selFlags &= ~(u32)SF_View; + pSelect->selFlags &= ~SF_View; sqlite3SelectPrep(&sParse, pTab->u.view.pSelect, &sNC); if( sParse.nErr ){ rc = sParse.rc; @@ -125445,7 +124528,7 @@ static void renameQuotefixFunc( if( sParse.pNewTable ){ if( IsView(sParse.pNewTable) ){ Select *pSelect = sParse.pNewTable->u.view.pSelect; - pSelect->selFlags &= ~(u32)SF_View; + pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); @@ -125544,10 +124627,10 @@ static void renameTableTest( if( zDb && zInput ){ int rc; Parse sParse; - u64 flags = db->flags; + int flags = db->flags; if( bNoDQS ) db->flags &= ~(SQLITE_DqsDML|SQLITE_DqsDDL); rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); - db->flags = flags; + db->flags |= (flags & (SQLITE_DqsDML|SQLITE_DqsDDL)); if( rc==SQLITE_OK ){ if( isLegacy==0 && sParse.pNewTable && IsView(sParse.pNewTable) ){ NameContext sNC; @@ -126039,8 +125122,7 @@ static void openStatTable( sqlite3NestedParse(pParse, "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols ); - assert( pParse->isCreate || pParse->nErr ); - aRoot[i] = (u32)pParse->u1.cr.regRoot; + aRoot[i] = (u32)pParse->regRoot; aCreateTbl[i] = OPFLAG_P2ISREG; } }else{ @@ -126231,7 +125313,7 @@ static void statInit( int nCol; /* Number of columns in index being sampled */ int nKeyCol; /* Number of key columns */ int nColUp; /* nCol rounded up for alignment */ - i64 n; /* Bytes of space to allocate */ + int n; /* Bytes of space to allocate */ sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */ #ifdef SQLITE_ENABLE_STAT4 /* Maximum number of samples. 0 if STAT4 data is not collected */ @@ -126267,7 +125349,7 @@ static void statInit( p->db = db; p->nEst = sqlite3_value_int64(argv[2]); p->nRow = 0; - p->nLimit = sqlite3_value_int(argv[3]); + p->nLimit = sqlite3_value_int64(argv[3]); p->nCol = nCol; p->nKeyCol = nKeyCol; p->nSkipAhead = 0; @@ -127400,6 +126482,16 @@ static void decodeIntArray( while( z[0]!=0 && z[0]!=' ' ) z++; while( z[0]==' ' ) z++; } + + /* Set the bLowQual flag if the peak number of rows obtained + ** from a full equality match is so large that a full table scan + ** seems likely to be faster than using the index. + */ + if( aLog[0] > 66 /* Index has more than 100 rows */ + && aLog[0] <= aLog[nOut-1] /* And only a single value seen */ + ){ + pIndex->bLowQual = 1; + } } } @@ -127995,7 +127087,7 @@ static void attachFunc( if( aNew==0 ) return; memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ - aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(1+(i64)db->nDb)); + aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); if( aNew==0 ) return; } db->aDb = aNew; @@ -128112,13 +127204,6 @@ static void attachFunc( sqlite3BtreeEnterAll(db); db->init.iDb = 0; db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - if( db->setlkFlags & SQLITE_SETLK_BLOCK_ON_CONNECT ){ - int val = 1; - sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pNew->pBt)); - sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, &val); - } -#endif if( !REOPEN_AS_MEMDB(db) ){ rc = sqlite3Init(db, &zErrDyn); } @@ -128841,7 +127926,6 @@ static SQLITE_NOINLINE void lockTable( } } - assert( pToplevel->nTableLock < 0x7fff0000 ); nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); pToplevel->aTableLock = sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); @@ -128942,12 +128026,10 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ if( pParse->bReturning ){ - Returning *pReturning; + Returning *pReturning = pParse->u1.pReturning; int addrRewind; int reg; - assert( !pParse->isCreate ); - pReturning = pParse->u1.d.pReturning; if( pReturning->nRetCol ){ sqlite3VdbeAddOp0(v, OP_FkCheck); addrRewind = @@ -129023,9 +128105,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ } if( pParse->bReturning ){ - Returning *pRet; - assert( !pParse->isCreate ); - pRet = pParse->u1.d.pReturning; + Returning *pRet = pParse->u1.pReturning; if( pRet->nRetCol ){ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); } @@ -129840,16 +128920,10 @@ SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){ ** find the (first) offset of that column in index pIdx. Or return -1 ** if column iCol is not used in index pIdx. */ -SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index *pIdx, int iCol){ +SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){ int i; - i16 iCol16; - assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN ); - assert( pIdx->nColumn<=SQLITE_MAX_COLUMN+1 ); - iCol16 = iCol; for(i=0; inColumn; i++){ - if( iCol16==pIdx->aiColumn[i] ){ - return i; - } + if( iCol==pIdx->aiColumn[i] ) return i; } return -1; } @@ -130103,9 +129177,8 @@ SQLITE_PRIVATE void sqlite3StartTable( /* If the file format and encoding in the database have not been set, ** set them now. */ - assert( pParse->isCreate ); - reg1 = pParse->u1.cr.regRowid = ++pParse->nMem; - reg2 = pParse->u1.cr.regRoot = ++pParse->nMem; + reg1 = pParse->regRowid = ++pParse->nMem; + reg2 = pParse->regRoot = ++pParse->nMem; reg3 = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); sqlite3VdbeUsesBtree(v, iDb); @@ -130120,8 +129193,8 @@ SQLITE_PRIVATE void sqlite3StartTable( ** The record created does not contain anything yet. It will be replaced ** by the real entry in code generated at sqlite3EndTable(). ** - ** The rowid for the new entry is left in register pParse->u1.cr.regRowid. - ** The root page of the new table is left in reg pParse->u1.cr.regRoot. + ** The rowid for the new entry is left in register pParse->regRowid. + ** The root page number of the new table is left in reg pParse->regRoot. ** The rowid and root page number values are needed by the code that ** sqlite3EndTable will generate. */ @@ -130132,7 +129205,7 @@ SQLITE_PRIVATE void sqlite3StartTable( #endif { assert( !pParse->bReturning ); - pParse->u1.cr.addrCrTab = + pParse->u1.addrCrTab = sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); } sqlite3OpenSchemaTable(pParse, iDb); @@ -130210,8 +129283,7 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ sqlite3ExprListDelete(db, pList); return; } - assert( !pParse->isCreate ); - pParse->u1.d.pReturning = pRet; + pParse->u1.pReturning = pRet; pRet->pParse = pParse; pRet->pReturnEL = pList; sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet); @@ -130253,6 +129325,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ char *zType; Column *pCol; sqlite3 *db = pParse->db; + u8 hName; Column *aNew; u8 eType = COLTYPE_CUSTOM; u8 szEst = 1; @@ -130306,10 +129379,13 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ memcpy(z, sName.z, sName.n); z[sName.n] = 0; sqlite3Dequote(z); - if( p->nCol && sqlite3ColumnIndex(p, z)>=0 ){ - sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); - sqlite3DbFree(db, z); - return; + hName = sqlite3StrIHash(z); + for(i=0; inCol; i++){ + if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zCnName)==0 ){ + sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); + sqlite3DbFree(db, z); + return; + } } aNew = sqlite3DbRealloc(db,p->aCol,((i64)p->nCol+1)*sizeof(p->aCol[0])); if( aNew==0 ){ @@ -130320,7 +129396,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zCnName = z; - pCol->hName = sqlite3StrIHash(z); + pCol->hName = hName; sqlite3ColumnPropertiesFromName(p, pCol); if( sType.n==0 ){ @@ -130344,14 +129420,9 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ pCol->affinity = sqlite3AffinityType(zType, pCol); pCol->colFlags |= COLFLAG_HASTYPE; } - if( p->nCol<=0xff ){ - u8 h = pCol->hName % sizeof(p->aHx); - p->aHx[h] = p->nCol; - } p->nCol++; p->nNVCol++; - assert( pParse->isCreate ); - pParse->u1.cr.constraintName.n = 0; + pParse->constraintName.n = 0; } /* @@ -130615,11 +129686,15 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey( assert( pCExpr!=0 ); sqlite3StringToId(pCExpr); if( pCExpr->op==TK_ID ){ + const char *zCName; assert( !ExprHasProperty(pCExpr, EP_IntValue) ); - iCol = sqlite3ColumnIndex(pTab, pCExpr->u.zToken); - if( iCol>=0 ){ - pCol = &pTab->aCol[iCol]; - makeColumnPartOfPrimaryKey(pParse, pCol); + zCName = pCExpr->u.zToken; + for(iCol=0; iColnCol; iCol++){ + if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zCnName)==0 ){ + pCol = &pTab->aCol[iCol]; + makeColumnPartOfPrimaryKey(pParse, pCol); + break; + } } } } @@ -130671,10 +129746,8 @@ SQLITE_PRIVATE void sqlite3AddCheckConstraint( && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt) ){ pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); - assert( pParse->isCreate ); - if( pParse->u1.cr.constraintName.n ){ - sqlite3ExprListSetName(pParse, pTab->pCheck, - &pParse->u1.cr.constraintName, 1); + if( pParse->constraintName.n ){ + sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); }else{ Token t; for(zStart++; sqlite3Isspace(zStart[0]); zStart++){} @@ -130869,8 +129942,7 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent){ ** from sqliteMalloc() and must be freed by the calling function. */ static char *createTableStmt(sqlite3 *db, Table *p){ - int i, k, len; - i64 n; + int i, k, n; char *zStmt; char *zSep, *zSep2, *zEnd; Column *pCol; @@ -130894,9 +129966,8 @@ static char *createTableStmt(sqlite3 *db, Table *p){ sqlite3OomFault(db); return 0; } - assert( n>14 && n<=0x7fffffff ); - memcpy(zStmt, "CREATE TABLE ", 13); - k = 13; + sqlite3_snprintf(n, zStmt, "CREATE TABLE "); + k = sqlite3Strlen30(zStmt); identPut(zStmt, &k, p->zName); zStmt[k++] = '('; for(pCol=p->aCol, i=0; inCol; i++, pCol++){ @@ -130908,15 +129979,13 @@ static char *createTableStmt(sqlite3 *db, Table *p){ /* SQLITE_AFF_REAL */ " REAL", /* SQLITE_AFF_FLEXNUM */ " NUM", }; + int len; const char *zType; - len = sqlite3Strlen30(zSep); - assert( k+lenzCnName); - assert( kaffinity-SQLITE_AFF_BLOB >= 0 ); assert( pCol->affinity-SQLITE_AFF_BLOB < ArraySize(azType) ); testcase( pCol->affinity==SQLITE_AFF_BLOB ); @@ -130931,14 +130000,11 @@ static char *createTableStmt(sqlite3 *db, Table *p){ assert( pCol->affinity==SQLITE_AFF_BLOB || pCol->affinity==SQLITE_AFF_FLEXNUM || pCol->affinity==sqlite3AffinityType(zType, 0) ); - assert( k+lennColumn>=N ) return SQLITE_OK; - db = pParse->db; - assert( N>0 ); - assert( N <= SQLITE_MAX_COLUMN*2 /* tag-20250221-1 */ ); - testcase( N==2*pParse->db->aLimit[SQLITE_LIMIT_COLUMN] ); assert( pIdx->isResized==0 ); - nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*(u64)N; + nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N; zExtra = sqlite3DbMallocZero(db, nByte); if( zExtra==0 ) return SQLITE_NOMEM_BKPT; memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn); @@ -130970,7 +130031,7 @@ static int resizeIndexObject(Parse *pParse, Index *pIdx, int N){ zExtra += sizeof(i16)*N; memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn); pIdx->aSortOrder = (u8*)zExtra; - pIdx->nColumn = (u16)N; /* See tag-20250221-1 above for proof of safety */ + pIdx->nColumn = N; pIdx->isResized = 1; return SQLITE_OK; } @@ -131136,9 +130197,9 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ ** into BTREE_BLOBKEY. */ assert( !pParse->bReturning ); - if( pParse->u1.cr.addrCrTab ){ + if( pParse->u1.addrCrTab ){ assert( v ); - sqlite3VdbeChangeP3(v, pParse->u1.cr.addrCrTab, BTREE_BLOBKEY); + sqlite3VdbeChangeP3(v, pParse->u1.addrCrTab, BTREE_BLOBKEY); } /* Locate the PRIMARY KEY index. Or, if this table was originally @@ -131224,14 +130285,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ pIdx->nColumn = pIdx->nKeyCol; continue; } - if( resizeIndexObject(pParse, pIdx, pIdx->nKeyCol+n) ) return; + if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return; for(i=0, j=pIdx->nKeyCol; inKeyCol, pPk, i) ){ testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); pIdx->aiColumn[j] = pPk->aiColumn[i]; pIdx->azColl[j] = pPk->azColl[i]; if( pPk->aSortOrder[i] ){ - /* See ticket https://sqlite.org/src/info/bba7b69f9849b5bf */ + /* See ticket https://www.sqlite.org/src/info/bba7b69f9849b5bf */ pIdx->bAscKeyBug = 1; } j++; @@ -131248,7 +130309,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( !hasColumn(pPk->aiColumn, nPk, i) && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) nExtra++; } - if( resizeIndexObject(pParse, pPk, nPk+nExtra) ) return; + if( resizeIndexObject(db, pPk, nPk+nExtra) ) return; for(i=0, j=nPk; inCol; i++){ if( !hasColumn(pPk->aiColumn, j, i) && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 @@ -131578,7 +130639,7 @@ SQLITE_PRIVATE void sqlite3EndTable( /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT ** statement to populate the new table. The root-page number for the - ** new table is in register pParse->u1.cr.regRoot. + ** new table is in register pParse->regRoot. ** ** Once the SELECT has been coded by sqlite3Select(), it is in a ** suitable state to query for the column names and types to be used @@ -131609,8 +130670,7 @@ SQLITE_PRIVATE void sqlite3EndTable( regRec = ++pParse->nMem; regRowid = ++pParse->nMem; sqlite3MayAbort(pParse); - assert( pParse->isCreate ); - sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->u1.cr.regRoot, iDb); + sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->regRoot, iDb); sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); addrTop = sqlite3VdbeCurrentAddr(v) + 1; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); @@ -131655,7 +130715,6 @@ SQLITE_PRIVATE void sqlite3EndTable( ** schema table. We just need to update that slot with all ** the information we've collected. */ - assert( pParse->isCreate ); sqlite3NestedParse(pParse, "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q" @@ -131664,9 +130723,9 @@ SQLITE_PRIVATE void sqlite3EndTable( zType, p->zName, p->zName, - pParse->u1.cr.regRoot, + pParse->regRoot, zStmt, - pParse->u1.cr.regRowid + pParse->regRowid ); sqlite3DbFree(db, zStmt); sqlite3ChangeCookie(pParse, iDb); @@ -132406,7 +131465,7 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( }else{ nCol = pFromCol->nExpr; } - nByte = SZ_FKEY(nCol) + pTo->n + 1; + nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1; if( pToCol ){ for(i=0; inExpr; i++){ nByte += sqlite3Strlen30(pToCol->a[i].zEName) + 1; @@ -132608,7 +131667,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables ** with DESC primary keys, since those indexes have there keys in ** a different order from the main table. - ** See ticket: https://sqlite.org/src/info/bba7b69f9849b5bf + ** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf */ sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx); } @@ -132632,14 +131691,13 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ */ SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( sqlite3 *db, /* Database connection */ - int nCol, /* Total number of columns in the index */ + i16 nCol, /* Total number of columns in the index */ int nExtra, /* Number of bytes of extra space to alloc */ char **ppExtra /* Pointer to the "extra" space */ ){ Index *p; /* Allocated index object */ - i64 nByte; /* Bytes of space for Index object + arrays */ + int nByte; /* Bytes of space for Index object + arrays */ - assert( nCol <= 2*db->aLimit[SQLITE_LIMIT_COLUMN] ); nByte = ROUND8(sizeof(Index)) + /* Index structure */ ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */ @@ -132652,9 +131710,8 @@ SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1); p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; p->aSortOrder = (u8*)pExtra; - assert( nCol>0 ); - p->nColumn = (u16)nCol; - p->nKeyCol = (u16)(nCol - 1); + p->nColumn = nCol; + p->nKeyCol = nCol - 1; *ppExtra = ((char*)p) + nByte; } return p; @@ -132992,6 +132049,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( assert( j<=0x7fff ); if( j<0 ){ j = pTab->iPKey; + pIndex->bIdxRowid = 1; }else{ if( pTab->aCol[j].notNull==0 ){ pIndex->uniqNotNull = 0; @@ -133465,11 +132523,12 @@ SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token * sqlite3 *db = pParse->db; int i; if( pList==0 ){ - pList = sqlite3DbMallocZero(db, SZ_IDLIST(1)); + pList = sqlite3DbMallocZero(db, sizeof(IdList) ); if( pList==0 ) return 0; }else{ IdList *pNew; - pNew = sqlite3DbRealloc(db, pList, SZ_IDLIST(pList->nId+1)); + pNew = sqlite3DbRealloc(db, pList, + sizeof(IdList) + pList->nId*sizeof(pList->a)); if( pNew==0 ){ sqlite3IdListDelete(db, pList); return 0; @@ -133568,7 +132627,8 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( return 0; } if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST; - pNew = sqlite3DbRealloc(db, pSrc, SZ_SRCLIST(nAlloc)); + pNew = sqlite3DbRealloc(db, pSrc, + sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); if( pNew==0 ){ assert( db->mallocFailed ); return 0; @@ -133643,7 +132703,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( assert( pParse->db!=0 ); db = pParse->db; if( pList==0 ){ - pList = sqlite3DbMallocRawNN(pParse->db, SZ_SRCLIST(1)); + pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) ); if( pList==0 ) return 0; pList->nAlloc = 1; pList->nSrc = 1; @@ -134529,9 +133589,10 @@ SQLITE_PRIVATE With *sqlite3WithAdd( } if( pWith ){ - pNew = sqlite3DbRealloc(db, pWith, SZ_WITH(pWith->nCte+1)); + sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); + pNew = sqlite3DbRealloc(db, pWith, nByte); }else{ - pNew = sqlite3DbMallocZero(db, SZ_WITH(1)); + pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); } assert( (pNew!=0 && zName!=0) || db->mallocFailed ); @@ -136505,6 +135566,11 @@ static void substrFunc( i64 p1, p2; assert( argc==3 || argc==2 ); + if( sqlite3_value_type(argv[1])==SQLITE_NULL + || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL) + ){ + return; + } p0type = sqlite3_value_type(argv[0]); p1 = sqlite3_value_int64(argv[1]); if( p0type==SQLITE_BLOB ){ @@ -136522,23 +135588,19 @@ static void substrFunc( } } } +#ifdef SQLITE_SUBSTR_COMPATIBILITY + /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as + ** as substr(X,1,N) - it returns the first N characters of X. This + ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8] + ** from 2009-02-02 for compatibility of applications that exploited the + ** old buggy behavior. */ + if( p1==0 ) p1 = 1; /* */ +#endif if( argc==3 ){ p2 = sqlite3_value_int64(argv[2]); - if( p2==0 && sqlite3_value_type(argv[2])==SQLITE_NULL ) return; }else{ p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; } - if( p1==0 ){ -#ifdef SQLITE_SUBSTR_COMPATIBILITY - /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as - ** as substr(X,1,N) - it returns the first N characters of X. This - ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8] - ** from 2009-02-02 for compatibility of applications that exploited the - ** old buggy behavior. */ - p1 = 1; /* */ -#endif - if( sqlite3_value_type(argv[1])==SQLITE_NULL ) return; - } if( p1<0 ){ p1 += len; if( p1<0 ){ @@ -137239,7 +136301,7 @@ static const char hexdigits[] = { ** Append to pStr text that is the SQL literal representation of the ** value contained in pValue. */ -SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue, int bEscape){ +SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ /* As currently implemented, the string must be initially empty. ** we might relax this requirement in the future, but that will ** require enhancements to the implementation. */ @@ -137287,7 +136349,7 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue, int } case SQLITE_TEXT: { const unsigned char *zArg = sqlite3_value_text(pValue); - sqlite3_str_appendf(pStr, bEscape ? "%#Q" : "%Q", zArg); + sqlite3_str_appendf(pStr, "%Q", zArg); break; } default: { @@ -137298,105 +136360,6 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue, int } } -/* -** Return true if z[] begins with N hexadecimal digits, and write -** a decoding of those digits into *pVal. Or return false if any -** one of the first N characters in z[] is not a hexadecimal digit. -*/ -static int isNHex(const char *z, int N, u32 *pVal){ - int i; - int v = 0; - for(i=0; i0 ){ - memmove(&zOut[j], &zIn[i], n); - j += n; - i += n; - } - if( zIn[i+1]=='\\' ){ - i += 2; - zOut[j++] = '\\'; - }else if( sqlite3Isxdigit(zIn[i+1]) ){ - if( !isNHex(&zIn[i+1], 4, &v) ) goto unistr_error; - i += 5; - j += sqlite3AppendOneUtf8Character(&zOut[j], v); - }else if( zIn[i+1]=='+' ){ - if( !isNHex(&zIn[i+2], 6, &v) ) goto unistr_error; - i += 8; - j += sqlite3AppendOneUtf8Character(&zOut[j], v); - }else if( zIn[i+1]=='u' ){ - if( !isNHex(&zIn[i+2], 4, &v) ) goto unistr_error; - i += 6; - j += sqlite3AppendOneUtf8Character(&zOut[j], v); - }else if( zIn[i+1]=='U' ){ - if( !isNHex(&zIn[i+2], 8, &v) ) goto unistr_error; - i += 10; - j += sqlite3AppendOneUtf8Character(&zOut[j], v); - }else{ - goto unistr_error; - } - } - zOut[j] = 0; - sqlite3_result_text64(context, zOut, j, sqlite3_free, SQLITE_UTF8); - return; - -unistr_error: - sqlite3_free(zOut); - sqlite3_result_error(context, "invalid Unicode escape", -1); - return; -} - - /* ** Implementation of the QUOTE() function. ** @@ -137406,10 +136369,6 @@ unistr_error: ** as needed. BLOBs are encoded as hexadecimal literals. Strings with ** embedded NUL characters cannot be represented as string literals in SQL ** and hence the returned string literal is truncated prior to the first NUL. -** -** If sqlite3_user_data() is non-zero, then the UNISTR_QUOTE() function is -** implemented instead. The difference is that UNISTR_QUOTE() uses the -** UNISTR() function to escape control characters. */ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ sqlite3_str str; @@ -137417,7 +136376,7 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ assert( argc==1 ); UNUSED_PARAMETER(argc); sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); - sqlite3QuoteValue(&str,argv[0],SQLITE_PTR_TO_INT(sqlite3_user_data(context))); + sqlite3QuoteValue(&str,argv[0]); sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar, SQLITE_DYNAMIC); if( str.accError!=SQLITE_OK ){ @@ -137672,7 +136631,7 @@ static void replaceFunc( assert( zRep==sqlite3_value_text(argv[2]) ); nOut = nStr + 1; assert( nOut0 ){ const char *v = (const char*)sqlite3_value_text(argv[i]); if( v!=0 ){ if( j>0 && nSep>0 ){ @@ -138068,7 +137027,7 @@ static void kahanBabuskaNeumaierInit( ** that it returns NULL if it sums over no inputs. TOTAL returns ** 0.0 in that case. In addition, TOTAL always returns a float where ** SUM might return an integer if it never encounters a floating point -** value. TOTAL never fails, but SUM might throw an exception if +** value. TOTAL never fails, but SUM might through an exception if ** it overflows an integer. */ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ @@ -138988,9 +137947,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ), DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), - FUNCTION(unistr, 1, 0, 0, unistrFunc ), FUNCTION(quote, 1, 0, 0, quoteFunc ), - FUNCTION(unistr_quote, 1, 1, 0, quoteFunc ), VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), VFUNCTION(changes, 0, 0, 0, changes ), VFUNCTION(total_changes, 0, 0, 0, total_changes ), @@ -141277,7 +140234,7 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList f = (f & pLeft->selFlags); } pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0); - pLeft->selFlags &= ~(u32)SF_MultiValue; + pLeft->selFlags &= ~SF_MultiValue; if( pSelect ){ pSelect->op = TK_ALL; pSelect->pPrior = pLeft; @@ -141659,22 +140616,28 @@ SQLITE_PRIVATE void sqlite3Insert( aTabColMap = sqlite3DbMallocZero(db, pTab->nCol*sizeof(int)); if( aTabColMap==0 ) goto insert_cleanup; for(i=0; inId; i++){ - j = sqlite3ColumnIndex(pTab, pColumn->a[i].zName); - if( j>=0 ){ - if( aTabColMap[j]==0 ) aTabColMap[j] = i+1; - if( i!=j ) bIdListInOrder = 0; - if( j==pTab->iPKey ){ - ipkColumn = i; assert( !withoutRowid ); - } + const char *zCName = pColumn->a[i].zName; + u8 hName = sqlite3StrIHash(zCName); + for(j=0; jnCol; j++){ + if( pTab->aCol[j].hName!=hName ) continue; + if( sqlite3StrICmp(zCName, pTab->aCol[j].zCnName)==0 ){ + if( aTabColMap[j]==0 ) aTabColMap[j] = i+1; + if( i!=j ) bIdListInOrder = 0; + if( j==pTab->iPKey ){ + ipkColumn = i; assert( !withoutRowid ); + } #ifndef SQLITE_OMIT_GENERATED_COLUMNS - if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ - sqlite3ErrorMsg(pParse, - "cannot INSERT into generated column \"%s\"", - pTab->aCol[j].zCnName); - goto insert_cleanup; - } + if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ + sqlite3ErrorMsg(pParse, + "cannot INSERT into generated column \"%s\"", + pTab->aCol[j].zCnName); + goto insert_cleanup; + } #endif - }else{ + break; + } + } + if( j>=pTab->nCol ){ if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ ipkColumn = i; bIdListInOrder = 0; @@ -141972,7 +140935,7 @@ SQLITE_PRIVATE void sqlite3Insert( continue; }else if( pColumn==0 ){ /* Hidden columns that are not explicitly named in the INSERT - ** get their default value */ + ** get there default value */ sqlite3ExprCodeFactorable(pParse, sqlite3ColumnExpr(pTab, &pTab->aCol[i]), iRegStore); @@ -142697,7 +141660,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** could happen in any order, but they are grouped up front for ** convenience. ** - ** 2018-08-14: Ticket https://sqlite.org/src/info/908f001483982c43 + ** 2018-08-14: Ticket https://www.sqlite.org/src/info/908f001483982c43 ** The order of constraints used to have OE_Update as (2) and OE_Abort ** and so forth as (1). But apparently PostgreSQL checks the OE_Update ** constraint before any others, so it had to be moved. @@ -144507,8 +143470,6 @@ struct sqlite3_api_routines { /* Version 3.44.0 and later */ void *(*get_clientdata)(sqlite3*,const char*); int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); - /* Version 3.50.0 and later */ - int (*setlk_timeout)(sqlite3*,int,int); }; /* @@ -144842,8 +143803,6 @@ typedef int (*sqlite3_loadext_entry)( /* Version 3.44.0 and later */ #define sqlite3_get_clientdata sqlite3_api->get_clientdata #define sqlite3_set_clientdata sqlite3_api->set_clientdata -/* Version 3.50.0 and later */ -#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -145365,9 +144324,7 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_stmt_explain, /* Version 3.44.0 and later */ sqlite3_get_clientdata, - sqlite3_set_clientdata, - /* Version 3.50.0 and later */ - sqlite3_setlk_timeout + sqlite3_set_clientdata }; /* True if x is the directory separator character @@ -145811,6 +144768,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ */ /* The various pragma types */ +#define PragTyp_KEY 255 #define PragTyp_ACTIVATE_EXTENSIONS 0 #define PragTyp_ANALYSIS_LIMIT 1 #define PragTyp_HEADER_VALUE 2 @@ -145855,9 +144813,8 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ #define PragTyp_THREADS 41 #define PragTyp_WAL_AUTOCHECKPOINT 42 #define PragTyp_WAL_CHECKPOINT 43 -#define PragTyp_KEY 44 -#define PragTyp_LOCK_STATUS 45 -#define PragTyp_STATS 46 +#define PragTyp_LOCK_STATUS 44 +#define PragTyp_STATS 45 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -146148,6 +145105,7 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, +/* BEGIN SQLCIPHER */ #if defined(SQLITE_HAS_CODEC) {/* zName: */ "hexkey", /* ePragTyp: */ PragTyp_KEY, @@ -146160,6 +145118,7 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 3 }, #endif +/* END SQLCIPHER */ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if !defined(SQLITE_OMIT_CHECK) {/* zName: */ "ignore_check_constraints", @@ -146212,6 +145171,7 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif +/* BEGIN SQLCIPHER */ #if defined(SQLITE_HAS_CODEC) {/* zName: */ "key", /* ePragTyp: */ PragTyp_KEY, @@ -146219,6 +145179,7 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif +/* END SQLCIPHER */ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "legacy_alter_table", /* ePragTyp: */ PragTyp_FLAG, @@ -146327,6 +145288,7 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ SQLITE_RecTriggers }, #endif +/* BEGIN SQLCIPHER */ #if defined(SQLITE_HAS_CODEC) {/* zName: */ "rekey", /* ePragTyp: */ PragTyp_KEY, @@ -146334,6 +145296,7 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 1 }, #endif +/* END SQLCIPHER */ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "reverse_unordered_selects", /* ePragTyp: */ PragTyp_FLAG, @@ -146424,6 +145387,7 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif +/* BEGIN SQLCIPHER */ #if defined(SQLITE_HAS_CODEC) {/* zName: */ "textkey", /* ePragTyp: */ PragTyp_KEY, @@ -146436,6 +145400,7 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 5 }, #endif +/* END SQLCIPHER */ {/* zName: */ "threads", /* ePragTyp: */ PragTyp_THREADS, /* ePragFlg: */ PragFlg_Result0, @@ -146504,7 +145469,7 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; -/* Number of pragmas: 68 on by default, 84 total. */ +/* Number of pragmas: 68 on by default, 78 total. */ /************** End of pragma.h **********************************************/ /************** Continuing where we left off in pragma.c *********************/ @@ -146515,7 +145480,7 @@ static const PragmaName aPragmaName[] = { ** the following macro or to the actual analysis_limit if it is non-zero, ** in order to prevent PRAGMA optimize from running for too long. ** -** The value of 2000 is chosen empirically so that the worst-case run-time +** The value of 2000 is chosen emperically so that the worst-case run-time ** for PRAGMA optimize does not exceed 100 milliseconds against a variety ** of test databases on a RaspberryPI-4 compiled using -Os and without ** -DSQLITE_DEBUG. Of course, your mileage may vary. For the purpose of @@ -147647,10 +146612,7 @@ SQLITE_PRIVATE void sqlite3Pragma( } }else{ db->flags &= ~mask; - if( mask==SQLITE_DeferFKs ){ - db->nDeferredImmCons = 0; - db->nDeferredCons = 0; - } + if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; if( (mask & SQLITE_WriteSchema)!=0 && sqlite3_stricmp(zRight, "reset")==0 ){ @@ -150868,7 +149830,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = 0; - if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); + if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc)); pNew->pSrc = pSrc; pNew->pWhere = pWhere; pNew->pGroupBy = pGroupBy; @@ -151033,33 +149995,10 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p */ SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ int i; - u8 h; - const Column *aCol; - int nCol; - - h = sqlite3StrIHash(zCol); - aCol = pTab->aCol; - nCol = pTab->nCol; - - /* See if the aHx gives us a lucky match */ - i = pTab->aHx[h % sizeof(pTab->aHx)]; - assert( i=nCol ) break; + u8 h = sqlite3StrIHash(zCol); + Column *pCol; + for(pCol=pTab->aCol, i=0; inCol; pCol++, i++){ + if( pCol->hName==h && sqlite3StrICmp(pCol->zCnName, zCol)==0 ) return i; } return -1; } @@ -151310,7 +150249,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ } pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); - if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 && pParse->nErr==0 ){ + if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ /* This branch runs if the query contains one or more RIGHT or FULL ** JOINs. If only a single table on the left side of this join ** contains the zName column, then this branch is a no-op. @@ -151326,8 +150265,6 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ */ ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ static const Token tkCoalesce = { "coalesce", 8 }; - assert( pE1!=0 ); - ExprSetProperty(pE1, EP_CanBeNull); while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, pRight->fg.isSynthUsing)!=0 ){ if( pSrc->a[iLeft].fg.isUsing==0 @@ -151344,13 +150281,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ if( pFuncArgs ){ pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); - if( pE1 ){ - pE1->affExpr = SQLITE_AFF_DEFER; - } } - }else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){ - assert( pE1!=0 ); - ExprSetProperty(pE1, EP_CanBeNull); } pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); sqlite3SrcItemColumnUsed(pRight, iRightCol); @@ -152259,8 +151190,8 @@ static void selectInnerLoop( ** X extra columns. */ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ - int nExtra = (N+X)*(sizeof(CollSeq*)+1); - KeyInfo *p = sqlite3DbMallocRawNN(db, SZ_KEYINFO(0) + nExtra); + int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*); + KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); if( p ){ p->aSortFlags = (u8*)&p->aColl[N+X]; p->nKeyField = (u16)N; @@ -152268,7 +151199,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ p->enc = ENC(db); p->db = db; p->nRef = 1; - memset(p->aColl, 0, nExtra); + memset(&p[1], 0, nExtra); }else{ return (KeyInfo*)sqlite3OomFault(db); } @@ -154958,9 +153889,9 @@ static int compoundHasDifferentAffinities(Select *p){ ** from 2015-02-09.) ** ** (3) If the subquery is the right operand of a LEFT JOIN then -** (3a) the subquery may not be a join -** (**) Was (3b): "the FROM clause of the subquery may not contain -** a virtual table" +** (3a) the subquery may not be a join and +** (3b) the FROM clause of the subquery may not contain a virtual +** table and ** (**) Was: "The outer query may not have a GROUP BY." This case ** is now managed correctly ** (3d) the outer query may not be DISTINCT. @@ -155176,7 +154107,7 @@ static int flattenSubquery( */ if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ if( pSubSrc->nSrc>1 /* (3a) */ - /**** || IsVirtual(pSubSrc->a[0].pSTab) (3b)-omitted */ + || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ || (p->selFlags & SF_Distinct)!=0 /* (3d) */ || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ ){ @@ -155580,8 +154511,7 @@ static void constInsert( return; /* Already present. Return without doing anything. */ } } - assert( SQLITE_AFF_NONEbHasAffBlob = 1; } @@ -155656,8 +154586,7 @@ static int propagateConstantExprRewriteOne( if( pColumn==pExpr ) continue; if( pColumn->iTable!=pExpr->iTable ) continue; if( pColumn->iColumn!=pExpr->iColumn ) continue; - assert( SQLITE_AFF_NONEpWinDefn = 0; #endif - p->selFlags &= ~(u32)SF_Compound; + p->selFlags &= ~SF_Compound; assert( (p->selFlags & SF_Converted)==0 ); p->selFlags |= SF_Converted; assert( pNew->pPrior!=0 ); @@ -156787,7 +155716,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pEList = p->pEList; if( pParse->pWith && (p->selFlags & SF_View) ){ if( p->pWith==0 ){ - p->pWith = (With*)sqlite3DbMallocZero(db, SZ_WITH(1) ); + p->pWith = (With*)sqlite3DbMallocZero(db, sizeof(With)); if( p->pWith==0 ){ return WRC_Abort; } @@ -157975,14 +156904,14 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ pExpr = 0; pSub = sqlite3SubqueryDetach(db, pFrom); sqlite3SrcListDelete(db, p->pSrc); - p->pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); + p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); while( pSub ){ Expr *pTerm; pPrior = pSub->pPrior; pSub->pPrior = 0; pSub->pNext = 0; pSub->selFlags |= SF_Aggregate; - pSub->selFlags &= ~(u32)SF_Compound; + pSub->selFlags &= ~SF_Compound; pSub->nSelectRow = 0; sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList); pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; @@ -157997,7 +156926,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ pSub = pPrior; } p->pEList->a[0].pExpr = pExpr; - p->selFlags &= ~(u32)SF_Aggregate; + p->selFlags &= ~SF_Aggregate; #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x200 ){ @@ -158204,7 +157133,7 @@ SQLITE_PRIVATE int sqlite3Select( testcase( pParse->earlyCleanup ); p->pOrderBy = 0; } - p->selFlags &= ~(u32)SF_Distinct; + p->selFlags &= ~SF_Distinct; p->selFlags |= SF_NoopOrderBy; } sqlite3SelectPrep(pParse, p, 0); @@ -158243,7 +157172,7 @@ SQLITE_PRIVATE int sqlite3Select( ** and leaving this flag set can cause errors if a compound sub-query ** in p->pSrc is flattened into this query and this function called ** again as part of compound SELECT processing. */ - p->selFlags &= ~(u32)SF_UFSrcCheck; + p->selFlags &= ~SF_UFSrcCheck; } if( pDest->eDest==SRT_Output ){ @@ -158732,7 +157661,7 @@ SQLITE_PRIVATE int sqlite3Select( && p->pWin==0 #endif ){ - p->selFlags &= ~(u32)SF_Distinct; + p->selFlags &= ~SF_Distinct; pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); if( pGroupBy ){ for(i=0; inExpr; i++){ @@ -158841,12 +157770,6 @@ SQLITE_PRIVATE int sqlite3Select( if( pWInfo==0 ) goto select_end; if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); - if( pDest->eDest<=SRT_DistQueue && pDest->eDest>=SRT_DistFifo ){ - /* TUNING: For a UNION CTE, because UNION is implies DISTINCT, - ** reduce the estimated output row count by 8 (LogEst 30). - ** Search for tag-20250414a to see other cases */ - p->nSelectRow -= 30; - } } if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); @@ -159077,7 +158000,6 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); VdbeComment((v, "clear abort flag")); sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); - sqlite3ExprNullRegisterRange(pParse, iAMem, pGroupBy->nExpr); /* Begin a loop that will extract all source rows in GROUP BY order. ** This might involve two separate loops with an OP_Sort in between, or @@ -159221,10 +158143,6 @@ SQLITE_PRIVATE int sqlite3Select( if( iOrderByCol ){ Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); - while( ALWAYS(pBase!=0) && pBase->op==TK_IF_NULL_ROW ){ - pX = pBase->pLeft; - pBase = sqlite3ExprSkipCollateAndLikely(pX); - } if( ALWAYS(pBase!=0) && pBase->op!=TK_AGG_COLUMN && pBase->op!=TK_REGISTER @@ -159808,8 +158726,7 @@ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ assert( pParse->db->pVtabCtx==0 ); #endif assert( pParse->bReturning ); - assert( !pParse->isCreate ); - assert( &(pParse->u1.d.pReturning->retTrig) == pTrig ); + assert( &(pParse->u1.pReturning->retTrig) == pTrig ); pTrig->table = pTab->zName; pTrig->pTabSchema = pTab->pSchema; pTrig->pNext = pList; @@ -160777,8 +159694,7 @@ static void codeReturningTrigger( ExprList *pNew; Returning *pReturning; Select sSelect; - SrcList *pFrom; - u8 fromSpace[SZ_SRCLIST_1]; + SrcList sFrom; assert( v!=0 ); if( !pParse->bReturning ){ @@ -160787,21 +159703,19 @@ static void codeReturningTrigger( return; } assert( db->pParse==pParse ); - assert( !pParse->isCreate ); - pReturning = pParse->u1.d.pReturning; + pReturning = pParse->u1.pReturning; if( pTrigger != &(pReturning->retTrig) ){ /* This RETURNING trigger is for a different statement */ return; } memset(&sSelect, 0, sizeof(sSelect)); - pFrom = (SrcList*)fromSpace; - memset(pFrom, 0, SZ_SRCLIST_1); + memset(&sFrom, 0, sizeof(sFrom)); sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); - sSelect.pSrc = pFrom; - pFrom->nSrc = 1; - pFrom->a[0].pSTab = pTab; - pFrom->a[0].zName = pTab->zName; /* tag-20240424-1 */ - pFrom->a[0].iCursor = -1; + sSelect.pSrc = &sFrom; + sFrom.nSrc = 1; + sFrom.a[0].pSTab = pTab; + sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ + sFrom.a[0].iCursor = -1; sqlite3SelectPrep(pParse, &sSelect, 0); if( pParse->nErr==0 ){ assert( db->mallocFailed==0 ); @@ -161019,8 +159933,6 @@ static TriggerPrg *codeRowTrigger( sSubParse.eTriggerOp = pTrigger->op; sSubParse.nQueryLoop = pParse->nQueryLoop; sSubParse.prepFlags = pParse->prepFlags; - sSubParse.oldmask = 0; - sSubParse.newmask = 0; v = sqlite3GetVdbe(&sSubParse); if( v ){ @@ -161775,32 +160687,38 @@ SQLITE_PRIVATE void sqlite3Update( */ chngRowid = chngPk = 0; for(i=0; inExpr; i++){ + u8 hCol = sqlite3StrIHash(pChanges->a[i].zEName); /* If this is an UPDATE with a FROM clause, do not resolve expressions ** here. The call to sqlite3Select() below will do that. */ if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){ goto update_cleanup; } - j = sqlite3ColumnIndex(pTab, pChanges->a[i].zEName); - if( j>=0 ){ - if( j==pTab->iPKey ){ - chngRowid = 1; - pRowidExpr = pChanges->a[i].pExpr; - iRowidExpr = i; - }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){ - chngPk = 1; - } + for(j=0; jnCol; j++){ + if( pTab->aCol[j].hName==hCol + && sqlite3StrICmp(pTab->aCol[j].zCnName, pChanges->a[i].zEName)==0 + ){ + if( j==pTab->iPKey ){ + chngRowid = 1; + pRowidExpr = pChanges->a[i].pExpr; + iRowidExpr = i; + }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){ + chngPk = 1; + } #ifndef SQLITE_OMIT_GENERATED_COLUMNS - else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){ - testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ); - testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); - sqlite3ErrorMsg(pParse, - "cannot UPDATE generated column \"%s\"", - pTab->aCol[j].zCnName); - goto update_cleanup; - } + else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); + sqlite3ErrorMsg(pParse, + "cannot UPDATE generated column \"%s\"", + pTab->aCol[j].zCnName); + goto update_cleanup; + } #endif - aXRef[j] = i; - }else{ + aXRef[j] = i; + break; + } + } + if( j>=pTab->nCol ){ if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zEName) ){ j = -1; chngRowid = 1; @@ -163123,7 +162041,7 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){ #else /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments ** to VACUUM are silently ignored. This is a back-out of a bug fix that - ** occurred on 2016-08-19 (https://sqlite.org/src/info/083f9e6270). + ** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270). ** The buggy behavior is required for binary compatibility with some ** legacy applications. */ iDb = sqlite3FindDb(pParse->db, pNm); @@ -163202,7 +162120,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( saved_nChange = db->nChange; saved_nTotalChange = db->nTotalChange; saved_mTrace = db->mTrace; - db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments; + db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_Defensive | SQLITE_CountRows); @@ -163922,12 +162840,11 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ ** schema table. We just need to update that slot with all ** the information we've collected. ** - ** The VM register number pParse->u1.cr.regRowid holds the rowid of an + ** The VM register number pParse->regRowid holds the rowid of an ** entry in the sqlite_schema table that was created for this vtab ** by sqlite3StartTable(). */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( pParse->isCreate ); sqlite3NestedParse(pParse, "UPDATE %Q." LEGACY_SCHEMA_TABLE " " "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " @@ -163936,7 +162853,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ pTab->zName, pTab->zName, zStmt, - pParse->u1.cr.regRowid + pParse->regRowid ); v = sqlite3GetVdbe(pParse); sqlite3ChangeCookie(pParse, iDb); @@ -165346,14 +164263,9 @@ struct WhereInfo { Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ WhereClause sWC; /* Decomposition of the WHERE clause */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ - WhereLevel a[FLEXARRAY]; /* Information about each nest loop in WHERE */ + WhereLevel a[1]; /* Information about each nest loop in WHERE */ }; -/* -** The size (in bytes) of a WhereInfo object that holds N WhereLevels. -*/ -#define SZ_WHEREINFO(N) ROUND8(offsetof(WhereInfo,a)+(N)*sizeof(WhereLevel)) - /* ** Private interfaces - callable only by other where.c routines. ** @@ -166033,7 +164945,7 @@ static void adjustOrderByCol(ExprList *pOrderBy, ExprList *pEList){ /* ** pX is an expression of the form: (vector) IN (SELECT ...) ** In other words, it is a vector IN operator with a SELECT clause on the -** RHS. But not all terms in the vector are indexable and the terms might +** LHS. But not all terms in the vector are indexable and the terms might ** not be in the correct order for indexing. ** ** This routine makes a copy of the input pX expression and then adjusts @@ -166089,9 +165001,7 @@ static Expr *removeUnindexableInClauseTerms( int iField; assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); iField = pLoop->aLTerm[i]->u.x.iField - 1; - if( NEVER(pOrigRhs->a[iField].pExpr==0) ){ - continue; /* Duplicate PK column */ - } + if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); pOrigRhs->a[iField].pExpr = 0; if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1; @@ -166188,7 +165098,7 @@ static SQLITE_NOINLINE void codeINTerm( return; } } - for(i=iEq; inLTerm; i++){ + for(i=iEq;inLTerm; i++){ assert( pLoop->aLTerm[i]!=0 ); if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; } @@ -166197,13 +165107,22 @@ static SQLITE_NOINLINE void codeINTerm( if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); }else{ - sqlite3 *db = pParse->db; - Expr *pXMod = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); - if( !db->mallocFailed ){ - aiMap = (int*)sqlite3DbMallocZero(db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pXMod, IN_INDEX_LOOP, 0, aiMap, &iTab); + Expr *pExpr = pTerm->pExpr; + if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ + sqlite3 *db = pParse->db; + pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); + if( !db->mallocFailed ){ + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); + pExpr->iTable = iTab; + } + sqlite3ExprDelete(db, pX); + }else{ + int n = sqlite3ExprVectorSize(pX->pLeft); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); } - sqlite3ExprDelete(db, pXMod); + pX = pExpr; } if( eType==IN_INDEX_INDEX_DESC ){ @@ -166233,7 +165152,7 @@ static SQLITE_NOINLINE void codeINTerm( if( pIn ){ int iMap = 0; /* Index in aiMap[] */ pIn += i; - for(i=iEq; inLTerm; i++){ + for(i=iEq;inLTerm; i++){ if( pLoop->aLTerm[i]->pExpr==pX ){ int iOut = iTarget + i - iEq; if( eType==IN_INDEX_ROWID ){ @@ -167092,9 +166011,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( } sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1); - /* The instruction immediately prior to OP_VFilter must be an OP_Integer - ** that sets the "argc" value for xVFilter. This is necessary for - ** resolveP2() to work correctly. See tag-20250207a. */ sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, pLoop->u.vtab.idxStr, pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC); @@ -167685,13 +166601,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( if( pLevel->iLeftJoin==0 ){ /* If a partial index is driving the loop, try to eliminate WHERE clause ** terms from the query that must be true due to the WHERE clause of - ** the partial index. This optimization does not work on an outer join, - ** as shown by: + ** the partial index. ** - ** 2019-11-02 ticket 623eff57e76d45f6 (LEFT JOIN) - ** 2025-05-29 forum post 7dee41d32506c4ae (RIGHT JOIN) + ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work + ** for a LEFT JOIN. */ - if( pIdx->pPartIdxWhere && pLevel->pRJ==0 ){ + if( pIdx->pPartIdxWhere ){ whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); } }else{ @@ -167798,7 +166713,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int nNotReady; /* The number of notReady tables */ SrcItem *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; - pOrTab = sqlite3DbMallocRawNN(db, SZ_SRCLIST(nNotReady+1)); + pOrTab = sqlite3DbMallocRawNN(db, + sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); if( pOrTab==0 ) return notReady; pOrTab->nAlloc = (u8)(nNotReady + 1); pOrTab->nSrc = pOrTab->nAlloc; @@ -167849,7 +166765,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** ** This optimization also only applies if the (x1 OR x2 OR ...) term ** is not contained in the ON clause of a LEFT JOIN. - ** See ticket http://sqlite.org/src/info/f2369304e4 + ** See ticket http://www.sqlite.org/src/info/f2369304e4 ** ** 2022-02-04: Do not push down slices of a row-value comparison. ** In other words, "w" or "y" may not be a slice of a vector. Otherwise, @@ -168341,8 +167257,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( WhereInfo *pSubWInfo; WhereLoop *pLoop = pLevel->pWLoop; SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; - SrcList *pFrom; - u8 fromSpace[SZ_SRCLIST_1]; + SrcList sFrom; Bitmask mAll = 0; int k; @@ -168386,14 +167301,13 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); } } - pFrom = (SrcList*)fromSpace; - pFrom->nSrc = 1; - pFrom->nAlloc = 1; - memcpy(&pFrom->a[0], pTabItem, sizeof(SrcItem)); - pFrom->a[0].fg.jointype = 0; + sFrom.nSrc = 1; + sFrom.nAlloc = 1; + memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); + sFrom.a[0].fg.jointype = 0; assert( pParse->withinRJSubrtn < 100 ); pParse->withinRJSubrtn++; - pSubWInfo = sqlite3WhereBegin(pParse, pFrom, pSubWhere, 0, 0, 0, + pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, WHERE_RIGHT_JOIN, 0); if( pSubWInfo ){ int iCur = pLevel->iTabCur; @@ -169364,42 +168278,30 @@ static void exprAnalyzeOrTerm( ** 1. The SQLITE_Transitive optimization must be enabled ** 2. Must be either an == or an IS operator ** 3. Not originating in the ON clause of an OUTER JOIN -** 4. The operator is not IS or else the query does not contain RIGHT JOIN -** 5. The affinities of A and B must be compatible -** 6a. Both operands use the same collating sequence OR -** 6b. The overall collating sequence is BINARY +** 4. The affinities of A and B must be compatible +** 5a. Both operands use the same collating sequence OR +** 5b. The overall collating sequence is BINARY ** If this routine returns TRUE, that means that the RHS can be substituted ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. ** This is an optimization. No harm comes from returning 0. But if 1 is ** returned when it should not be, then incorrect answers might result. */ -static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ +static int termIsEquivalence(Parse *pParse, Expr *pExpr){ char aff1, aff2; CollSeq *pColl; - if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ - if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ - if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ - assert( pSrc!=0 ); - if( pExpr->op==TK_IS - && pSrc->nSrc - && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 - ){ - return 0; /* (4) */ - } + if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; + if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; + if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; aff1 = sqlite3ExprAffinity(pExpr->pLeft); aff2 = sqlite3ExprAffinity(pExpr->pRight); if( aff1!=aff2 && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) ){ - return 0; /* (5) */ + return 0; } pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); - if( !sqlite3IsBinary(pColl) - && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) - ){ - return 0; /* (6) */ - } - return 1; + if( sqlite3IsBinary(pColl) ) return 1; + return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); } /* @@ -169664,8 +168566,8 @@ static void exprAnalyze( if( op==TK_IS ) pNew->wtFlags |= TERM_IS; pTerm = &pWC->a[idxTerm]; pTerm->wtFlags |= TERM_COPIED; - assert( pWInfo->pTabList!=0 ); - if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){ + + if( termIsEquivalence(pParse, pDup) ){ pTerm->eOperator |= WO_EQUIV; eExtraOp = WO_EQUIV; } @@ -170393,16 +169295,11 @@ struct HiddenIndexInfo { int eDistinct; /* Value to return from sqlite3_vtab_distinct() */ u32 mIn; /* Mask of terms that are IN (...) */ u32 mHandleIn; /* Terms that vtab will handle as IN (...) */ - sqlite3_value *aRhs[FLEXARRAY]; /* RHS values for constraints. MUST BE LAST - ** Extra space is allocated to hold up - ** to nTerm such values */ + sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST + ** because extra space is allocated to hold up + ** to nTerm such values */ }; -/* Size (in bytes) of a HiddenIndeInfo object sufficient to hold as -** many as N constraints */ -#define SZ_HIDDENINDEXINFO(N) \ - (offsetof(HiddenIndexInfo,aRhs) + (N)*sizeof(sqlite3_value*)) - /* Forward declaration of methods */ static int whereLoopResize(sqlite3*, WhereLoop*, int); @@ -171467,8 +170364,6 @@ static SQLITE_NOINLINE void constructAutomaticIndex( } /* Construct the Index object to describe this index */ - assert( nKeyCol <= pTable->nCol + MAX(0, pTable->nCol - BMS + 1) ); - /* ^-- This guarantees that the number of index columns will fit in the u16 */ pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+HasRowid(pTable), 0, &zNotUsed); if( pIdx==0 ) goto end_auto_index_create; @@ -171880,8 +170775,8 @@ static sqlite3_index_info *allocateIndexInfo( */ pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm - + sizeof(*pIdxOrderBy)*nOrderBy - + SZ_HIDDENINDEXINFO(nTerm) ); + + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) + + sizeof(sqlite3_value*)*nTerm ); if( pIdxInfo==0 ){ sqlite3ErrorMsg(pParse, "out of memory"); return 0; @@ -173517,8 +172412,11 @@ static int whereLoopAddBtreeIndex( assert( pNew->u.btree.nBtm==0 ); opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; } - if( pProbe->bUnordered ){ - opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + if( pProbe->bUnordered || pProbe->bLowQual ){ + if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + if( pProbe->bLowQual && pSrc->fg.isIndexedBy==0 ){ + opMask &= ~(WO_EQ|WO_IN|WO_IS); + } } assert( pNew->u.btree.nEqnColumn ); @@ -173591,7 +172489,6 @@ static int whereLoopAddBtreeIndex( if( ExprUseXSelect(pExpr) ){ /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ int i; - int bRedundant = 0; nIn = 46; assert( 46==sqlite3LogEst(25) ); /* The expression may actually be of the form (x, y) IN (SELECT...). @@ -173600,20 +172497,7 @@ static int whereLoopAddBtreeIndex( ** for each such term. The following loop checks that pTerm is the ** first such term in use, and sets nIn back to 0 if it is not. */ for(i=0; inLTerm-1; i++){ - if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ){ - nIn = 0; - if( pNew->aLTerm[i]->u.x.iField == pTerm->u.x.iField ){ - /* Detect when two or more columns of an index match the same - ** column of a vector IN operater, and avoid adding the column - ** to the WhereLoop more than once. See tag-20250707-01 - ** in test/rowvalue.test */ - bRedundant = 1; - } - } - } - if( bRedundant ){ - pNew->nLTerm--; - continue; + if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; } }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ /* "x IN (value, value, ...)" */ @@ -173845,7 +172729,7 @@ static int whereLoopAddBtreeIndex( if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 && pNew->u.btree.nEqnColumn && (pNew->u.btree.nEqnKeyCol || - pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) + (pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY && !pProbe->bIdxRowid)) ){ if( pNew->u.btree.nEq>3 ){ sqlite3ProgressCheck(pParse); @@ -173974,7 +172858,6 @@ static int whereUsablePartialIndex( if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) - && !sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, -1) && (pTerm->wtFlags & TERM_VNULL)==0 ){ return 1; @@ -174388,7 +173271,6 @@ static int whereLoopAddBtree( pNew->u.btree.nEq = 0; pNew->u.btree.nBtm = 0; pNew->u.btree.nTop = 0; - pNew->u.btree.nDistinctCol = 0; pNew->nSkip = 0; pNew->nLTerm = 0; pNew->iSortIdx = 0; @@ -174471,7 +173353,7 @@ static int whereLoopAddBtree( && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700)) ){ WHERETRACE(0x200, - ("-> %s is a covering index according to bitmasks\n", + ("-> %s a covering index according to bitmasks\n", pProbe->zName, m==0 ? "is" : "is not")); pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; } @@ -175457,6 +174339,8 @@ static i8 wherePathSatisfiesOrderBy( obSat = obDone; } break; + }else if( wctrlFlags & WHERE_DISTINCTBY ){ + pLoop->u.btree.nDistinctCol = 0; } iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; @@ -177086,7 +175970,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** field (type Bitmask) it must be aligned on an 8-byte boundary on ** some architectures. Hence the ROUND8() below. */ - nByteWInfo = SZ_WHEREINFO(nTabList); + nByteWInfo = ROUND8P(sizeof(WhereInfo)); + if( nTabList>1 ){ + nByteWInfo = ROUND8P(nByteWInfo + (nTabList-1)*sizeof(WhereLevel)); + } pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); if( db->mallocFailed ){ sqlite3DbFree(db, pWInfo); @@ -177303,8 +176190,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } /* TUNING: Assume that a DISTINCT clause on a subquery reduces - ** the output size by a factor of 8 (LogEst -30). Search for - ** tag-20250414a to see other cases. + ** the output size by a factor of 8 (LogEst -30). */ if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ WHERETRACE(0x0080,("nRowOut reduced from %d to %d due to DISTINCT\n", @@ -179039,7 +177925,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ p->pWhere = 0; p->pGroupBy = 0; p->pHaving = 0; - p->selFlags &= ~(u32)SF_Aggregate; + p->selFlags &= ~SF_Aggregate; p->selFlags |= SF_WinRewrite; /* Create the ORDER BY clause for the sub-select. This is the concatenation @@ -181179,11 +180065,6 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( /* #include "sqliteInt.h" */ -/* -** Verify that the pParse->isCreate field is set -*/ -#define ASSERT_IS_CREATE assert(pParse->isCreate) - /* ** Disable all error recovery processing in the parser push-down ** automaton. @@ -181247,10 +180128,6 @@ static void parserSyntaxError(Parse *pParse, Token *p){ static void disableLookaside(Parse *pParse){ sqlite3 *db = pParse->db; pParse->disableLookaside++; -#ifdef SQLITE_DEBUG - pParse->isCreate = 1; -#endif - memset(&pParse->u1.cr, 0, sizeof(pParse->u1.cr)); DisableLookaside; } @@ -184887,9 +183764,7 @@ static YYACTIONTYPE yy_reduce( } break; case 14: /* createkw ::= CREATE */ -{ - disableLookaside(pParse); -} +{disableLookaside(pParse);} break; case 15: /* ifnotexists ::= */ case 18: /* temp ::= */ yytestcase(yyruleno==18); @@ -184981,7 +183856,7 @@ static YYACTIONTYPE yy_reduce( break; case 32: /* ccons ::= CONSTRAINT nm */ case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67); -{ASSERT_IS_CREATE; pParse->u1.cr.constraintName = yymsp[0].minor.yy0;} +{pParse->constraintName = yymsp[0].minor.yy0;} break; case 33: /* ccons ::= DEFAULT scantok term */ {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy590,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} @@ -185091,7 +183966,7 @@ static YYACTIONTYPE yy_reduce( {yymsp[-1].minor.yy502 = 0;} break; case 66: /* tconscomma ::= COMMA */ -{ASSERT_IS_CREATE; pParse->u1.cr.constraintName.n = 0;} +{pParse->constraintName.n = 0;} break; case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ {sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy402,yymsp[0].minor.yy502,yymsp[-2].minor.yy502,0);} @@ -185178,8 +184053,8 @@ static YYACTIONTYPE yy_reduce( if( pRhs ){ pRhs->op = (u8)yymsp[-1].minor.yy502; pRhs->pPrior = pLhs; - if( ALWAYS(pLhs) ) pLhs->selFlags &= ~(u32)SF_MultiValue; - pRhs->selFlags &= ~(u32)SF_MultiValue; + if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; + pRhs->selFlags &= ~SF_MultiValue; if( yymsp[-1].minor.yy502!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); @@ -185819,21 +184694,12 @@ static YYACTIONTYPE yy_reduce( ** expr1 IN () ** expr1 NOT IN () ** - ** simplify to constants 0 (false) and 1 (true), respectively. - ** - ** Except, do not apply this optimization if expr1 contains a function - ** because that function might be an aggregate (we don't know yet whether - ** it is or not) and if it is an aggregate, that could change the meaning - ** of the whole query. + ** simplify to constants 0 (false) and 1 (true), respectively, + ** regardless of the value of expr1. */ - Expr *pB = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false"); - if( pB ) sqlite3ExprIdToTrueFalse(pB); - if( !ExprHasProperty(yymsp[-4].minor.yy590, EP_HasFunc) ){ - sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy590); - yymsp[-4].minor.yy590 = pB; - }else{ - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, yymsp[-3].minor.yy502 ? TK_OR : TK_AND, pB, yymsp[-4].minor.yy590); - } + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy590); + yymsp[-4].minor.yy590 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false"); + if( yymsp[-4].minor.yy590 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy590); }else{ Expr *pRHS = yymsp[-1].minor.yy402->a[0].pExpr; if( yymsp[-1].minor.yy402->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy590->op!=TK_VECTOR ){ @@ -185993,10 +184859,6 @@ static YYACTIONTYPE yy_reduce( { sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy502, yymsp[-4].minor.yy28.a, yymsp[-4].minor.yy28.b, yymsp[-2].minor.yy563, yymsp[0].minor.yy590, yymsp[-10].minor.yy502, yymsp[-8].minor.yy502); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ -#ifdef SQLITE_DEBUG - assert( pParse->isCreate ); /* Set by createkw reduce action */ - pParse->isCreate = 0; /* But, should not be set for CREATE TRIGGER */ -#endif } break; case 262: /* trigger_time ::= BEFORE|AFTER */ @@ -187439,7 +186301,7 @@ static int getToken(const unsigned char **pz){ int t; /* Token type to return */ do { z += sqlite3GetToken(z, &t); - }while( t==TK_SPACE || t==TK_COMMENT ); + }while( t==TK_SPACE ); if( t==TK_ID || t==TK_STRING || t==TK_JOIN_KW @@ -187932,11 +186794,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ assert( n==6 ); tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); #endif /* SQLITE_OMIT_WINDOWFUNC */ - }else if( tokenType==TK_COMMENT - && (db->init.busy || (db->flags & SQLITE_Comments)!=0) - ){ - /* Ignore SQL comments if either (1) we are reparsing the schema or - ** (2) SQLITE_DBCONFIG_ENABLE_COMMENTS is turned on (the default). */ + }else if( tokenType==TK_COMMENT && (db->flags & SQLITE_Comments)!=0 ){ zSql += n; continue; }else if( tokenType!=TK_QNUMBER ){ @@ -188831,14 +187689,6 @@ SQLITE_API int sqlite3_initialize(void){ if( rc==SQLITE_OK ){ sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); -#ifdef SQLITE_EXTRA_INIT_MUTEXED - { - int SQLITE_EXTRA_INIT_MUTEXED(const char*); - rc = SQLITE_EXTRA_INIT_MUTEXED(0); - } -#endif - } - if( rc==SQLITE_OK ){ sqlite3MemoryBarrier(); sqlite3GlobalConfig.isInit = 1; #ifdef SQLITE_EXTRA_INIT @@ -189295,22 +188145,17 @@ SQLITE_API int sqlite3_config(int op, ...){ ** If lookaside is already active, return SQLITE_BUSY. ** ** The sz parameter is the number of bytes in each lookaside slot. -** The cnt parameter is the number of slots. If pBuf is NULL the -** space for the lookaside memory is obtained from sqlite3_malloc() -** or similar. If pBuf is not NULL then it is sz*cnt bytes of memory -** to use for the lookaside memory. +** The cnt parameter is the number of slots. If pStart is NULL the +** space for the lookaside memory is obtained from sqlite3_malloc(). +** If pStart is not NULL then it is sz*cnt bytes of memory to use for +** the lookaside memory. */ -static int setupLookaside( - sqlite3 *db, /* Database connection being configured */ - void *pBuf, /* Memory to use for lookaside. May be NULL */ - int sz, /* Desired size of each lookaside memory slot */ - int cnt /* Number of slots to allocate */ -){ +static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ #ifndef SQLITE_OMIT_LOOKASIDE - void *pStart; /* Start of the lookaside buffer */ - sqlite3_int64 szAlloc; /* Total space set aside for lookaside memory */ - int nBig; /* Number of full-size slots */ - int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */ + void *pStart; + sqlite3_int64 szAlloc; + int nBig; /* Number of full-size slots */ + int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */ if( sqlite3LookasideUsed(db,0)>0 ){ return SQLITE_BUSY; @@ -189323,22 +188168,19 @@ static int setupLookaside( sqlite3_free(db->lookaside.pStart); } /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger - ** than a pointer and small enough to fit in a u16. + ** than a pointer to be useful. */ - sz = ROUNDDOWN8(sz); + sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; if( sz>65528 ) sz = 65528; - /* Count must be at least 1 to be useful, but not so large as to use - ** more than 0x7fff0000 total bytes for lookaside. */ - if( cnt<1 ) cnt = 0; - if( sz>0 && cnt>(0x7fff0000/sz) ) cnt = 0x7fff0000/sz; + if( cnt<0 ) cnt = 0; szAlloc = (i64)sz*(i64)cnt; - if( szAlloc==0 ){ + if( sz==0 || cnt==0 ){ sz = 0; pStart = 0; }else if( pBuf==0 ){ sqlite3BeginBenignMalloc(); - pStart = sqlite3Malloc( szAlloc ); + pStart = sqlite3Malloc( szAlloc ); /* IMP: R-61949-35727 */ sqlite3EndBenignMalloc(); if( pStart ) szAlloc = sqlite3MallocSize(pStart); }else{ @@ -190315,9 +189157,6 @@ SQLITE_API int sqlite3_busy_handler( db->busyHandler.pBusyArg = pArg; db->busyHandler.nBusy = 0; db->busyTimeout = 0; -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - db->setlkTimeout = 0; -#endif sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -190367,49 +189206,12 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, (void*)db); db->busyTimeout = ms; -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - db->setlkTimeout = ms; -#endif }else{ sqlite3_busy_handler(db, 0, 0); } return SQLITE_OK; } -/* -** Set the setlk timeout value. -*/ -SQLITE_API int sqlite3_setlk_timeout(sqlite3 *db, int ms, int flags){ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - int iDb; - int bBOC = ((flags & SQLITE_SETLK_BLOCK_ON_CONNECT) ? 1 : 0); -#endif -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - if( ms<-1 ) return SQLITE_RANGE; -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - sqlite3_mutex_enter(db->mutex); - db->setlkTimeout = ms; - db->setlkFlags = flags; - sqlite3BtreeEnterAll(db); - for(iDb=0; iDbnDb; iDb++){ - Btree *pBt = db->aDb[iDb].pBt; - if( pBt ){ - sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); - sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); - } - } - sqlite3BtreeLeaveAll(db); - sqlite3_mutex_leave(db->mutex); -#endif -#if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) - UNUSED_PARAMETER(db); - UNUSED_PARAMETER(flags); -#endif - return SQLITE_OK; -} - /* ** Cause any pending operation to stop at its earliest opportunity. */ @@ -192417,7 +191219,7 @@ SQLITE_API int sqlite3_set_clientdata( return SQLITE_OK; }else{ size_t n = strlen(zName); - p = sqlite3_malloc64( SZ_DBCLIENTDATA(n+1) ); + p = sqlite3_malloc64( sizeof(DbClientData)+n+1 ); if( p==0 ){ if( xDestructor ) xDestructor(pData); sqlite3_mutex_leave(db->mutex); @@ -192571,10 +191373,13 @@ SQLITE_API int sqlite3_table_column_metadata( if( zColumnName==0 ){ /* Query for existence of table only */ }else{ - iCol = sqlite3ColumnIndex(pTab, zColumnName); - if( iCol>=0 ){ + for(iCol=0; iColnCol; iCol++){ pCol = &pTab->aCol[iCol]; - }else{ + if( 0==sqlite3StrICmp(pCol->zCnName, zColumnName) ){ + break; + } + } + if( iCol==pTab->nCol ){ if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){ iCol = pTab->iPKey; pCol = iCol>=0 ? &pTab->aCol[iCol] : 0; @@ -192783,8 +191588,8 @@ SQLITE_API int sqlite3_test_control(int op, ...){ /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); ** ** If b is true, then activate the SQLITE_FkNoAction setting. If b is - ** false then clear that setting. If the SQLITE_FkNoAction setting is - ** enabled, all foreign key ON DELETE and ON UPDATE actions behave as if + ** false then clearn that setting. If the SQLITE_FkNoAction setting is + ** abled, all foreign key ON DELETE and ON UPDATE actions behave as if ** they were NO ACTION, regardless of how they are defined. ** ** NB: One must usually run "PRAGMA writable_schema=RESET" after @@ -194131,7 +192936,7 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ ** Here, array { X } means zero or more occurrences of X, adjacent in ** memory. A "position" is an index of a token in the token stream ** generated by the tokenizer. Note that POS_END and POS_COLUMN occur -** in the same logical place as the position element, and act as sentinels +** in the same logical place as the position element, and act as sentinals ** ending a position list array. POS_END is 0. POS_COLUMN is 1. ** The positions numbers are not stored literally but rather as two more ** than the difference from the prior position, or the just the position plus @@ -194350,13 +193155,6 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ #ifndef _FTSINT_H #define _FTSINT_H -/* #include */ -/* #include */ -/* #include */ -/* #include */ -/* #include */ -/* #include */ - #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) # define NDEBUG 1 #endif @@ -194826,19 +193624,6 @@ typedef sqlite3_int64 i64; /* 8-byte signed integer */ #define deliberate_fall_through -/* -** Macros needed to provide flexible arrays in a portable way -*/ -#ifndef offsetof -# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define FLEXARRAY -#else -# define FLEXARRAY 1 -#endif - - #endif /* SQLITE_AMALGAMATION */ #ifdef SQLITE_DEBUG @@ -194943,7 +193728,7 @@ struct Fts3Table { #endif #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - /* True to disable the incremental doclist optimization. This is controlled + /* True to disable the incremental doclist optimization. This is controled ** by special insert command 'test-no-incr-doclist'. */ int bNoIncrDoclist; @@ -194995,7 +193780,7 @@ struct Fts3Cursor { /* ** The Fts3Cursor.eSearch member is always set to one of the following. -** Actually, Fts3Cursor.eSearch can be greater than or equal to +** Actualy, Fts3Cursor.eSearch can be greater than or equal to ** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index ** of the column to be searched. For example, in ** @@ -195068,13 +193853,9 @@ struct Fts3Phrase { */ int nToken; /* Number of tokens in the phrase */ int iColumn; /* Index of column this phrase must match */ - Fts3PhraseToken aToken[FLEXARRAY]; /* One for each token in the phrase */ + Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */ }; -/* Size (in bytes) of an Fts3Phrase object large enough to hold N tokens */ -#define SZ_FTS3PHRASE(N) \ - (offsetof(Fts3Phrase,aToken)+(N)*sizeof(Fts3PhraseToken)) - /* ** A tree of these objects forms the RHS of a MATCH operator. ** @@ -195308,6 +194089,12 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk); # define SQLITE_CORE 1 #endif +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ /* #include "fts3.h" */ #ifndef SQLITE_CORE @@ -197646,7 +196433,7 @@ static int fts3DoclistOrMerge( ** sizes of the two inputs, plus enough space for exactly one of the input ** docids to grow. ** - ** A symmetric argument may be made if the doclists are in descending + ** A symetric argument may be made if the doclists are in descending ** order. */ aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING); @@ -199445,7 +198232,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ nDistance = iPrev - nMaxUndeferred; } - aOut = (char *)sqlite3Fts3MallocZero(((i64)nPoslist)+FTS3_BUFFER_PADDING); + aOut = (char *)sqlite3Fts3MallocZero(nPoslist+FTS3_BUFFER_PADDING); if( !aOut ){ sqlite3_free(aPoslist); return SQLITE_NOMEM; @@ -199744,7 +198531,7 @@ static int incrPhraseTokenNext( ** ** * does not contain any deferred tokens. ** -** Advance it to the next matching document in the database and populate +** Advance it to the next matching documnent in the database and populate ** the Fts3Doclist.pList and nList fields. ** ** If there is no "next" entry and no error occurs, then *pbEof is set to @@ -200751,7 +199538,7 @@ static int fts3EvalNext(Fts3Cursor *pCsr){ } /* -** Restart iteration for expression pExpr so that the next call to +** Restart interation for expression pExpr so that the next call to ** fts3EvalNext() visits the first row. Do not allow incremental ** loading or merging of phrase doclists for this iteration. ** @@ -201943,23 +200730,6 @@ SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer( */ static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); -/* -** Search buffer z[], size n, for a '"' character. Or, if enable_parenthesis -** is defined, search for '(' and ')' as well. Return the index of the first -** such character in the buffer. If there is no such character, return -1. -*/ -static int findBarredChar(const char *z, int n){ - int ii; - for(ii=0; iiiLangid, z, n, &pCursor); + /* Set variable i to the maximum number of bytes of input to tokenize. */ + for(i=0; iiLangid, z, i, &pCursor); if( rc==SQLITE_OK ){ const char *zToken; int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; @@ -201994,18 +200771,7 @@ static int getNextToken( rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); if( rc==SQLITE_OK ){ - /* Check that this tokenization did not gobble up any " characters. Or, - ** if enable_parenthesis is true, that it did not gobble up any - ** open or close parenthesis characters either. If it did, call - ** getNextToken() again, but pass only that part of the input buffer - ** up to the first such character. */ - int iBarred = findBarredChar(z, iEnd); - if( iBarred>=0 ){ - pModule->xClose(pCursor); - return getNextToken(pParse, iCol, z, iBarred, ppExpr, pnConsumed); - } - - nByte = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1) + nToken; + nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte); if( !pRet ){ rc = SQLITE_NOMEM; @@ -202015,7 +200781,7 @@ static int getNextToken( pRet->pPhrase->nToken = 1; pRet->pPhrase->iColumn = iCol; pRet->pPhrase->aToken[0].n = nToken; - pRet->pPhrase->aToken[0].z = (char*)&pRet->pPhrase->aToken[1]; + pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1]; memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken); if( iEnd=0 ){ - *pnConsumed = iBarred; - } + }else if( i && rc==SQLITE_DONE ){ rc = SQLITE_OK; } @@ -202090,9 +200852,9 @@ static int getNextString( Fts3Expr *p = 0; sqlite3_tokenizer_cursor *pCursor = 0; char *zTemp = 0; - i64 nTemp = 0; + int nTemp = 0; - const int nSpace = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1); + const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase); int nToken = 0; /* The final Fts3Expr data structure, including the Fts3Phrase, @@ -202464,7 +201226,7 @@ static int fts3ExprParse( /* The isRequirePhrase variable is set to true if a phrase or ** an expression contained in parenthesis is required. If a - ** binary operator (AND, OR, NOT or NEAR) is encountered when + ** binary operator (AND, OR, NOT or NEAR) is encounted when ** isRequirePhrase is set, this is a syntax error. */ if( !isPhrase && isRequirePhrase ){ @@ -203046,6 +201808,7 @@ static void fts3ExprTestCommon( } if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ + sqlite3Fts3ExprFree(pExpr); sqlite3_result_error(context, "Error parsing expression", -1); }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){ sqlite3_result_error_nomem(context); @@ -203288,7 +202051,7 @@ static void fts3HashInsertElement( } -/* Resize the hash table so that it contains "new_size" buckets. +/* Resize the hash table so that it cantains "new_size" buckets. ** "new_size" must be a power of 2. The hash table might fail ** to resize if sqliteMalloc() fails. ** @@ -203743,7 +202506,7 @@ static int star_oh(const char *z){ /* ** If the word ends with zFrom and xCond() is true for the stem -** of the word that precedes the zFrom ending, then change the +** of the word that preceeds the zFrom ending, then change the ** ending to zTo. ** ** The input word *pz and zFrom are both in reverse order. zTo @@ -205254,7 +204017,7 @@ static int fts3tokFilterMethod( fts3tokResetCursor(pCsr); if( idxNum==1 ){ const char *zByte = (const char *)sqlite3_value_text(apVal[0]); - sqlite3_int64 nByte = sqlite3_value_bytes(apVal[0]); + int nByte = sqlite3_value_bytes(apVal[0]); pCsr->zInput = sqlite3_malloc64(nByte+1); if( pCsr->zInput==0 ){ rc = SQLITE_NOMEM; @@ -209326,7 +208089,7 @@ static int fts3IncrmergePush( ** ** It is assumed that the buffer associated with pNode is already large ** enough to accommodate the new entry. The buffer associated with pPrev -** is extended by this function if required. +** is extended by this function if requrired. ** ** If an error (i.e. OOM condition) occurs, an SQLite error code is ** returned. Otherwise, SQLITE_OK. @@ -210989,7 +209752,7 @@ SQLITE_PRIVATE int sqlite3Fts3DeferToken( /* ** SQLite value pRowid contains the rowid of a row that may or may not be ** present in the FTS3 table. If it is, delete it and adjust the contents -** of subsidiary data structures accordingly. +** of subsiduary data structures accordingly. */ static int fts3DeleteByRowid( Fts3Table *p, @@ -211315,13 +210078,9 @@ struct MatchinfoBuffer { int nElem; int bGlobal; /* Set if global data is loaded */ char *zMatchinfo; - u32 aMI[FLEXARRAY]; + u32 aMatchinfo[1]; }; -/* Size (in bytes) of a MatchinfoBuffer sufficient for N elements */ -#define SZ_MATCHINFOBUFFER(N) \ - (offsetof(MatchinfoBuffer,aMI)+(((N)+1)/2)*sizeof(u64)) - /* ** The snippet() and offsets() functions both return text values. An instance @@ -211346,13 +210105,13 @@ struct StrBuffer { static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ MatchinfoBuffer *pRet; sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) - + SZ_MATCHINFOBUFFER(1); + + sizeof(MatchinfoBuffer); sqlite3_int64 nStr = strlen(zMatchinfo); pRet = sqlite3Fts3MallocZero(nByte + nStr+1); if( pRet ){ - pRet->aMI[0] = (u8*)(&pRet->aMI[1]) - (u8*)pRet; - pRet->aMI[1+nElem] = pRet->aMI[0] + pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet; + pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*((int)nElem+1); pRet->nElem = (int)nElem; pRet->zMatchinfo = ((char*)pRet) + nByte; @@ -211366,10 +210125,10 @@ static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ static void fts3MIBufferFree(void *p){ MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]); - assert( (u32*)p==&pBuf->aMI[1] - || (u32*)p==&pBuf->aMI[pBuf->nElem+2] + assert( (u32*)p==&pBuf->aMatchinfo[1] + || (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2] ); - if( (u32*)p==&pBuf->aMI[1] ){ + if( (u32*)p==&pBuf->aMatchinfo[1] ){ pBuf->aRef[1] = 0; }else{ pBuf->aRef[2] = 0; @@ -211386,18 +210145,18 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){ if( p->aRef[1]==0 ){ p->aRef[1] = 1; - aOut = &p->aMI[1]; + aOut = &p->aMatchinfo[1]; xRet = fts3MIBufferFree; } else if( p->aRef[2]==0 ){ p->aRef[2] = 1; - aOut = &p->aMI[p->nElem+2]; + aOut = &p->aMatchinfo[p->nElem+2]; xRet = fts3MIBufferFree; }else{ aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32)); if( aOut ){ xRet = sqlite3_free; - if( p->bGlobal ) memcpy(aOut, &p->aMI[1], p->nElem*sizeof(u32)); + if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32)); } } @@ -211407,7 +210166,7 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){ static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){ p->bGlobal = 1; - memcpy(&p->aMI[2+p->nElem], &p->aMI[1], p->nElem*sizeof(u32)); + memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32)); } /* @@ -211822,7 +210581,7 @@ static int fts3StringAppend( } /* If there is insufficient space allocated at StrBuffer.z, use realloc() - ** to grow the buffer until so that it is big enough to accommodate the + ** to grow the buffer until so that it is big enough to accomadate the ** appended data. */ if( pStr->n+nAppend+1>=pStr->nAlloc ){ @@ -212234,16 +210993,16 @@ static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ break; case FTS3_MATCHINFO_LHITS: - nVal = (size_t)pInfo->nCol * pInfo->nPhrase; + nVal = pInfo->nCol * pInfo->nPhrase; break; case FTS3_MATCHINFO_LHITS_BM: - nVal = (size_t)pInfo->nPhrase * ((pInfo->nCol + 31) / 32); + nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32); break; default: assert( cArg==FTS3_MATCHINFO_HITS ); - nVal = (size_t)pInfo->nCol * pInfo->nPhrase * 3; + nVal = pInfo->nCol * pInfo->nPhrase * 3; break; } @@ -213801,8 +212560,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** Beginning with version 3.45.0 (circa 2024-01-01), these routines also ** accept BLOB values that have JSON encoded using a binary representation ** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk -** format for SQLite-JSONB is completely different and incompatible with -** PostgreSQL-JSONB. +** format SQLite JSONB is completely different and incompatible with +** PostgreSQL JSONB. ** ** Decoding and interpreting JSONB is still O(N) where N is the size of ** the input, the same as text JSON. However, the constant of proportionality @@ -213859,7 +212618,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** ** The payload size need not be expressed in its minimal form. For example, ** if the payload size is 10, the size can be expressed in any of 5 different -** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by one 0x0a byte, +** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by on 0x0a byte, ** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by ** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and ** a single byte of 0x0a. The shorter forms are preferred, of course, but @@ -213869,7 +212628,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** the size when it becomes known, resulting in a non-minimal encoding. ** ** The value (X>>4)==15 is not actually used in the current implementation -** (as SQLite is currently unable to handle BLOBs larger than about 2GB) +** (as SQLite is currently unable handle BLOBs larger than about 2GB) ** but is included in the design to allow for future enhancements. ** ** The payload follows the header. NULL, TRUE, and FALSE have no payload and @@ -213929,47 +212688,23 @@ static const char * const jsonbType[] = { ** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). */ static const char jsonIsSpace[] = { -#ifdef SQLITE_ASCII -/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */ -#endif -#ifdef SQLITE_EBCDIC -/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */ -#endif + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #define jsonIsspace(x) (jsonIsSpace[(unsigned char)x]) @@ -213977,13 +212712,7 @@ static const char jsonIsSpace[] = { ** The set of all space characters recognized by jsonIsspace(). ** Useful as the second argument to strspn(). */ -#ifdef SQLITE_ASCII static const char jsonSpaces[] = "\011\012\015\040"; -#endif -#ifdef SQLITE_EBCDIC -static const char jsonSpaces[] = "\005\045\015\100"; -#endif - /* ** Characters that are special to JSON. Control characters, @@ -213992,46 +212721,23 @@ static const char jsonSpaces[] = "\005\045\015\100"; ** it in the set of special characters. */ static const char jsonIsOk[256] = { -#ifdef SQLITE_ASCII -/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ - 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 5 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */ -#endif -#ifdef SQLITE_EBCDIC -/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ - 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 3 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, /* 7 */ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */ -#endif + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; /* Objects */ @@ -214176,7 +212882,7 @@ struct JsonParse { ** Forward references **************************************************************************/ static void jsonReturnStringAsBlob(JsonString*); -static int jsonArgIsJsonb(sqlite3_value *pJson, JsonParse *p); +static int jsonFuncArgMightBeBinary(sqlite3_value *pJson); static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); static void jsonReturnParse(sqlite3_context*,JsonParse*); static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); @@ -214250,7 +212956,7 @@ static int jsonCacheInsert( ** most-recently used entry if it isn't so already. ** ** The JsonParse object returned still belongs to the Cache and might -** be deleted at any moment. If the caller wants the JsonParse to +** be deleted at any moment. If the caller whants the JsonParse to ** linger, it needs to increment the nPJRef reference counter. */ static JsonParse *jsonCacheSearch( @@ -214594,9 +213300,11 @@ static void jsonAppendSqlValue( break; } default: { - JsonParse px; - memset(&px, 0, sizeof(px)); - if( jsonArgIsJsonb(pValue, &px) ){ + if( jsonFuncArgMightBeBinary(pValue) ){ + JsonParse px; + memset(&px, 0, sizeof(px)); + px.aBlob = (u8*)sqlite3_value_blob(pValue); + px.nBlob = sqlite3_value_bytes(pValue); jsonTranslateBlobToText(&px, 0, p); }else if( p->eErr==0 ){ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); @@ -214915,7 +213623,7 @@ static void jsonWrongNumArgs( */ static int jsonBlobExpand(JsonParse *pParse, u32 N){ u8 *aNew; - u64 t; + u32 t; assert( N>pParse->nBlobAlloc ); if( pParse->nBlobAlloc==0 ){ t = 100; @@ -214925,9 +213633,8 @@ static int jsonBlobExpand(JsonParse *pParse, u32 N){ if( tdb, pParse->aBlob, t); if( aNew==0 ){ pParse->oom = 1; return 1; } - assert( t<0x7fffffff ); pParse->aBlob = aNew; - pParse->nBlobAlloc = (u32)t; + pParse->nBlobAlloc = t; return 0; } @@ -214994,7 +213701,7 @@ static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( } -/* Append a node type byte together with the payload size and +/* Append an node type byte together with the payload size and ** possibly also the payload. ** ** If aPayload is not NULL, then it is a pointer to the payload which @@ -215063,10 +213770,8 @@ static int jsonBlobChangePayloadSize( nExtra = 1; }else if( szType==13 ){ nExtra = 2; - }else if( szType==14 ){ - nExtra = 4; }else{ - nExtra = 8; + nExtra = 4; } if( szPayload<=11 ){ nNeeded = 0; @@ -215536,12 +214241,7 @@ json_parse_restart: || c=='n' || c=='r' || c=='t' || (c=='u' && jsonIs4Hex(&z[j+1])) ){ if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ; - }else if( c=='\'' || c=='v' || c=='\n' -#ifdef SQLITE_BUG_COMPATIBLE_20250510 - || (c=='0') /* Legacy bug compatible */ -#else - || (c=='0' && !sqlite3Isdigit(z[j+1])) /* Correct implementation */ -#endif + }else if( c=='\'' || c=='0' || c=='v' || c=='\n' || (0xe2==(u8)c && 0x80==(u8)z[j+1] && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) || (c=='x' && jsonIs2Hex(&z[j+1])) ){ @@ -215891,7 +214591,10 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ u8 x; u32 sz; u32 n; - assert( i<=pParse->nBlob ); + if( NEVER(i>pParse->nBlob) ){ + *pSz = 0; + return 0; + } x = pParse->aBlob[i]>>4; if( x<=11 ){ sz = x; @@ -215928,15 +214631,15 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ *pSz = 0; return 0; } - sz = ((u32)pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + + sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; n = 9; } if( (i64)i+sz+n > pParse->nBlob && (i64)i+sz+n > pParse->nBlob-pParse->delta ){ - *pSz = 0; - return 0; + sz = 0; + n = 0; } *pSz = sz; return n; @@ -216033,12 +214736,9 @@ static u32 jsonTranslateBlobToText( } case JSONB_TEXT: case JSONB_TEXTJ: { - if( pOut->nUsed+sz+2<=pOut->nAlloc || jsonStringGrow(pOut, sz+2)==0 ){ - pOut->zBuf[pOut->nUsed] = '"'; - memcpy(pOut->zBuf+pOut->nUsed+1,(const char*)&pParse->aBlob[i+n],sz); - pOut->zBuf[pOut->nUsed+sz+1] = '"'; - pOut->nUsed += sz+2; - } + jsonAppendChar(pOut, '"'); + jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); + jsonAppendChar(pOut, '"'); break; } case JSONB_TEXT5: { @@ -216277,6 +214977,33 @@ static u32 jsonTranslateBlobToPrettyText( return i; } + +/* Return true if the input pJson +** +** For performance reasons, this routine does not do a detailed check of the +** input BLOB to ensure that it is well-formed. Hence, false positives are +** possible. False negatives should never occur, however. +*/ +static int jsonFuncArgMightBeBinary(sqlite3_value *pJson){ + u32 sz, n; + const u8 *aBlob; + int nBlob; + JsonParse s; + if( sqlite3_value_type(pJson)!=SQLITE_BLOB ) return 0; + aBlob = sqlite3_value_blob(pJson); + nBlob = sqlite3_value_bytes(pJson); + if( nBlob<1 ) return 0; + if( NEVER(aBlob==0) || (aBlob[0] & 0x0f)>JSONB_OBJECT ) return 0; + memset(&s, 0, sizeof(s)); + s.aBlob = (u8*)aBlob; + s.nBlob = nBlob; + n = jsonbPayloadSize(&s, 0, &sz); + if( n==0 ) return 0; + if( sz+n!=(u32)nBlob ) return 0; + if( (aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0 ) return 0; + return sz+n==(u32)nBlob; +} + /* ** Given that a JSONB_ARRAY object starts at offset i, return ** the number of entries in that array. @@ -216309,82 +215036,6 @@ static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){ pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz); } -/* -** If the JSONB at aIns[0..nIns-1] can be expanded (by denormalizing the -** size field) by d bytes, then write the expansion into aOut[] and -** return true. In this way, an overwrite happens without changing the -** size of the JSONB, which reduces memcpy() operations and also make it -** faster and easier to update the B-Tree entry that contains the JSONB -** in the database. -** -** If the expansion of aIns[] by d bytes cannot be (easily) accomplished -** then return false. -** -** The d parameter is guaranteed to be between 1 and 8. -** -** This routine is an optimization. A correct answer is obtained if it -** always leaves the output unchanged and returns false. -*/ -static int jsonBlobOverwrite( - u8 *aOut, /* Overwrite here */ - const u8 *aIns, /* New content */ - u32 nIns, /* Bytes of new content */ - u32 d /* Need to expand new content by this much */ -){ - u32 szPayload; /* Bytes of payload */ - u32 i; /* New header size, after expansion & a loop counter */ - u8 szHdr; /* Size of header before expansion */ - - /* Lookup table for finding the upper 4 bits of the first byte of the - ** expanded aIns[], based on the size of the expanded aIns[] header: - ** - ** 2 3 4 5 6 7 8 9 */ - static const u8 aType[] = { 0xc0, 0xd0, 0, 0xe0, 0, 0, 0, 0xf0 }; - - if( (aIns[0]&0x0f)<=2 ) return 0; /* Cannot enlarge NULL, true, false */ - switch( aIns[0]>>4 ){ - default: { /* aIns[] header size 1 */ - if( ((1<=2 && i<=9 && aType[i-2]!=0 ); - aOut[0] = (aIns[0] & 0x0f) | aType[i-2]; - memcpy(&aOut[i], &aIns[szHdr], nIns-szHdr); - szPayload = nIns - szHdr; - while( 1/*edit-by-break*/ ){ - i--; - aOut[i] = szPayload & 0xff; - if( i==1 ) break; - szPayload >>= 8; - } - assert( (szPayload>>8)==0 ); - return 1; -} - /* ** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of ** content beginning at iDel, and replacing them with nIns bytes of @@ -216406,11 +215057,6 @@ static void jsonBlobEdit( u32 nIns /* Bytes of content to insert */ ){ i64 d = (i64)nIns - (i64)nDel; - if( d<0 && d>=(-8) && aIns!=0 - && jsonBlobOverwrite(&pParse->aBlob[iDel], aIns, nIns, (int)-d) - ){ - return; - } if( d!=0 ){ if( pParse->nBlob + d > pParse->nBlobAlloc ){ jsonBlobExpand(pParse, pParse->nBlob+d); @@ -216422,9 +215068,7 @@ static void jsonBlobEdit( pParse->nBlob += d; pParse->delta += d; } - if( nIns && aIns ){ - memcpy(&pParse->aBlob[iDel], aIns, nIns); - } + if( nIns && aIns ) memcpy(&pParse->aBlob[iDel], aIns, nIns); } /* @@ -216509,21 +215153,7 @@ static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){ case 'r': { *piOut = '\r'; return 2; } case 't': { *piOut = '\t'; return 2; } case 'v': { *piOut = '\v'; return 2; } - case '0': { - /* JSON5 requires that the \0 escape not be followed by a digit. - ** But SQLite did not enforce this restriction in versions 3.42.0 - ** through 3.49.2. That was a bug. But some applications might have - ** come to depend on that bug. Use the SQLITE_BUG_COMPATIBLE_20250510 - ** option to restore the old buggy behavior. */ -#ifdef SQLITE_BUG_COMPATIBLE_20250510 - /* Legacy bug-compatible behavior */ - *piOut = 0; -#else - /* Correct behavior */ - *piOut = (n>2 && sqlite3Isdigit(z[2])) ? JSON_INVALID_CHAR : 0; -#endif - return 2; - } + case '0': { *piOut = 0; return 2; } case '\'': case '"': case '/': @@ -217023,7 +215653,7 @@ static void jsonReturnFromBlob( char *zOut; u32 nOut = sz; z = (const char*)&pParse->aBlob[i+n]; - zOut = sqlite3DbMallocRaw(db, ((u64)nOut)+1); + zOut = sqlite3DbMallocRaw(db, nOut+1); if( zOut==0 ) goto returnfromblob_oom; for(iIn=iOut=0; iInaBlob = (u8*)sqlite3_value_blob(pArg); + pParse->nBlob = sqlite3_value_bytes(pArg); + }else{ sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1); return 1; } @@ -217198,7 +215831,7 @@ static char *jsonBadPathError( } /* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent -** arguments come in pairs where each pair contains a JSON path and +** arguments come in parse where each pair contains a JSON path and ** content to insert or set at that patch. Do the updates ** and return the result. ** @@ -217269,46 +215902,27 @@ jsonInsertIntoBlob_patherror: /* ** If pArg is a blob that seems like a JSONB blob, then initialize ** p to point to that JSONB and return TRUE. If pArg does not seem like -** a JSONB blob, then return FALSE. +** a JSONB blob, then return FALSE; ** -** For small BLOBs (having no more than 7 bytes of payload) a full -** validity check is done. So for small BLOBs this routine only returns -** true if the value is guaranteed to be a valid JSONB. For larger BLOBs -** (8 byte or more of payload) only the size of the outermost element is -** checked to verify that the BLOB is superficially valid JSONB. -** -** A full JSONB validation is done on smaller BLOBs because those BLOBs might -** also be text JSON that has been incorrectly cast into a BLOB. -** (See tag-20240123-a and https://sqlite.org/forum/forumpost/012136abd5) -** If the BLOB is 9 bytes are larger, then it is not possible for the -** superficial size check done here to pass if the input is really text -** JSON so we do not need to look deeper in that case. -** -** Why we only need to do full JSONB validation for smaller BLOBs: -** -** The first byte of valid JSON text must be one of: '{', '[', '"', ' ', '\n', -** '\r', '\t', '-', or a digit '0' through '9'. Of these, only a subset -** can also be the first byte of JSONB: '{', '[', and digits '3' -** through '9'. In every one of those cases, the payload size is 7 bytes -** or less. So if we do full JSONB validation for every BLOB where the -** payload is less than 7 bytes, we will never get a false positive for -** JSONB on an input that is really text JSON. +** This routine is only called if it is already known that pArg is a +** blob. The only open question is whether or not the blob appears +** to be a JSONB blob. */ static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){ u32 n, sz = 0; - u8 c; - if( sqlite3_value_type(pArg)!=SQLITE_BLOB ) return 0; p->aBlob = (u8*)sqlite3_value_blob(pArg); p->nBlob = (u32)sqlite3_value_bytes(pArg); - if( p->nBlob>0 - && ALWAYS(p->aBlob!=0) - && ((c = p->aBlob[0]) & 0x0f)<=JSONB_OBJECT + if( p->nBlob==0 ){ + p->aBlob = 0; + return 0; + } + if( NEVER(p->aBlob==0) ){ + return 0; + } + if( (p->aBlob[0] & 0x0f)<=JSONB_OBJECT && (n = jsonbPayloadSize(p, 0, &sz))>0 && sz+n==p->nBlob - && ((c & 0x0f)>JSONB_FALSE || sz==0) - && (sz>7 - || (c!=0x7b && c!=0x5b && !sqlite3Isdigit(c)) - || jsonbValidityCheck(p, 0, p->nBlob, 1)==0) + && ((p->aBlob[0] & 0x0f)>JSONB_FALSE || sz==0) ){ return 1; } @@ -217386,7 +216000,7 @@ rebuild_from_cache: ** JSON functions were suppose to work. From the beginning, blob was ** reserved for expansion and a blob value should have raised an error. ** But it did not, due to a bug. And many applications came to depend - ** upon this buggy behavior, especially when using the CLI and reading + ** upon this buggy behavior, espeically when using the CLI and reading ** JSON text using readfile(), which returns a blob. For this reason ** we will continue to support the bug moving forward. ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d @@ -218401,17 +217015,21 @@ static void jsonValidFunc( return; } case SQLITE_BLOB: { - JsonParse py; - memset(&py, 0, sizeof(py)); - if( jsonArgIsJsonb(argv[0], &py) ){ + if( jsonFuncArgMightBeBinary(argv[0]) ){ if( flags & 0x04 ){ /* Superficial checking only - accomplished by the - ** jsonArgIsJsonb() call above. */ + ** jsonFuncArgMightBeBinary() call above. */ res = 1; }else if( flags & 0x08 ){ /* Strict checking. Check by translating BLOB->TEXT->BLOB. If ** no errors occur, call that a "strict check". */ - res = 0==jsonbValidityCheck(&py, 0, py.nBlob, 1); + JsonParse px; + u32 iErr; + memset(&px, 0, sizeof(px)); + px.aBlob = (u8*)sqlite3_value_blob(argv[0]); + px.nBlob = sqlite3_value_bytes(argv[0]); + iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1); + res = iErr==0; } break; } @@ -218469,7 +217087,9 @@ static void jsonErrorFunc( UNUSED_PARAMETER(argc); memset(&s, 0, sizeof(s)); s.db = sqlite3_context_db_handle(ctx); - if( jsonArgIsJsonb(argv[0], &s) ){ + if( jsonFuncArgMightBeBinary(argv[0]) ){ + s.aBlob = (u8*)sqlite3_value_blob(argv[0]); + s.nBlob = sqlite3_value_bytes(argv[0]); iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1); }else{ s.zJson = (char*)sqlite3_value_text(argv[0]); @@ -218630,20 +217250,18 @@ static void jsonObjectStep( UNUSED_PARAMETER(argc); pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ - z = (const char*)sqlite3_value_text(argv[0]); - n = sqlite3Strlen30(z); if( pStr->zBuf==0 ){ jsonStringInit(pStr, ctx); jsonAppendChar(pStr, '{'); - }else if( pStr->nUsed>1 && z!=0 ){ + }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); } pStr->pCtx = ctx; - if( z!=0 ){ - jsonAppendString(pStr, z, n); - jsonAppendChar(pStr, ':'); - jsonAppendSqlValue(pStr, argv[1]); - } + z = (const char*)sqlite3_value_text(argv[0]); + n = sqlite3Strlen30(z); + jsonAppendString(pStr, z, n); + jsonAppendChar(pStr, ':'); + jsonAppendSqlValue(pStr, argv[1]); } } static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ @@ -219156,8 +217774,9 @@ static int jsonEachFilter( memset(&p->sParse, 0, sizeof(p->sParse)); p->sParse.nJPRef = 1; p->sParse.db = p->db; - if( jsonArgIsJsonb(argv[0], &p->sParse) ){ - /* We have JSONB */ + if( jsonFuncArgMightBeBinary(argv[0]) ){ + p->sParse.nBlob = sqlite3_value_bytes(argv[0]); + p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]); }else{ p->sParse.zJson = (char*)sqlite3_value_text(argv[0]); p->sParse.nJson = sqlite3_value_bytes(argv[0]); @@ -219451,8 +218070,6 @@ SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3 *db){ #endif SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ -/* #include */ - /* ** If building separately, we will need some setup that is normally ** found in sqliteInt.h @@ -219483,14 +218100,6 @@ typedef unsigned int u32; # define ALWAYS(X) (X) # define NEVER(X) (X) #endif -#ifndef offsetof -#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define FLEXARRAY -#else -# define FLEXARRAY 1 -#endif #endif /* !defined(SQLITE_AMALGAMATION) */ /* Macro to check for 4-byte alignment. Only used inside of assert() */ @@ -219811,13 +218420,9 @@ struct RtreeMatchArg { RtreeGeomCallback cb; /* Info about the callback functions */ int nParam; /* Number of parameters to the SQL function */ sqlite3_value **apSqlParam; /* Original SQL parameter values */ - RtreeDValue aParam[FLEXARRAY]; /* Values for parameters to the SQL function */ + RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ }; -/* Size of an RtreeMatchArg object with N parameters */ -#define SZ_RTREEMATCHARG(N) \ - (offsetof(RtreeMatchArg,aParam)+(N)*sizeof(RtreeDValue)) - #ifndef MAX # define MAX(x,y) ((x) < (y) ? (y) : (x)) #endif @@ -221506,7 +220111,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ } /* -** Return the N-dimensional volume of the cell stored in *p. +** Return the N-dimensional volumn of the cell stored in *p. */ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ RtreeDValue area = (RtreeDValue)1; @@ -223272,7 +221877,7 @@ static sqlite3_stmt *rtreeCheckPrepare( /* ** The second and subsequent arguments to this function are a printf() ** style format string and arguments. This function formats the string and -** appends it to the report being accumulated in pCheck. +** appends it to the report being accumuated in pCheck. */ static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ va_list ap; @@ -224460,7 +223065,7 @@ static void geopolyBBoxFinal( ** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). ** Returns: ** -** +2 x0,y0 is on the line segment +** +2 x0,y0 is on the line segement ** ** +1 x0,y0 is beneath line segment ** @@ -224566,7 +223171,7 @@ static void geopolyWithinFunc( sqlite3_free(p2); } -/* Objects used by the overlap algorithm. */ +/* Objects used by the overlap algorihm. */ typedef struct GeoEvent GeoEvent; typedef struct GeoSegment GeoSegment; typedef struct GeoOverlap GeoOverlap; @@ -225613,7 +224218,8 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ sqlite3_int64 nBlob; int memErr = 0; - nBlob = SZ_RTREEMATCHARG(nArg) + nArg*sizeof(sqlite3_value*); + nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue) + + nArg*sizeof(sqlite3_value*); pBlob = (RtreeMatchArg *)sqlite3_malloc64(nBlob); if( !pBlob ){ sqlite3_result_error_nomem(ctx); @@ -226708,7 +225314,7 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( ** ** "RBU" stands for "Resumable Bulk Update". As in a large database update ** transmitted via a wireless network to a mobile device. A transaction -** applied using this extension is hence referred to as an "RBU update". +** applied using this extension is hence refered to as an "RBU update". ** ** ** LIMITATIONS @@ -227005,7 +225611,7 @@ SQLITE_API sqlite3rbu *sqlite3rbu_open( ** the next call to sqlite3rbu_vacuum() opens a handle that starts a ** new RBU vacuum operation. ** -** As with sqlite3rbu_open(), Zipvfs users should refer to the comment +** As with sqlite3rbu_open(), Zipvfs users should rever to the comment ** describing the sqlite3rbu_create_vfs() API function below for ** a description of the complications associated with using RBU with ** zipvfs databases. @@ -227101,7 +225707,7 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu); ** ** If the RBU update has been completely applied, mark the RBU database ** as fully applied. Otherwise, assuming no error has occurred, save the -** current state of the RBU update application to the RBU database. +** current state of the RBU update appliation to the RBU database. ** ** If an error has already occurred as part of an sqlite3rbu_step() ** or sqlite3rbu_open() call, or if one occurs within this function, an @@ -232027,7 +230633,7 @@ static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ /* If this is an RBU vacuum operation and this is the target database, ** pretend that it has at least one page. Otherwise, SQLite will not - ** check for the existence of a *-wal file. rbuVfsRead() contains + ** check for the existance of a *-wal file. rbuVfsRead() contains ** similar logic. */ if( rc==SQLITE_OK && *pSize==0 && p->pRbu && rbuIsVacuum(p->pRbu) @@ -233959,8 +232565,8 @@ static int dbpageUpdate( /* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and ** all subsequent pages to be deleted. */ pTab->iDbTrunc = iDb; - pTab->pgnoTrunc = pgno-1; - pgno = 1; + pgno--; + pTab->pgnoTrunc = pgno; }else{ zErr = "bad page value"; goto update_fail; @@ -235257,7 +233863,7 @@ static int sessionTableInfo( /* ** This function is called to initialize the SessionTable.nCol, azCol[] ** abPK[] and azDflt[] members of SessionTable object pTab. If these -** fields are already initialized, this function is a no-op. +** fields are already initilialized, this function is a no-op. ** ** If an error occurs, an error code is stored in sqlite3_session.rc and ** non-zero returned. Or, if no error occurs but the table has no primary @@ -235276,8 +233882,6 @@ static int sessionInitTable( if( pTab->nCol==0 ){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); - sqlite3_free(pTab->azCol); - pTab->abPK = 0; rc = sessionTableInfo(pSession, db, zDb, pTab->zName, &pTab->nCol, &pTab->nTotalCol, 0, &pTab->azCol, &pTab->azDflt, &pTab->aiIdx, &abPK, @@ -236285,9 +234889,7 @@ SQLITE_API int sqlite3session_diff( SessionTable *pTo; /* Table zTbl */ /* Locate and if necessary initialize the target table object */ - pSession->bAutoAttach++; rc = sessionFindTable(pSession, zTbl, &pTo); - pSession->bAutoAttach--; if( pTo==0 ) goto diff_out; if( sessionInitTable(pSession, pTo, pSession->db, pSession->zDb) ){ rc = pSession->rc; @@ -236298,43 +234900,17 @@ SQLITE_API int sqlite3session_diff( if( rc==SQLITE_OK ){ int bHasPk = 0; int bMismatch = 0; - int nCol = 0; /* Columns in zFrom.zTbl */ + int nCol; /* Columns in zFrom.zTbl */ int bRowid = 0; - u8 *abPK = 0; + u8 *abPK; const char **azCol = 0; - char *zDbExists = 0; - - /* Check that database zFrom is attached. */ - zDbExists = sqlite3_mprintf("SELECT * FROM %Q.sqlite_schema", zFrom); - if( zDbExists==0 ){ - rc = SQLITE_NOMEM; - }else{ - sqlite3_stmt *pDbExists = 0; - rc = sqlite3_prepare_v2(db, zDbExists, -1, &pDbExists, 0); - if( rc==SQLITE_ERROR ){ - rc = SQLITE_OK; - nCol = -1; - } - sqlite3_finalize(pDbExists); - sqlite3_free(zDbExists); - } - - if( rc==SQLITE_OK && nCol==0 ){ - rc = sessionTableInfo(0, db, zFrom, zTbl, - &nCol, 0, 0, &azCol, 0, 0, &abPK, - pSession->bImplicitPK ? &bRowid : 0 - ); - } + rc = sessionTableInfo(0, db, zFrom, zTbl, + &nCol, 0, 0, &azCol, 0, 0, &abPK, + pSession->bImplicitPK ? &bRowid : 0 + ); if( rc==SQLITE_OK ){ if( pTo->nCol!=nCol ){ - if( nCol<=0 ){ - rc = SQLITE_SCHEMA; - if( pzErrMsg ){ - *pzErrMsg = sqlite3_mprintf("no such table: %s.%s", zFrom, zTbl); - } - }else{ - bMismatch = 1; - } + bMismatch = 1; }else{ int i; for(i=0; idb; /* Source database handle */ SessionTable *pTab; /* Used to iterate through attached tables */ - SessionBuffer buf = {0,0,0}; /* Buffer in which to accumulate changeset */ + SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */ int rc; /* Return code */ assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0) ); @@ -237463,15 +236039,14 @@ SQLITE_API int sqlite3changeset_start_v2_strm( ** object and the buffer is full, discard some data to free up space. */ static void sessionDiscardData(SessionInput *pIn){ - if( pIn->xInput && pIn->iCurrent>=sessions_strm_chunk_size ){ - int nMove = pIn->buf.nBuf - pIn->iCurrent; + if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){ + int nMove = pIn->buf.nBuf - pIn->iNext; assert( nMove>=0 ); if( nMove>0 ){ - memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iCurrent], nMove); + memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); } - pIn->buf.nBuf -= pIn->iCurrent; - pIn->iNext -= pIn->iCurrent; - pIn->iCurrent = 0; + pIn->buf.nBuf -= pIn->iNext; + pIn->iNext = 0; pIn->nData = pIn->buf.nBuf; } } @@ -237825,8 +236400,8 @@ static int sessionChangesetNextOne( p->rc = sessionInputBuffer(&p->in, 2); if( p->rc!=SQLITE_OK ) return p->rc; - p->in.iCurrent = p->in.iNext; sessionDiscardData(&p->in); + p->in.iCurrent = p->in.iNext; /* If the iterator is already at the end of the changeset, return DONE. */ if( p->in.iNext>=p->in.nData ){ @@ -240185,19 +238760,14 @@ SQLITE_API int sqlite3changegroup_add_change( sqlite3_changegroup *pGrp, sqlite3_changeset_iter *pIter ){ - int rc = SQLITE_OK; - if( pIter->in.iCurrent==pIter->in.iNext || pIter->rc!=SQLITE_OK || pIter->bInvert ){ /* Iterator does not point to any valid entry or is an INVERT iterator. */ - rc = SQLITE_ERROR; - }else{ - pIter->in.bNoDiscard = 1; - rc = sessionOneChangeToHash(pGrp, pIter, 0); + return SQLITE_ERROR; } - return rc; + return sessionOneChangeToHash(pGrp, pIter, 0); } /* @@ -241495,7 +240065,6 @@ SQLITE_EXTENSION_INIT1 /* #include */ /* #include */ -/* #include */ #ifndef SQLITE_AMALGAMATION @@ -241551,18 +240120,6 @@ typedef sqlite3_uint64 u64; # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) #endif -/* -** Macros needed to provide flexible arrays in a portable way -*/ -#ifndef offsetof -# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define FLEXARRAY -#else -# define FLEXARRAY 1 -#endif - #endif /* Truncate very long tokens to this many bytes. Hard limit is @@ -241635,11 +240192,10 @@ typedef struct Fts5Colset Fts5Colset; */ struct Fts5Colset { int nCol; - int aiCol[FLEXARRAY]; + int aiCol[1]; }; -/* Size (int bytes) of a complete Fts5Colset object with N columns. */ -#define SZ_FTS5COLSET(N) (sizeof(i64)*((N+2)/2)) + /************************************************************************** ** Interface to code in fts5_config.c. fts5_config.c contains contains code @@ -242468,7 +241024,7 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); ** ** The "lemon" program processes an LALR(1) input grammar file, then uses ** this template to construct a parser. The "lemon" program inserts text -** at each "%%" line. Also, any "P-a-r-s-e" identifier prefix (without the +** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the ** interstitial "-" characters) contained in this template is changed into ** the value of the %name directive from the grammar. Otherwise, the content ** of this template is copied straight through into the generate parser @@ -244622,7 +243178,7 @@ static int fts5Bm25GetData( ** under consideration. ** ** The problem with this is that if (N < 2*nHit), the IDF is - ** negative. Which is undesirable. So the minimum allowable IDF is + ** negative. Which is undesirable. So the mimimum allowable IDF is ** (1e-6) - roughly the same as a term that appears in just over ** half of set of 5,000,000 documents. */ double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) ); @@ -245085,7 +243641,7 @@ static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){ ** * The 52 upper and lower case ASCII characters, and ** * The 10 integer ASCII characters. ** * The underscore character "_" (0x5F). -** * The unicode "substitute" character (0x1A). +** * The unicode "subsitute" character (0x1A). */ static int sqlite3Fts5IsBareword(char t){ u8 aBareword[128] = { @@ -246403,13 +244959,9 @@ struct Fts5ExprNode { /* Child nodes. For a NOT node, this array always contains 2 entries. For ** AND or OR nodes, it contains 2 or more entries. */ int nChild; /* Number of child nodes */ - Fts5ExprNode *apChild[FLEXARRAY]; /* Array of child nodes */ + Fts5ExprNode *apChild[1]; /* Array of child nodes */ }; -/* Size (in bytes) of an Fts5ExprNode object that holds up to N children */ -#define SZ_FTS5EXPRNODE(N) \ - (offsetof(Fts5ExprNode,apChild) + (N)*sizeof(Fts5ExprNode*)) - #define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING) /* @@ -246440,13 +244992,9 @@ struct Fts5ExprPhrase { Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */ Fts5Buffer poslist; /* Current position list */ int nTerm; /* Number of entries in aTerm[] */ - Fts5ExprTerm aTerm[FLEXARRAY]; /* Terms that make up this phrase */ + Fts5ExprTerm aTerm[1]; /* Terms that make up this phrase */ }; -/* Size (in bytes) of an Fts5ExprPhrase object that holds up to N terms */ -#define SZ_FTS5EXPRPHRASE(N) \ - (offsetof(Fts5ExprPhrase,aTerm) + (N)*sizeof(Fts5ExprTerm)) - /* ** One or more phrases that must appear within a certain token distance of ** each other within each matching document. @@ -246455,12 +245003,9 @@ struct Fts5ExprNearset { int nNear; /* NEAR parameter */ Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */ int nPhrase; /* Number of entries in aPhrase[] array */ - Fts5ExprPhrase *apPhrase[FLEXARRAY]; /* Array of phrase pointers */ + Fts5ExprPhrase *apPhrase[1]; /* Array of phrase pointers */ }; -/* Size (in bytes) of an Fts5ExprNearset object covering up to N phrases */ -#define SZ_FTS5EXPRNEARSET(N) \ - (offsetof(Fts5ExprNearset,apPhrase)+(N)*sizeof(Fts5ExprPhrase*)) /* ** Parse context. @@ -246620,7 +245165,7 @@ static int sqlite3Fts5ExprNew( /* If the LHS of the MATCH expression was a user column, apply the ** implicit column-filter. */ if( sParse.rc==SQLITE_OK && iColnCol ){ - int n = SZ_FTS5COLSET(1); + int n = sizeof(Fts5Colset); Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); if( pColset ){ pColset->nCol = 1; @@ -247978,7 +246523,7 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( if( pParse->rc==SQLITE_OK ){ if( pNear==0 ){ sqlite3_int64 nByte; - nByte = SZ_FTS5EXPRNEARSET(SZALLOC+1); + nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); pRet = sqlite3_malloc64(nByte); if( pRet==0 ){ pParse->rc = SQLITE_NOMEM; @@ -247989,7 +246534,7 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( int nNew = pNear->nPhrase + SZALLOC; sqlite3_int64 nByte; - nByte = SZ_FTS5EXPRNEARSET(nNew+1); + nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*); pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte); if( pRet==0 ){ pParse->rc = SQLITE_NOMEM; @@ -248080,12 +246625,12 @@ static int fts5ParseTokenize( int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0); pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase, - SZ_FTS5EXPRPHRASE(nNew+1) + sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew ); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ - if( pPhrase==0 ) memset(pNew, 0, SZ_FTS5EXPRPHRASE(1)); + if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase)); pCtx->pPhrase = pPhrase = pNew; pNew->nTerm = nNew - SZALLOC; } @@ -248193,7 +246738,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( if( sCtx.pPhrase==0 ){ /* This happens when parsing a token or quoted phrase that contains ** no token characters at all. (e.g ... MATCH '""'). */ - sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, SZ_FTS5EXPRPHRASE(1)); + sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase)); }else if( sCtx.pPhrase->nTerm ){ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; } @@ -248228,18 +246773,19 @@ static int sqlite3Fts5ExprClonePhrase( sizeof(Fts5ExprPhrase*)); } if( rc==SQLITE_OK ){ - pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRNODE(1)); + pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, + sizeof(Fts5ExprNode)); } if( rc==SQLITE_OK ){ pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, - SZ_FTS5EXPRNEARSET(2)); + sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)); } if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){ Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; if( pColsetOrig ){ sqlite3_int64 nByte; Fts5Colset *pColset; - nByte = SZ_FTS5COLSET(pColsetOrig->nCol); + nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int); pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte); if( pColset ){ memcpy(pColset, pColsetOrig, (size_t)nByte); @@ -248267,7 +246813,7 @@ static int sqlite3Fts5ExprClonePhrase( }else{ /* This happens when parsing a token or quoted phrase that contains ** no token characters at all. (e.g ... MATCH '""'). */ - sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRPHRASE(1)); + sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); } } @@ -248332,8 +246878,7 @@ static void sqlite3Fts5ParseSetDistance( ); return; } - if( nNear<214748363 ) nNear = nNear * 10 + (p->p[i] - '0'); - /* ^^^^^^^^^^^^^^^--- Prevent integer overflow */ + nNear = nNear * 10 + (p->p[i] - '0'); } }else{ nNear = FTS5_DEFAULT_NEARDIST; @@ -248362,7 +246907,7 @@ static Fts5Colset *fts5ParseColset( assert( pParse->rc==SQLITE_OK ); assert( iCol>=0 && iColpConfig->nCol ); - pNew = sqlite3_realloc64(p, SZ_FTS5COLSET(nCol+1)); + pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol); if( pNew==0 ){ pParse->rc = SQLITE_NOMEM; }else{ @@ -248397,7 +246942,7 @@ static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p int nCol = pParse->pConfig->nCol; pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc, - SZ_FTS5COLSET(nCol+1) + sizeof(Fts5Colset) + sizeof(int)*nCol ); if( pRet ){ int i; @@ -248458,7 +247003,7 @@ static Fts5Colset *sqlite3Fts5ParseColset( static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){ Fts5Colset *pRet; if( pOrig ){ - sqlite3_int64 nByte = SZ_FTS5COLSET(pOrig->nCol); + sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int); pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte); if( pRet ){ memcpy(pRet, pOrig, (size_t)nByte); @@ -248626,7 +247171,7 @@ static Fts5ExprNode *fts5ParsePhraseToAnd( assert( pNear->nPhrase==1 ); assert( pParse->bPhraseToAnd ); - nByte = SZ_FTS5EXPRNODE(nTerm+1); + nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*); pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); if( pRet ){ pRet->eType = FTS5_AND; @@ -248636,7 +247181,7 @@ static Fts5ExprNode *fts5ParsePhraseToAnd( pParse->nPhrase--; for(ii=0; iirc, SZ_FTS5EXPRPHRASE(1) + &pParse->rc, sizeof(Fts5ExprPhrase) ); if( pPhrase ){ if( parseGrowPhraseArray(pParse) ){ @@ -248705,7 +247250,7 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( if( pRight->eType==eType ) nChild += pRight->nChild-1; } - nByte = SZ_FTS5EXPRNODE(nChild); + nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1); pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); if( pRet ){ @@ -249580,7 +248125,7 @@ static int sqlite3Fts5ExprInstToken( } /* -** Clear the token mappings for all Fts5IndexIter objects managed by +** Clear the token mappings for all Fts5IndexIter objects mannaged by ** the expression passed as the only argument. */ static void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){ @@ -249615,7 +248160,7 @@ typedef struct Fts5HashEntry Fts5HashEntry; /* ** This file contains the implementation of an in-memory hash table used -** to accumulate "term -> doclist" content before it is flushed to a level-0 +** to accumuluate "term -> doclist" content before it is flused to a level-0 ** segment. */ @@ -249672,7 +248217,7 @@ struct Fts5HashEntry { }; /* -** Equivalent to: +** Eqivalent to: ** ** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; } */ @@ -250608,13 +249153,9 @@ struct Fts5Structure { u64 nOriginCntr; /* Origin value for next top-level segment */ int nSegment; /* Total segments in this structure */ int nLevel; /* Number of levels in this index */ - Fts5StructureLevel aLevel[FLEXARRAY]; /* Array of nLevel level objects */ + Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */ }; -/* Size (in bytes) of an Fts5Structure object holding up to N levels */ -#define SZ_FTS5STRUCTURE(N) \ - (offsetof(Fts5Structure,aLevel) + (N)*sizeof(Fts5StructureLevel)) - /* ** An object of type Fts5SegWriter is used to write to segments. */ @@ -250744,15 +249285,11 @@ struct Fts5SegIter { ** Array of tombstone pages. Reference counted. */ struct Fts5TombstoneArray { - int nRef; /* Number of pointers to this object */ + int nRef; /* Number of pointers to this object */ int nTombstone; - Fts5Data *apTombstone[FLEXARRAY]; /* Array of tombstone pages */ + Fts5Data *apTombstone[1]; /* Array of tombstone pages */ }; -/* Size (in bytes) of an Fts5TombstoneArray holding up to N tombstones */ -#define SZ_FTS5TOMBSTONEARRAY(N) \ - (offsetof(Fts5TombstoneArray,apTombstone)+(N)*sizeof(Fts5Data*)) - /* ** Argument is a pointer to an Fts5Data structure that contains a ** leaf page. @@ -250821,12 +249358,9 @@ struct Fts5Iter { i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */ Fts5CResult *aFirst; /* Current merge state (see above) */ - Fts5SegIter aSeg[FLEXARRAY]; /* Array of segment iterators */ + Fts5SegIter aSeg[1]; /* Array of segment iterators */ }; -/* Size (in bytes) of an Fts5Iter object holding up to N segment iterators */ -#define SZ_FTS5ITER(N) (offsetof(Fts5Iter,aSeg)+(N)*sizeof(Fts5SegIter)) - /* ** An instance of the following type is used to iterate through the contents ** of a doclist-index record. @@ -250853,13 +249387,9 @@ struct Fts5DlidxLvl { struct Fts5DlidxIter { int nLvl; int iSegid; - Fts5DlidxLvl aLvl[FLEXARRAY]; + Fts5DlidxLvl aLvl[1]; }; -/* Size (in bytes) of an Fts5DlidxIter object with up to N levels */ -#define SZ_FTS5DLIDXITER(N) \ - (offsetof(Fts5DlidxIter,aLvl)+(N)*sizeof(Fts5DlidxLvl)) - static void fts5PutU16(u8 *aOut, u16 iVal){ aOut[0] = (iVal>>8); aOut[1] = (iVal&0xFF); @@ -251227,7 +249757,7 @@ static int sqlite3Fts5StructureTest(Fts5Index *p, void *pStruct){ static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){ Fts5Structure *p = *pp; if( *pRc==SQLITE_OK && p->nRef>1 ){ - i64 nByte = SZ_FTS5STRUCTURE(p->nLevel); + i64 nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel); Fts5Structure *pNew; pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte); if( pNew ){ @@ -251301,7 +249831,10 @@ static int fts5StructureDecode( ){ return FTS5_CORRUPT; } - nByte = SZ_FTS5STRUCTURE(nLevel); + nByte = ( + sizeof(Fts5Structure) + /* Main structure */ + sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */ + ); pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte); if( pRet ){ @@ -251381,7 +249914,10 @@ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){ if( *pRc==SQLITE_OK ){ Fts5Structure *pStruct = *ppStruct; int nLevel = pStruct->nLevel; - sqlite3_int64 nByte = SZ_FTS5STRUCTURE(nLevel+2); + sqlite3_int64 nByte = ( + sizeof(Fts5Structure) + /* Main structure */ + sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */ + ); pStruct = sqlite3_realloc64(pStruct, nByte); if( pStruct ){ @@ -251920,7 +250456,7 @@ static Fts5DlidxIter *fts5DlidxIterInit( int bDone = 0; for(i=0; p->rc==SQLITE_OK && bDone==0; i++){ - sqlite3_int64 nByte = SZ_FTS5DLIDXITER(i+1); + sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl); Fts5DlidxIter *pNew; pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte); @@ -252136,9 +250672,9 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){ ** leave an error in the Fts5Index object. */ static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ - const i64 nTomb = (i64)pIter->pSeg->nPgTombstone; + const int nTomb = pIter->pSeg->nPgTombstone; if( nTomb>0 ){ - i64 nByte = SZ_FTS5TOMBSTONEARRAY(nTomb+1); + int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray); Fts5TombstoneArray *pNew; pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ @@ -253599,7 +252135,8 @@ static Fts5Iter *fts5MultiIterAlloc( for(nSlot=2; nSlotaSeg[] */ + sizeof(Fts5Iter) + /* pNew */ + sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */ sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */ ); if( pNew ){ @@ -255400,7 +253937,7 @@ static void fts5DoSecureDelete( int iDelKeyOff = 0; /* Offset of deleted key, if any */ nIdx = nPg-iPgIdx; - aIdx = sqlite3Fts5MallocZero(&p->rc, ((i64)nIdx)+16); + aIdx = sqlite3Fts5MallocZero(&p->rc, nIdx+16); if( p->rc ) return; memcpy(aIdx, &aPg[iPgIdx], nIdx); @@ -255965,7 +254502,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( Fts5Structure *pStruct ){ Fts5Structure *pNew = 0; - sqlite3_int64 nByte = SZ_FTS5STRUCTURE(1); + sqlite3_int64 nByte = sizeof(Fts5Structure); int nSeg = pStruct->nSegment; int i; @@ -255994,8 +254531,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( assert( pStruct->aLevel[i].nMerge<=nThis ); } - nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel); - assert( nByte==SZ_FTS5STRUCTURE(pStruct->nLevel+2) ); + nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel); pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ @@ -256572,13 +255108,9 @@ struct Fts5TokenDataIter { int nIterAlloc; Fts5PoslistReader *aPoslistReader; int *aPoslistToIter; - Fts5Iter *apIter[FLEXARRAY]; + Fts5Iter *apIter[1]; }; -/* Size in bytes of an Fts5TokenDataIter object holding up to N iterators */ -#define SZ_FTS5TOKENDATAITER(N) \ - (offsetof(Fts5TokenDataIter,apIter) + (N)*sizeof(Fts5Iter)) - /* ** The two input arrays - a1[] and a2[] - are in sorted order. This function ** merges the two arrays together and writes the result to output array @@ -256650,7 +255182,7 @@ static void fts5TokendataIterAppendMap( /* ** Sort the contents of the pT->aMap[] array. ** -** The sorting algorithm requires a malloc(). If this fails, an error code +** The sorting algorithm requries a malloc(). If this fails, an error code ** is left in Fts5Index.rc before returning. */ static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ @@ -256841,7 +255373,7 @@ static void fts5SetupPrefixIter( && p->pConfig->bPrefixInsttoken ){ s.pTokendata = &s2; - s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, SZ_FTS5TOKENDATAITER(1)); + s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT)); } if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ @@ -256887,8 +255419,7 @@ static void fts5SetupPrefixIter( } } - pData = fts5IdxMalloc(p, sizeof(*pData) - + ((i64)s.doclist.n)+FTS5_DATA_ZERO_PADDING); + pData = fts5IdxMalloc(p, sizeof(*pData)+s.doclist.n+FTS5_DATA_ZERO_PADDING); assert( pData!=0 || p->rc!=SQLITE_OK ); if( pData ){ pData->p = (u8*)&pData[1]; @@ -256969,17 +255500,15 @@ static int sqlite3Fts5IndexRollback(Fts5Index *p){ ** and the initial version of the "averages" record (a zero-byte blob). */ static int sqlite3Fts5IndexReinit(Fts5Index *p){ - Fts5Structure *pTmp; - u8 tmpSpace[SZ_FTS5STRUCTURE(1)]; + Fts5Structure s; fts5StructureInvalidate(p); fts5IndexDiscardData(p); - pTmp = (Fts5Structure*)tmpSpace; - memset(pTmp, 0, SZ_FTS5STRUCTURE(1)); + memset(&s, 0, sizeof(Fts5Structure)); if( p->pConfig->bContentlessDelete ){ - pTmp->nOriginCntr = 1; + s.nOriginCntr = 1; } fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); - fts5StructureWrite(p, pTmp); + fts5StructureWrite(p, &s); return fts5IndexReturn(p); } @@ -257187,7 +255716,7 @@ static Fts5TokenDataIter *fts5AppendTokendataIter( if( p->rc==SQLITE_OK ){ if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; - int nByte = SZ_FTS5TOKENDATAITER(nAlloc+1); + int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter); Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte); if( pNew==0 ){ @@ -257703,8 +256232,7 @@ static int fts5SetupPrefixIterTokendata( fts5BufferGrow(&p->rc, &token, nToken+1); assert( token.p!=0 || p->rc!=SQLITE_OK ); - ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, - SZ_FTS5TOKENDATAITER(1)); + ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT)); if( p->rc==SQLITE_OK ){ @@ -257835,8 +256363,7 @@ static int sqlite3Fts5IndexIterWriteTokendata( if( pIter->nSeg>0 ){ /* This is a prefix term iterator. */ if( pT==0 ){ - pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, - SZ_FTS5TOKENDATAITER(1)); + pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT)); pIter->pTokenDataIter = pT; } if( pT ){ @@ -258870,7 +257397,7 @@ static void fts5DecodeRowid( #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ - int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid components */ + int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid compenents */ fts5DecodeRowid(iKey, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); if( iSegid==0 ){ @@ -259116,7 +257643,7 @@ static void fts5DecodeFunction( ** buffer overreads even if the record is corrupt. */ n = sqlite3_value_bytes(apVal[1]); aBlob = sqlite3_value_blob(apVal[1]); - nSpace = ((i64)n) + FTS5_DATA_ZERO_PADDING; + nSpace = n + FTS5_DATA_ZERO_PADDING; a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace); if( a==0 ) goto decode_out; if( n>0 ) memcpy(a, aBlob, n); @@ -259831,11 +258358,9 @@ struct Fts5Sorter { i64 iRowid; /* Current rowid */ const u8 *aPoslist; /* Position lists for current row */ int nIdx; /* Number of entries in aIdx[] */ - int aIdx[FLEXARRAY]; /* Offsets into aPoslist for current row */ + int aIdx[1]; /* Offsets into aPoslist for current row */ }; -/* Size (int bytes) of an Fts5Sorter object with N indexes */ -#define SZ_FTS5SORTER(N) (offsetof(Fts5Sorter,nIdx)+((N+2)/2)*sizeof(i64)) /* ** Virtual-table cursor object. @@ -260713,7 +259238,7 @@ static int fts5CursorFirstSorted( const char *zRankArgs = pCsr->zRankArgs; nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr); - nByte = SZ_FTS5SORTER(nPhrase); + nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1); pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte); if( pSorter==0 ) return SQLITE_NOMEM; memset(pSorter, 0, (size_t)nByte); @@ -263239,7 +261764,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2025-07-30 19:33:53 4d8adfb30e03f9cf27f800a2c1ba3c48fb4ca1b08b0f5ed59a4d5ecbf45e20a3", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2025-05-07 10:39:52 17144570b0d96ae63cd6f3edca39e27ebd74925252bbaf6723bcb2f6b4861fb1", -1, SQLITE_TRANSIENT); } /* @@ -263464,8 +261989,8 @@ static int fts5Init(sqlite3 *db){ ** its entry point to enable the matchinfo() demo. */ #ifdef SQLITE_FTS5_ENABLE_TEST_MI if( rc==SQLITE_OK ){ - extern int sqlite3Fts5TestRegisterMatchinfoAPI(fts5_api*); - rc = sqlite3Fts5TestRegisterMatchinfoAPI(&pGlobal->api); + extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*); + rc = sqlite3Fts5TestRegisterMatchinfo(db); } #endif @@ -264054,7 +262579,6 @@ static int fts5StorageDeleteFromIndex( for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ if( pConfig->abUnindexed[iCol-1]==0 ){ sqlite3_value *pVal = 0; - sqlite3_value *pFree = 0; const char *pText = 0; int nText = 0; const char *pLoc = 0; @@ -264071,22 +262595,11 @@ static int fts5StorageDeleteFromIndex( if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); }else{ - if( sqlite3_value_type(pVal)!=SQLITE_TEXT ){ - /* Make a copy of the value to work with. This is because the call - ** to sqlite3_value_text() below forces the type of the value to - ** SQLITE_TEXT, and we may need to use it again later. */ - pFree = pVal = sqlite3_value_dup(pVal); - if( pVal==0 ){ - rc = SQLITE_NOMEM; - } - } - if( rc==SQLITE_OK ){ - pText = (const char*)sqlite3_value_text(pVal); - nText = sqlite3_value_bytes(pVal); - if( pConfig->bLocale && pSeek ){ - pLoc = (const char*)sqlite3_column_text(pSeek, iCol+pConfig->nCol); - nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); - } + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale && pSeek ){ + pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); + nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); } } @@ -264102,7 +262615,6 @@ static int fts5StorageDeleteFromIndex( } sqlite3Fts5ClearLocale(pConfig); } - sqlite3_value_free(pFree); } } if( rc==SQLITE_OK && p->nTotalRow<1 ){ @@ -267316,6 +265828,7 @@ static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ aAscii[0] = 0; /* 0x00 is never a token character */ } + /* ** 2015 May 30 ** @@ -267856,12 +266369,12 @@ static int fts5VocabInitVtab( *pzErr = sqlite3_mprintf("wrong number of vtable arguments"); rc = SQLITE_ERROR; }else{ - i64 nByte; /* Bytes of space to allocate */ + int nByte; /* Bytes of space to allocate */ const char *zDb = bDb ? argv[3] : argv[1]; const char *zTab = bDb ? argv[4] : argv[3]; const char *zType = bDb ? argv[5] : argv[4]; - i64 nDb = strlen(zDb)+1; - i64 nTab = strlen(zTab)+1; + int nDb = (int)strlen(zDb)+1; + int nTab = (int)strlen(zTab)+1; int eType = 0; rc = fts5VocabTableType(zType, pzErr, &eType); diff --git a/Sources/DataLiteC/sqlcipher/sqlite3.h b/Sources/DataLiteC/sqlcipher/sqlite3.h index 30ab011..cb6288d 100644 --- a/Sources/DataLiteC/sqlcipher/sqlite3.h +++ b/Sources/DataLiteC/sqlcipher/sqlite3.h @@ -133,7 +133,7 @@ extern "C" { ** ** Since [version 3.6.18] ([dateof:3.6.18]), ** SQLite source code has been stored in the -** Fossil configuration management +** Fossil configuration management ** system. ^The SQLITE_SOURCE_ID macro evaluates to ** a string which identifies a particular check-in of SQLite ** within its configuration management system. ^The SQLITE_SOURCE_ID @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.50.4" -#define SQLITE_VERSION_NUMBER 3050004 -#define SQLITE_SOURCE_ID "2025-07-30 19:33:53 4d8adfb30e03f9cf27f800a2c1ba3c48fb4ca1b08b0f5ed59a4d5ecbf45ealt1" +#define SQLITE_VERSION "3.49.2" +#define SQLITE_VERSION_NUMBER 3049002 +#define SQLITE_SOURCE_ID "2025-05-07 10:39:52 17144570b0d96ae63cd6f3edca39e27ebd74925252bbaf6723bcb2f6b486alt1" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -1163,12 +1163,6 @@ struct sqlite3_io_methods { ** the value that M is to be set to. Before returning, the 32-bit signed ** integer is overwritten with the previous value of M. ** -**
        • [[SQLITE_FCNTL_BLOCK_ON_CONNECT]] -** The [SQLITE_FCNTL_BLOCK_ON_CONNECT] opcode is used to configure the -** VFS to block when taking a SHARED lock to connect to a wal mode database. -** This is used to implement the functionality associated with -** SQLITE_SETLK_BLOCK_ON_CONNECT. -** **
        • [[SQLITE_FCNTL_DATA_VERSION]] ** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to ** a database file. The argument is a pointer to a 32-bit unsigned integer. @@ -1265,7 +1259,6 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 #define SQLITE_FCNTL_NULL_IO 43 -#define SQLITE_FCNTL_BLOCK_ON_CONNECT 44 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -1996,16 +1989,13 @@ struct sqlite3_mem_methods { ** ** [[SQLITE_CONFIG_LOOKASIDE]]
          SQLITE_CONFIG_LOOKASIDE
          **
          ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine -** the default size of [lookaside memory] on each [database connection]. +** the default size of lookaside memory on each [database connection]. ** The first argument is the -** size of each lookaside buffer slot ("sz") and the second is the number of -** slots allocated to each database connection ("cnt").)^ -** ^(SQLITE_CONFIG_LOOKASIDE sets the default lookaside size. -** The [SQLITE_DBCONFIG_LOOKASIDE] option to [sqlite3_db_config()] can -** be used to change the lookaside configuration on individual connections.)^ -** The [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to change the -** default lookaside configuration at compile-time. -**
          +** size of each lookaside buffer slot and the second is the number of +** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE +** sets the default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** option to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections.)^
        • ** ** [[SQLITE_CONFIG_PCACHE2]]
          SQLITE_CONFIG_PCACHE2
          **
          ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is @@ -2242,50 +2232,31 @@ struct sqlite3_mem_methods { ** [[SQLITE_DBCONFIG_LOOKASIDE]] **
          SQLITE_DBCONFIG_LOOKASIDE
          **
          The SQLITE_DBCONFIG_LOOKASIDE option is used to adjust the -** configuration of the [lookaside memory allocator] within a database +** configuration of the lookaside memory allocator within a database ** connection. ** The arguments to the SQLITE_DBCONFIG_LOOKASIDE option are not ** in the [DBCONFIG arguments|usual format]. ** The SQLITE_DBCONFIG_LOOKASIDE option takes three arguments, not two, ** so that a call to [sqlite3_db_config()] that uses SQLITE_DBCONFIG_LOOKASIDE ** should have a total of five parameters. -**
            -**
          1. The first argument ("buf") is a +** ^The first argument (the third parameter to [sqlite3_db_config()] is a ** pointer to a memory buffer to use for lookaside memory. -** The first argument may be NULL in which case SQLite will allocate the -** lookaside buffer itself using [sqlite3_malloc()]. -**

          2. The second argument ("sz") is the -** size of each lookaside buffer slot. Lookaside is disabled if "sz" -** is less than 8. The "sz" argument should be a multiple of 8 less than -** 65536. If "sz" does not meet this constraint, it is reduced in size until -** it does. -**

          3. The third argument ("cnt") is the number of slots. Lookaside is disabled -** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so -** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt" -** parameter is usually chosen so that the product of "sz" and "cnt" is less -** than 1,000,000. -**

          -**

          If the "buf" argument is not NULL, then it must -** point to a memory buffer with a size that is greater than -** or equal to the product of "sz" and "cnt". -** The buffer must be aligned to an 8-byte boundary. -** The lookaside memory +** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb +** may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the +** size of each lookaside buffer slot. ^The third argument is the number of +** slots. The size of the buffer in the first argument must be greater than +** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. ^If the second argument to +** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally +** rounded down to the next smaller multiple of 8. ^(The lookaside memory ** configuration for a database connection can only be changed when that ** connection is not currently using lookaside memory, or in other words -** when the value returned by [SQLITE_DBSTATUS_LOOKASIDE_USED] is zero. +** when the "current value" returned by +** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero. ** Any attempt to change the lookaside memory configuration when lookaside ** memory is in use leaves the configuration unchanged and returns -** [SQLITE_BUSY]. -** If the "buf" argument is NULL and an attempt -** to allocate memory based on "sz" and "cnt" fails, then -** lookaside is silently disabled. -**

          -** The [SQLITE_CONFIG_LOOKASIDE] configuration option can be used to set the -** default lookaside configuration at initialization. The -** [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to set the default lookaside -** configuration at compile-time. Typical values for lookaside are 1200 for -** "sz" and 40 to 100 for "cnt". -**

          +** [SQLITE_BUSY].)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FKEY]] **
          SQLITE_DBCONFIG_ENABLE_FKEY
          @@ -3022,44 +2993,6 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); */ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); -/* -** CAPI3REF: Set the Setlk Timeout -** METHOD: sqlite3 -** -** This routine is only useful in SQLITE_ENABLE_SETLK_TIMEOUT builds. If -** the VFS supports blocking locks, it sets the timeout in ms used by -** eligible locks taken on wal mode databases by the specified database -** handle. In non-SQLITE_ENABLE_SETLK_TIMEOUT builds, or if the VFS does -** not support blocking locks, this function is a no-op. -** -** Passing 0 to this function disables blocking locks altogether. Passing -** -1 to this function requests that the VFS blocks for a long time - -** indefinitely if possible. The results of passing any other negative value -** are undefined. -** -** Internally, each SQLite database handle store two timeout values - the -** busy-timeout (used for rollback mode databases, or if the VFS does not -** support blocking locks) and the setlk-timeout (used for blocking locks -** on wal-mode databases). The sqlite3_busy_timeout() method sets both -** values, this function sets only the setlk-timeout value. Therefore, -** to configure separate busy-timeout and setlk-timeout values for a single -** database handle, call sqlite3_busy_timeout() followed by this function. -** -** Whenever the number of connections to a wal mode database falls from -** 1 to 0, the last connection takes an exclusive lock on the database, -** then checkpoints and deletes the wal file. While it is doing this, any -** new connection that tries to read from the database fails with an -** SQLITE_BUSY error. Or, if the SQLITE_SETLK_BLOCK_ON_CONNECT flag is -** passed to this API, the new connection blocks until the exclusive lock -** has been released. -*/ -SQLITE_API int sqlite3_setlk_timeout(sqlite3*, int ms, int flags); - -/* -** CAPI3REF: Flags for sqlite3_setlk_timeout() -*/ -#define SQLITE_SETLK_BLOCK_ON_CONNECT 0x01 - /* ** CAPI3REF: Convenience Routines For Running Queries ** METHOD: sqlite3 @@ -4079,7 +4012,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** database filename D with corresponding journal file J and WAL file W and -** an array P of N URI Key/Value pairs. The result from +** with N URI parameters key/values pairs in the array P. The result from ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that ** is safe to pass to routines like: **
            @@ -4760,7 +4693,7 @@ typedef struct sqlite3_context sqlite3_context; ** METHOD: sqlite3_stmt ** ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, -** literals may be replaced by a [parameter] that matches one of the following +** literals may be replaced by a [parameter] that matches one of following ** templates: ** **
              @@ -4805,7 +4738,7 @@ typedef struct sqlite3_context sqlite3_context; ** ** [[byte-order determination rules]] ^The byte-order of ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) -** found in the first character, which is removed, or in the absence of a BOM +** found in first character, which is removed, or in the absence of a BOM ** the byte order is the native byte order of the host ** machine for sqlite3_bind_text16() or the byte order specified in ** the 6th parameter for sqlite3_bind_text64().)^ @@ -4825,7 +4758,7 @@ typedef struct sqlite3_context sqlite3_context; ** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL -** terminated. If any NUL characters occur at byte offsets less than +** terminated. If any NUL characters occurs at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. @@ -5037,7 +4970,7 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); ** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and -** table column that is the origin of a particular result column in a +** table column that is the origin of a particular result column in ** [SELECT] statement. ** ^The name of the database or table or column can be returned as ** either a UTF-8 or UTF-16 string. ^The _database_ routines return @@ -5175,7 +5108,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** other than [SQLITE_ROW] before any subsequent invocation of ** sqlite3_step(). Failure to reset the prepared statement using ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from -** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), +** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], ** sqlite3_step() began ** calling [sqlite3_reset()] automatically in this circumstance rather ** than returning [SQLITE_MISUSE]. This is not considered a compatibility @@ -5606,8 +5539,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be -** used inside of triggers, views, CHECK constraints, or other elements of -** the database schema. This flag is especially recommended for SQL +** used inside of triggers, view, CHECK constraints, or other elements of +** the database schema. This flags is especially recommended for SQL ** functions that have side effects or reveal internal application state. ** Without this flag, an attacker might be able to modify the schema of ** a database file to include invocations of the function with parameters @@ -5638,7 +5571,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** [user-defined window functions|available here]. ** ** ^(If the final parameter to sqlite3_create_function_v2() or -** sqlite3_create_window_function() is not NULL, then it is the destructor for +** sqlite3_create_window_function() is not NULL, then it is destructor for ** the application data pointer. The destructor is invoked when the function ** is deleted, either by being overloaded or when the database connection ** closes.)^ ^The destructor is also invoked if the call to @@ -6038,7 +5971,7 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); ** METHOD: sqlite3_value ** ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] -** object V and returns a pointer to that copy. ^The [sqlite3_value] returned +** object D and returns a pointer to that copy. ^The [sqlite3_value] returned ** is a [protected sqlite3_value] object even if the input is not. ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a ** memory allocation fails. ^If V is a [pointer value], then the result @@ -6076,7 +6009,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*); ** allocation error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is -** determined by the N parameter on the first successful call. Changing the +** determined by the N parameter on first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory ** allocation.)^ Within the xFinal callback, it is customary to set @@ -6238,7 +6171,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi ** ** Security Warning: These interfaces should not be exposed in scripting ** languages or in other circumstances where it might be possible for an -** attacker to invoke them. Any agent that can invoke these interfaces +** an attacker to invoke them. Any agent that can invoke these interfaces ** can probably also take control of the process. ** ** Database connection client data is only available for SQLite @@ -6352,7 +6285,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would -** appear if the string were NUL terminated. If any NUL characters occur +** appear if the string where NUL terminated. If any NUL characters occur ** in the string at a byte offset that is less than the value of the 3rd ** parameter, then the resulting string will contain embedded NULs and the ** result of expressions operating on strings with embedded NULs is undefined. @@ -6410,7 +6343,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** string and preferably a string literal. The sqlite3_result_pointer() ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** -** If these routines are called from within a different thread +** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ @@ -6876,7 +6809,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** METHOD: sqlite3 ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name -** for the N-th database on database connection D, or a NULL pointer if N is +** for the N-th database on database connection D, or a NULL pointer of N is ** out of range. An N value of 0 means the main database file. An N of 1 is ** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** databases. @@ -6971,7 +6904,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); **
              The SQLITE_TXN_READ state means that the database is currently ** in a read transaction. Content has been read from the database file ** but nothing in the database file has changed. The transaction state -** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are +** will advanced to SQLITE_TXN_WRITE if any changes occur and there are ** no other conflicting concurrent write transactions. The transaction ** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or ** [COMMIT].
              @@ -6980,7 +6913,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); **
              The SQLITE_TXN_WRITE state means that the database is currently ** in a write transaction. Content has been written to the database file ** but has not yet committed. The transaction state will change to -** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].
              +** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT]. */ #define SQLITE_TXN_NONE 0 #define SQLITE_TXN_READ 1 @@ -7131,8 +7064,6 @@ SQLITE_API int sqlite3_autovacuum_pages( ** ** ^The second argument is a pointer to the function to invoke when a ** row is updated, inserted or deleted in a rowid table. -** ^The update hook is disabled by invoking sqlite3_update_hook() -** with a NULL pointer as the second parameter. ** ^The first argument to the callback is a copy of the third argument ** to sqlite3_update_hook(). ** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], @@ -7261,7 +7192,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); ** CAPI3REF: Impose A Limit On Heap Size ** ** These interfaces impose limits on the amount of heap memory that will be -** used by all database connections within a single process. +** by all database connections within a single process. ** ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** soft limit on the amount of heap memory that may be allocated by SQLite. @@ -7319,7 +7250,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); **
            )^ ** ** The circumstances under which SQLite will enforce the heap limits may -** change in future releases of SQLite. +** changes in future releases of SQLite. */ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); @@ -7434,8 +7365,8 @@ SQLITE_API int sqlite3_table_column_metadata( ** ^The entry point is zProc. ** ^(zProc may be 0, in which case SQLite will try to come up with an ** entry point name on its own. It first tries "sqlite3_extension_init". -** If that does not work, it constructs a name "sqlite3_X_init" where -** X consists of the lower-case equivalent of all ASCII alphabetic +** If that does not work, it constructs a name "sqlite3_X_init" where the +** X is consists of the lower-case equivalent of all ASCII alphabetic ** characters in the filename from the last "/" to the first following ** "." and omitting any initial "lib".)^ ** ^The sqlite3_load_extension() interface returns @@ -7506,7 +7437,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** ^(Even though the function prototype shows that xEntryPoint() takes ** no arguments and returns void, SQLite invokes xEntryPoint() with three ** arguments and expects an integer result as if the signature of the -** entry point were as follows: +** entry point where as follows: ** **
             **    int xEntryPoint(
            @@ -7670,7 +7601,7 @@ struct sqlite3_module {
             ** virtual table and might not be checked again by the byte code.)^ ^(The
             ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag
             ** is left in its default setting of false, the constraint will always be
            -** checked separately in byte code.  If the omit flag is changed to true, then
            +** checked separately in byte code.  If the omit flag is change to true, then
             ** the constraint may or may not be checked in byte code.  In other words,
             ** when the omit flag is true there is no guarantee that the constraint will
             ** not be checked again using byte code.)^
            @@ -7696,7 +7627,7 @@ struct sqlite3_module {
             ** The xBestIndex method may optionally populate the idxFlags field with a
             ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
             ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
            -** output to show the idxNum as hex instead of as decimal.  Another flag is
            +** output to show the idxNum has hex instead of as decimal.  Another flag is
             ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
             ** return at most one row.
             **
            @@ -7837,7 +7768,7 @@ struct sqlite3_index_info {
             ** the implementation of the [virtual table module].   ^The fourth
             ** parameter is an arbitrary client data pointer that is passed through
             ** into the [xCreate] and [xConnect] methods of the virtual table module
            -** when a new virtual table is being created or reinitialized.
            +** when a new virtual table is be being created or reinitialized.
             **
             ** ^The sqlite3_create_module_v2() interface has a fifth parameter which
             ** is a pointer to a destructor for the pClientData.  ^SQLite will
            @@ -8002,7 +7933,7 @@ typedef struct sqlite3_blob sqlite3_blob;
             ** in *ppBlob. Otherwise an [error code] is returned and, unless the error
             ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
             ** the API is not misused, it is always safe to call [sqlite3_blob_close()]
            -** on *ppBlob after this function returns.
            +** on *ppBlob after this function it returns.
             **
             ** This function fails with SQLITE_ERROR if any of the following are true:
             ** 
              @@ -8122,7 +8053,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The -** incremental blob I/O routines can only read or overwrite existing +** incremental blob I/O routines can only read or overwriting existing ** blob content; they cannot change the size of a blob. ** ** This routine only works on a [BLOB handle] which has been created @@ -8272,7 +8203,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ^The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** routine returns NULL if it is unable to allocate the requested -** mutex. The argument to sqlite3_mutex_alloc() must be one of these +** mutex. The argument to sqlite3_mutex_alloc() must one of these ** integer constants: ** **
                @@ -8505,7 +8436,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** -** ^This interface returns a pointer to the [sqlite3_mutex] object that +** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this @@ -8628,7 +8559,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); ** CAPI3REF: SQL Keyword Checking ** ** These routines provide access to the set of SQL language keywords -** recognized by SQLite. Applications can use these routines to determine +** recognized by SQLite. Applications can uses these routines to determine ** whether or not a specific identifier needs to be escaped (for example, ** by enclosing in double-quotes) so as not to confuse the parser. ** @@ -8796,7 +8727,7 @@ SQLITE_API void sqlite3_str_reset(sqlite3_str*); ** content of the dynamic string under construction in X. The value ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** and might be freed or altered by any subsequent method on the same -** [sqlite3_str] object. Applications must not use the pointer returned by +** [sqlite3_str] object. Applications must not used the pointer returned ** [sqlite3_str_value(X)] after any subsequent method call on the same ** object. ^Applications may change the content of the string returned ** by [sqlite3_str_value(X)] as long as they do not write into any bytes @@ -8882,7 +8813,7 @@ SQLITE_API int sqlite3_status64( ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** buffer and where forced to overflow to [sqlite3_malloc()]. The ** returned value includes allocations that overflowed because they -** were too large (they were larger than the "sz" parameter to +** where too large (they were larger than the "sz" parameter to ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because ** no space was left in the page cache.)^ ** @@ -8966,29 +8897,28 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
                SQLITE_DBSTATUS_LOOKASIDE_HIT
                **
                This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; -** the current value is always zero.
                )^ +** the current value is always zero.)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] ** ^(
                SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
                -**
                This parameter returns the number of malloc attempts that might have +**
                This parameter returns the number malloc attempts that might have ** been satisfied using lookaside memory but failed due to the amount of ** memory requested being larger than the lookaside slot size. ** Only the high-water value is meaningful; -** the current value is always zero.
                )^ +** the current value is always zero.)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] ** ^(
                SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
                -**
                This parameter returns the number of malloc attempts that might have +**
                This parameter returns the number malloc attempts that might have ** been satisfied using lookaside memory but failed due to all lookaside ** memory already being in use. ** Only the high-water value is meaningful; -** the current value is always zero.
                )^ +** the current value is always zero.)^ ** ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
                SQLITE_DBSTATUS_CACHE_USED
                **
                This parameter returns the approximate number of bytes of heap ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. -**
                ** ** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] ** ^(
                SQLITE_DBSTATUS_CACHE_USED_SHARED
                @@ -8997,10 +8927,10 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** memory used by that pager cache is divided evenly between the attached ** connections.)^ In other words, if none of the pager caches associated ** with the database connection are shared, this request returns the same -** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are +** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are ** shared, the value returned by this call will be smaller than that returned ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with -** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. +** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. ** ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
                SQLITE_DBSTATUS_SCHEMA_USED
                **
                This parameter returns the approximate number of bytes of heap @@ -9010,7 +8940,6 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** schema memory is shared with other database connections due to ** [shared cache mode] being enabled. ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. -**
                ** ** [[SQLITE_DBSTATUS_STMT_USED]] ^(
                SQLITE_DBSTATUS_STMT_USED
                **
                This parameter returns the approximate number of bytes of heap @@ -9047,7 +8976,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces -** additional overhead. This parameter can be used to help identify +** additional overhead. This parameter can be used help identify ** inefficiencies that can be resolved by increasing the cache size. **
                ** @@ -9118,13 +9047,13 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** [[SQLITE_STMTSTATUS_SORT]]
                SQLITE_STMTSTATUS_SORT
                **
                ^This is the number of sort operations that have occurred. ** A non-zero value in this counter may indicate an opportunity to -** improve performance through careful use of indices.
                +** improvement performance through careful use of indices. ** ** [[SQLITE_STMTSTATUS_AUTOINDEX]]
                SQLITE_STMTSTATUS_AUTOINDEX
                **
                ^This is the number of rows inserted into transient indices that ** were created automatically in order to help joins run faster. ** A non-zero value in this counter may indicate an opportunity to -** improve performance by adding permanent indices that do not +** improvement performance by adding permanent indices that do not ** need to be reinitialized each time the statement is run.
                ** ** [[SQLITE_STMTSTATUS_VM_STEP]]
                SQLITE_STMTSTATUS_VM_STEP
                @@ -9133,19 +9062,19 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** to 2147483647. The number of virtual machine operations can be ** used as a proxy for the total work done by the prepared statement. ** If the number of virtual machine operations exceeds 2147483647 -** then the value returned by this statement status code is undefined. +** then the value returned by this statement status code is undefined. ** ** [[SQLITE_STMTSTATUS_REPREPARE]]
                SQLITE_STMTSTATUS_REPREPARE
                **
                ^This is the number of times that the prepare statement has been ** automatically regenerated due to schema changes or changes to -** [bound parameters] that might affect the query plan.
                +** [bound parameters] that might affect the query plan. ** ** [[SQLITE_STMTSTATUS_RUN]]
                SQLITE_STMTSTATUS_RUN
                **
                ^This is the number of times that the prepared statement has ** been run. A single "run" for the purposes of this counter is one ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. ** The counter is incremented on the first [sqlite3_step()] call of each -** cycle.
                +** cycle. ** ** [[SQLITE_STMTSTATUS_FILTER_MISS]] ** [[SQLITE_STMTSTATUS_FILTER HIT]] @@ -9155,7 +9084,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** step was bypassed because a Bloom filter returned not-found. The ** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of ** times that the Bloom filter returned a find, and thus the join step -** had to be processed as normal. +** had to be processed as normal. ** ** [[SQLITE_STMTSTATUS_MEMUSED]]
                SQLITE_STMTSTATUS_MEMUSED
                **
                ^This is the approximate number of bytes of heap memory @@ -9260,9 +9189,9 @@ struct sqlite3_pcache_page { ** SQLite will typically create one cache instance for each open database file, ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must -** be allocated by the cache. ^szPage will always be a power of two. ^The +** be allocated by the cache. ^szPage will always a power of two. ^The ** second parameter szExtra is a number of bytes of extra storage -** associated with each page cache entry. ^The szExtra parameter will be +** associated with each page cache entry. ^The szExtra parameter will ** a number less than 250. SQLite will use the ** extra szExtra bytes on each page to store metadata about the underlying ** database page on disk. The value passed into szExtra depends @@ -9270,17 +9199,17 @@ struct sqlite3_pcache_page { ** ^The third argument to xCreate(), bPurgeable, is true if the cache being ** created will be used to cache database pages of a file stored on disk, or ** false if it is used for an in-memory database. The cache implementation -** does not have to do anything special based upon the value of bPurgeable; +** does not have to do anything special based with the value of bPurgeable; ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will ** never invoke xUnpin() except to deliberately delete a page. ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to ** false will always have the "discard" flag set to true. -** ^Hence, a cache created with bPurgeable set to false will +** ^Hence, a cache created with bPurgeable false will ** never contain any unpinned pages. ** ** [[the xCachesize() page cache method]] ** ^(The xCachesize() method may be called at any time by SQLite to set the -** suggested maximum cache-size (number of pages stored) for the cache +** suggested maximum cache-size (number of pages stored by) the cache ** instance passed as the first argument. This is the value configured using ** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable ** parameter, the implementation is not required to do anything with this @@ -9307,12 +9236,12 @@ struct sqlite3_pcache_page { ** implementation must return a pointer to the page buffer with its content ** intact. If the requested page is not already in the cache, then the ** cache implementation should use the value of the createFlag -** parameter to help it determine what action to take: +** parameter to help it determined what action to take: ** ** **
                createFlag Behavior when page is not already in cache **
                0 Do not allocate a new page. Return NULL. -**
                1 Allocate a new page if it is easy and convenient to do so. +**
                1 Allocate a new page if it easy and convenient to do so. ** Otherwise return NULL. **
                2 Make every effort to allocate a new page. Only return ** NULL if allocating a new page is effectively impossible. @@ -9329,7 +9258,7 @@ struct sqlite3_pcache_page { ** as its second argument. If the third parameter, discard, is non-zero, ** then the page must be evicted from the cache. ** ^If the discard parameter is -** zero, then the page may be discarded or retained at the discretion of the +** zero, then the page may be discarded or retained at the discretion of ** page cache implementation. ^The page cache implementation ** may choose to evict unpinned pages at any time. ** @@ -9347,7 +9276,7 @@ struct sqlite3_pcache_page { ** When SQLite calls the xTruncate() method, the cache must discard all ** existing cache entries with page numbers (keys) greater than or equal ** to the value of the iLimit parameter passed to xTruncate(). If any -** of these pages are pinned, they become implicitly unpinned, meaning that +** of these pages are pinned, they are implicitly unpinned, meaning that ** they can be safely discarded. ** ** [[the xDestroy() page cache method]] @@ -9527,7 +9456,7 @@ typedef struct sqlite3_backup sqlite3_backup; ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically ** restarted by the next call to sqlite3_backup_step(). ^If the source -** database is modified by using the same database connection as is used +** database is modified by the using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** @@ -9544,7 +9473,7 @@ typedef struct sqlite3_backup sqlite3_backup; ** and may not be used following a call to sqlite3_backup_finish(). ** ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no -** sqlite3_backup_step() errors occurred, regardless of whether or not +** sqlite3_backup_step() errors occurred, regardless or whether or not ** sqlite3_backup_step() completed. ** ^If an out-of-memory condition or IO error occurred during any prior ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then @@ -9646,7 +9575,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** application receives an SQLITE_LOCKED error, it may call the ** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked -** when the blocking connection's current transaction is concluded. ^The +** when the blocking connections current transaction is concluded. ^The ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] ** call that concludes the blocking connection's transaction. ** @@ -9666,7 +9595,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is canceled. ^The blocked connection's +** unlock-notify callback is canceled. ^The blocked connections ** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** @@ -10064,7 +9993,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** support constraints. In this configuration (which is the default) if ** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire ** statement is rolled back as if [ON CONFLICT | OR ABORT] had been -** specified as part of the user's SQL statement, regardless of the actual +** specified as part of the users SQL statement, regardless of the actual ** ON CONFLICT mode specified. ** ** If X is non-zero, then the virtual table implementation guarantees @@ -10098,7 +10027,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** [[SQLITE_VTAB_INNOCUOUS]]
                SQLITE_VTAB_INNOCUOUS
                **
                Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the -** [xConnect] or [xCreate] methods of a [virtual table] implementation +** the [xConnect] or [xCreate] methods of a [virtual table] implementation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a @@ -10266,7 +10195,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); **
                ** ** ^For the purposes of comparing virtual table output values to see if the -** values are the same value for sorting purposes, two NULL values are considered +** values are same value for sorting purposes, two NULL values are considered ** to be the same. In other words, the comparison operator is "IS" ** (or "IS NOT DISTINCT FROM") and not "==". ** @@ -10276,7 +10205,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** ** ^A virtual table implementation is always free to return rows in any order ** it wants, as long as the "orderByConsumed" flag is not set. ^When the -** "orderByConsumed" flag is unset, the query planner will add extra +** the "orderByConsumed" flag is unset, the query planner will add extra ** [bytecode] to ensure that the final results returned by the SQL query are ** ordered correctly. The use of the "orderByConsumed" flag and the ** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful @@ -10373,7 +10302,7 @@ SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); ** sqlite3_vtab_in_next(X,P) should be one of the parameters to the ** xFilter method which invokes these routines, and specifically ** a parameter that was previously selected for all-at-once IN constraint -** processing using the [sqlite3_vtab_in()] interface in the +** processing use the [sqlite3_vtab_in()] interface in the ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not ** an xFilter argument that was selected for all-at-once IN constraint ** processing, then these routines return [SQLITE_ERROR].)^ @@ -10428,7 +10357,7 @@ SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface -** can return a result code other than SQLITE_OK or SQLITE_NOTFOUND if +** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if ** something goes wrong. ** ** The sqlite3_vtab_rhs_value() interface is usually only successful if @@ -10456,8 +10385,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** ** KEYWORDS: {conflict resolution mode} ** ** These constants are returned by [sqlite3_vtab_on_conflict()] to -** inform a [virtual table] implementation of the [ON CONFLICT] mode -** for the SQL statement being evaluated. +** inform a [virtual table] implementation what the [ON CONFLICT] mode +** is for the SQL statement being evaluated. ** ** Note that the [SQLITE_IGNORE] constant is also used as a potential ** return value from the [sqlite3_set_authorizer()] callback and that @@ -10497,39 +10426,39 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** ** [[SQLITE_SCANSTAT_EST]]
                SQLITE_SCANSTAT_EST
                **
                ^The "double" variable pointed to by the V parameter will be set to the ** query planner's estimate for the average number of rows output from each -** iteration of the X-th loop. If the query planner's estimate was accurate, +** iteration of the X-th loop. If the query planner's estimates was accurate, ** then this value will approximate the quotient NVISIT/NLOOP and the ** product of this value for all prior loops with the same SELECTID will -** be the NLOOP value for the current loop.
                +** be the NLOOP value for the current loop. ** ** [[SQLITE_SCANSTAT_NAME]]
                SQLITE_SCANSTAT_NAME
                **
                ^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the name of the index or table -** used for the X-th loop.
                +** used for the X-th loop. ** ** [[SQLITE_SCANSTAT_EXPLAIN]]
                SQLITE_SCANSTAT_EXPLAIN
                **
                ^The "const char *" variable pointed to by the V parameter will be set ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] -** description for the X-th loop.
                +** description for the X-th loop. ** ** [[SQLITE_SCANSTAT_SELECTID]]
                SQLITE_SCANSTAT_SELECTID
                **
                ^The "int" variable pointed to by the V parameter will be set to the ** id for the X-th query plan element. The id value is unique within the ** statement. The select-id is the same value as is output in the first -** column of an [EXPLAIN QUERY PLAN] query.
                +** column of an [EXPLAIN QUERY PLAN] query. ** ** [[SQLITE_SCANSTAT_PARENTID]]
                SQLITE_SCANSTAT_PARENTID
                **
                The "int" variable pointed to by the V parameter will be set to the -** id of the parent of the current query element, if applicable, or +** the id of the parent of the current query element, if applicable, or ** to zero if the query element has no parent. This is the same value as -** returned in the second column of an [EXPLAIN QUERY PLAN] query.
                +** returned in the second column of an [EXPLAIN QUERY PLAN] query. ** ** [[SQLITE_SCANSTAT_NCYCLE]]
                SQLITE_SCANSTAT_NCYCLE
                **
                The sqlite3_int64 output value is set to the number of cycles, ** according to the processor time-stamp counter, that elapsed while the ** query element was being processed. This value is not available for ** all query elements - if it is unavailable the output variable is -** set to -1.
                +** set to -1. ** */ #define SQLITE_SCANSTAT_NLOOP 0 @@ -10570,8 +10499,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. ** ** Parameter "idx" identifies the specific query element to retrieve statistics -** for. Query elements are numbered starting from zero. A value of -1 may -** retrieve statistics for the entire query. ^If idx is out of range +** for. Query elements are numbered starting from zero. A value of -1 may be +** to query for statistics regarding the entire query. ^If idx is out of range ** - less than -1 or greater than or equal to the total number of query ** elements used to implement the statement - a non-zero value is returned and ** the variable that pOut points to is unchanged. @@ -10614,7 +10543,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); ** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the -** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty +** [sqlite3_db_cacheflush(D)] interface invoked, any dirty ** pages in the pager-cache that are not currently in use are written out ** to disk. A dirty page may be in use if a database cursor created by an ** active SQL statement is reading from it, or if it is page 1 of a database @@ -10728,8 +10657,8 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** triggers; and so forth. ** ** When the [sqlite3_blob_write()] API is used to update a blob column, -** the pre-update hook is invoked with SQLITE_DELETE, because -** the new values are not yet available. In this case, when a +** the pre-update hook is invoked with SQLITE_DELETE. This is because the +** in this case the new values are not available. In this case, when a ** callback made with op==SQLITE_DELETE is actually a write using the ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns ** the index of the column being written. In other cases, where the @@ -10982,7 +10911,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written -** to disk if that database were backed up to disk. +** to disk if that database where backed up to disk. ** ** The usual case is that sqlite3_serialize() copies the serialization of ** the database into memory obtained from [sqlite3_malloc64()] and returns @@ -10991,7 +10920,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations ** are made, and the sqlite3_serialize() function will return a pointer ** to the contiguous memory representation of the database that SQLite -** is currently using for that database, or NULL if no such contiguous +** is currently using for that database, or NULL if the no such contiguous ** memory representation of the database exists. A contiguous memory ** representation of the database will usually only exist if there has ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same @@ -11062,7 +10991,7 @@ SQLITE_API unsigned char *sqlite3_serialize( ** database is currently in a read transaction or is involved in a backup ** operation. ** -** It is not possible to deserialize into the TEMP database. If the +** It is not possible to deserialized into the TEMP database. If the ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** @@ -11084,7 +11013,7 @@ SQLITE_API int sqlite3_deserialize( sqlite3 *db, /* The database connection */ const char *zSchema, /* Which DB to reopen with the deserialization */ unsigned char *pData, /* The serialized database content */ - sqlite3_int64 szDb, /* Number of bytes in the deserialization */ + sqlite3_int64 szDb, /* Number bytes in the deserialization */ sqlite3_int64 szBuf, /* Total size of buffer pData[] */ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ ); @@ -11092,7 +11021,7 @@ SQLITE_API int sqlite3_deserialize( /* ** CAPI3REF: Flags for sqlite3_deserialize() ** -** The following are allowed values for the 6th argument (the F argument) to +** The following are allowed values for 6th argument (the F argument) to ** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. ** ** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization @@ -11617,10 +11546,9 @@ SQLITE_API void sqlite3session_table_filter( ** is inserted while a session object is enabled, then later deleted while ** the same session object is disabled, no INSERT record will appear in the ** changeset, even though the delete took place while the session was disabled. -** Or, if one field of a row is updated while a session is enabled, and -** then another field of the same row is updated while the session is disabled, -** the resulting changeset will contain an UPDATE change that updates both -** fields. +** Or, if one field of a row is updated while a session is disabled, and +** another field of the same row is updated while the session is enabled, the +** resulting changeset will contain an UPDATE change that updates both fields. */ SQLITE_API int sqlite3session_changeset( sqlite3_session *pSession, /* Session object */ @@ -11692,9 +11620,8 @@ SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession ** database zFrom the contents of the two compatible tables would be ** identical. ** -** Unless the call to this function is a no-op as described above, it is an -** error if database zFrom does not exist or does not contain the required -** compatible table. +** It an error if database zFrom does not exist or does not contain the +** required compatible table. ** ** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite ** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg @@ -11829,7 +11756,7 @@ SQLITE_API int sqlite3changeset_start_v2( ** The following flags may passed via the 4th parameter to ** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: ** -**
                SQLITE_CHANGESETSTART_INVERT
                +**
                SQLITE_CHANGESETAPPLY_INVERT
                ** Invert the changeset while iterating through it. This is equivalent to ** inverting a changeset using sqlite3changeset_invert() before applying it. ** It is an error to specify this flag with a patchset. @@ -12144,6 +12071,19 @@ SQLITE_API int sqlite3changeset_concat( void **ppOut /* OUT: Buffer containing output changeset */ ); + +/* +** CAPI3REF: Upgrade the Schema of a Changeset/Patchset +*/ +SQLITE_API int sqlite3changeset_upgrade( + sqlite3 *db, + const char *zDb, + int nIn, const void *pIn, /* Input changeset */ + int *pnOut, void **ppOut /* OUT: Inverse of input */ +); + + + /* ** CAPI3REF: Changegroup Handle **