| | @@ -16,11 +16,11 @@ |
| 16 | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | 19 | ** |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | | -** 4cb349370daab17123770c814c71872a3e4c with changes in files: |
| 21 | +** 3f3fb9b638f59ad982beafb7c117f24ddd3d with changes in files: |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| | @@ -467,14 +467,14 @@ |
| 467 | 467 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 468 | 468 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 469 | 469 | */ |
| 470 | 470 | #define SQLITE_VERSION "3.54.0" |
| 471 | 471 | #define SQLITE_VERSION_NUMBER 3054000 |
| 472 | | -#define SQLITE_SOURCE_ID "2026-06-08 18:15:27 4cb349370daab17123770c814c71872a3e4c616a3f984569b3d7f97f9c3f5ea0" |
| 472 | +#define SQLITE_SOURCE_ID "2026-06-16 13:43:08 3f3fb9b638f59ad982beafb7c117f24ddd3da612e62c862510805fa672ffae06" |
| 473 | 473 | #define SQLITE_SCM_BRANCH "trunk" |
| 474 | 474 | #define SQLITE_SCM_TAGS "" |
| 475 | | -#define SQLITE_SCM_DATETIME "2026-06-08T18:15:27.790Z" |
| 475 | +#define SQLITE_SCM_DATETIME "2026-06-16T13:43:08.110Z" |
| 476 | 476 | |
| 477 | 477 | /* |
| 478 | 478 | ** CAPI3REF: Run-Time Library Version Numbers |
| 479 | 479 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 480 | 480 | ** |
| | @@ -4696,11 +4696,12 @@ |
| 4696 | 4696 | ** <dd>The maximum number of columns in a table definition or in the |
| 4697 | 4697 | ** result set of a [SELECT] or the maximum number of columns in an index |
| 4698 | 4698 | ** or in an ORDER BY or GROUP BY clause.</dd>)^ |
| 4699 | 4699 | ** |
| 4700 | 4700 | ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt> |
| 4701 | | -** <dd>The maximum depth of the parse tree on any expression.</dd>)^ |
| 4701 | +** <dd>The maximum depth of the parse tree on any expression and |
| 4702 | +** the maximum nesting depth for subqueries and VIEWs</dd>)^ |
| 4702 | 4703 | ** |
| 4703 | 4704 | ** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt> |
| 4704 | 4705 | ** <dd>The maximum depth of the LALR(1) parser stack used to analyze |
| 4705 | 4706 | ** input SQL statements.</dd>)^ |
| 4706 | 4707 | ** |
| | @@ -4727,11 +4728,12 @@ |
| 4727 | 4728 | ** [[SQLITE_LIMIT_VARIABLE_NUMBER]] |
| 4728 | 4729 | ** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt> |
| 4729 | 4730 | ** <dd>The maximum index number of any [parameter] in an SQL statement.)^ |
| 4730 | 4731 | ** |
| 4731 | 4732 | ** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt> |
| 4732 | | -** <dd>The maximum depth of recursion for triggers.</dd>)^ |
| 4733 | +** <dd>The maximum depth of recursion for triggers, and the maximum |
| 4734 | +** nesting depth for separate triggers.</dd>)^ |
| 4733 | 4735 | ** |
| 4734 | 4736 | ** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt> |
| 4735 | 4737 | ** <dd>The maximum number of auxiliary worker threads that a single |
| 4736 | 4738 | ** [prepared statement] may start.</dd>)^ |
| 4737 | 4739 | ** </dl> |
| | @@ -11533,12 +11535,23 @@ |
| 11533 | 11535 | ** reopen S as an in-memory database based on the serialization |
| 11534 | 11536 | ** contained in P. If S is a NULL pointer, the main database is |
| 11535 | 11537 | ** used. The serialized database P is N bytes in size. M is the size |
| 11536 | 11538 | ** of the buffer P, which might be larger than N. If M is larger than |
| 11537 | 11539 | ** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then |
| 11538 | | -** SQLite is permitted to add content to the in-memory database as |
| 11539 | | -** long as the total size does not exceed M bytes. |
| 11540 | +** SQLite is permitted to add content to the in-memory database, in |
| 11541 | +** page-sized chunks, as long as the total size does not exceed M bytes. |
| 11542 | +** |
| 11543 | +** The parameter M must be greater than or equal to N. Ideally, M |
| 11544 | +** should have a value which is N+(512×K)+20 where K determines how |
| 11545 | +** must extra space is available to hold new content as the database |
| 11546 | +** grows. K can be 0 if the database is read-only. |
| 11547 | +** |
| 11548 | +** If the database content in P is malformed in a malicious way then |
| 11549 | +** it is possible that SQLite might try to read a few more than N bytes |
| 11550 | +** from P. If the veracity of the database content P is uncertain, |
| 11551 | +** then applications are advised to allocate about 20 extra bytes on |
| 11552 | +** the end of the P buffer to avoid a memory error. |
| 11540 | 11553 | ** |
| 11541 | 11554 | ** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will |
| 11542 | 11555 | ** invoke sqlite3_free() on the serialization buffer when the database |
| 11543 | 11556 | ** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then |
| 11544 | 11557 | ** SQLite will try to increase the buffer size using sqlite3_realloc64() |
| | @@ -15809,10 +15822,17 @@ |
| 15809 | 15822 | */ |
| 15810 | 15823 | #ifndef offsetof |
| 15811 | 15824 | # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) |
| 15812 | 15825 | #endif |
| 15813 | 15826 | |
| 15827 | +/* |
| 15828 | +** sizeof64() is like sizeof(), but always returns a 64-bit value, even |
| 15829 | +** on 32-bit builds. This can help to avoid overflow by ensuring 64-bit |
| 15830 | +** arithmetic is used consistently in both 32-bit and 64-bit builds. |
| 15831 | +*/ |
| 15832 | +#define sizeof64(X) ((sqlite3_int64)sizeof(X)) |
| 15833 | + |
| 15814 | 15834 | /* |
| 15815 | 15835 | ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as |
| 15816 | 15836 | ** to avoid complaints from -fsanitize=strict-bounds. |
| 15817 | 15837 | */ |
| 15818 | 15838 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| | @@ -20928,10 +20948,11 @@ |
| 20928 | 20948 | int nTab; /* Number of previously allocated VDBE cursors */ |
| 20929 | 20949 | int nMem; /* Number of memory cells used so far */ |
| 20930 | 20950 | int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ |
| 20931 | 20951 | int iSelfTab; /* Table associated with an index on expr, or negative |
| 20932 | 20952 | ** of the base register during check-constraint eval */ |
| 20953 | + int nNestSel; /* Number of nested SELECT statements and/or VIEWs */ |
| 20933 | 20954 | int nLabel; /* The *negative* of the number of labels used */ |
| 20934 | 20955 | int nLabelAlloc; /* Number of slots in aLabel */ |
| 20935 | 20956 | int *aLabel; /* Space to hold the labels */ |
| 20936 | 20957 | ExprList *pConstExpr;/* Constant expressions */ |
| 20937 | 20958 | IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ |
| | @@ -39255,10 +39276,26 @@ |
| 39255 | 39276 | ****************************************************************************** |
| 39256 | 39277 | ** |
| 39257 | 39278 | ** This file contains an experimental VFS layer that operates on a |
| 39258 | 39279 | ** Key/Value storage engine where both keys and values must be pure |
| 39259 | 39280 | ** text. |
| 39281 | +** |
| 39282 | +** DEBUG AND TEST |
| 39283 | +** |
| 39284 | +** For testing on Unix, compile using: |
| 39285 | +** |
| 39286 | +** make clean sqlite3d CFLAGS='-DSQLITE_OS_KV_OPTIONAL' |
| 39287 | +** |
| 39288 | +** Then start up a shell using something like: |
| 39289 | +** |
| 39290 | +** ./sqlite3d 'file:dbname?vfs=kvvfs' |
| 39291 | +** |
| 39292 | +** Each K/V entry is stored in a separate file in the working |
| 39293 | +** directory that has a name like "kvvfs-dbname-*". Due to limitations |
| 39294 | +** on the key size, the name of the database must be very short - just |
| 39295 | +** a few characters. If the database name is too long, the VFS will |
| 39296 | +** malfunction and you will get SQLITE_CORRUPT errors. |
| 39260 | 39297 | */ |
| 39261 | 39298 | /* #include <sqliteInt.h> */ |
| 39262 | 39299 | #if SQLITE_OS_KV || (SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL)) |
| 39263 | 39300 | |
| 39264 | 39301 | /***************************************************************************** |
| | @@ -39707,16 +39744,18 @@ |
| 39707 | 39744 | } |
| 39708 | 39745 | if( j+n>nOut ) return -1; |
| 39709 | 39746 | memset(&aOut[j], 0, n); |
| 39710 | 39747 | j += n; |
| 39711 | 39748 | if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */ |
| 39712 | | - }else{ |
| 39749 | + }else if( j<nOut ){ |
| 39713 | 39750 | aOut[j] = c<<4; |
| 39714 | 39751 | c = kvvfsHexValue[aIn[++i]]; |
| 39715 | 39752 | if( c<0 ) return -1 /* hex bytes are always in pairs */; |
| 39716 | 39753 | aOut[j++] += c; |
| 39717 | 39754 | i++; |
| 39755 | + }else{ |
| 39756 | + return -1; |
| 39718 | 39757 | } |
| 39719 | 39758 | } |
| 39720 | 39759 | return j; |
| 39721 | 39760 | } |
| 39722 | 39761 | |
| | @@ -40138,10 +40177,22 @@ |
| 40138 | 40177 | }else{ |
| 40139 | 40178 | pFile->isJournal = 0; |
| 40140 | 40179 | pFile->base.pMethods = &kvvfs_db_io_methods; |
| 40141 | 40180 | } |
| 40142 | 40181 | if( !pFile->zClass ){ |
| 40182 | +#ifdef SQLITE_WASM |
| 40183 | + if( strlen(zName) >= (KVRECORD_KEY_SZ |
| 40184 | + - 6 /* "kvvfs-" */ |
| 40185 | + - 11 /* "-##########" */) ){ |
| 40186 | + return SQLITE_CANTOPEN; |
| 40187 | + } |
| 40188 | +#else |
| 40189 | + if( 0!=strcmp(zName, "local") && 0!=strcmp(zName, "session") ){ |
| 40190 | + /* Historical naming restriction which journaling depends on. */ |
| 40191 | + return SQLITE_CANTOPEN; |
| 40192 | + } |
| 40193 | +#endif |
| 40143 | 40194 | pFile->zClass = zName; |
| 40144 | 40195 | } |
| 40145 | 40196 | pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ); |
| 40146 | 40197 | if( pFile->aData==0 ){ |
| 40147 | 40198 | return SQLITE_NOMEM; |
| | @@ -52170,15 +52221,33 @@ |
| 52170 | 52221 | # define sqlite3_win_test_unc_locking 0 |
| 52171 | 52222 | #endif |
| 52172 | 52223 | |
| 52173 | 52224 | /* |
| 52174 | 52225 | ** Return true if the string passed as the only argument is likely |
| 52175 | | -** to be a UNC path. In other words, if it starts with "\\". |
| 52226 | +** to be a UNC path. Return false if note. |
| 52227 | +** |
| 52228 | +** Return true if: |
| 52229 | +** |
| 52230 | +** (1) The name begins with "\\" |
| 52231 | +** (2) But does not begin with "\\?\C:\" where C can be any alphabetic |
| 52232 | +** character. |
| 52233 | +** |
| 52234 | +** For testing, also return true in all cases if the global variable |
| 52235 | +** sqlite3_win_test_unc_locking is true. |
| 52176 | 52236 | */ |
| 52177 | 52237 | static int winIsUNCPath(const char *zFile){ |
| 52178 | 52238 | if( zFile[0]=='\\' && zFile[1]=='\\' ){ |
| 52179 | | - return 1; |
| 52239 | + if( zFile[2]=='?' |
| 52240 | + && zFile[3]=='\\' |
| 52241 | + && sqlite3Isalpha(zFile[4]) |
| 52242 | + && zFile[5]==':' |
| 52243 | + && winIsDirSep(zFile[6]) |
| 52244 | + ){ |
| 52245 | + return sqlite3_win_test_unc_locking; |
| 52246 | + }else{ |
| 52247 | + return 1; |
| 52248 | + } |
| 52180 | 52249 | } |
| 52181 | 52250 | return sqlite3_win_test_unc_locking; |
| 52182 | 52251 | } |
| 52183 | 52252 | |
| 52184 | 52253 | /* |
| | @@ -59841,73 +59910,84 @@ |
| 59841 | 59910 | #define pager_set_pagehash(X) |
| 59842 | 59911 | #define CHECK_PAGE(x) |
| 59843 | 59912 | #endif /* SQLITE_CHECK_PAGES */ |
| 59844 | 59913 | |
| 59845 | 59914 | /* |
| 59846 | | -** When this is called the journal file for pager pPager must be open. |
| 59847 | | -** This function attempts to read a super-journal file name from the |
| 59848 | | -** end of the file and, if successful, copies it into memory supplied |
| 59849 | | -** by the caller. See comments above writeSuperJournal() for the format |
| 59850 | | -** used to store a super-journal file name at the end of a journal file. |
| 59851 | | -** |
| 59852 | | -** zSuper must point to a buffer of at least nSuper bytes allocated by |
| 59853 | | -** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is |
| 59854 | | -** enough space to write the super-journal name). If the super-journal |
| 59855 | | -** name in the journal is longer than nSuper bytes (including a |
| 59856 | | -** nul-terminator), then this is handled as if no super-journal name |
| 59857 | | -** were present in the journal. |
| 59858 | | -** |
| 59859 | | -** If a super-journal file name is present at the end of the journal |
| 59860 | | -** file, then it is copied into the buffer pointed to by zSuper. A |
| 59861 | | -** nul-terminator byte is appended to the buffer following the |
| 59862 | | -** super-journal file name. |
| 59863 | | -** |
| 59864 | | -** If it is determined that no super-journal file name is present |
| 59865 | | -** zSuper[0] is set to 0 and SQLITE_OK returned. |
| 59866 | | -** |
| 59867 | | -** If an error occurs while reading from the journal file, an SQLite |
| 59868 | | -** error code is returned. |
| 59869 | | -*/ |
| 59870 | | -static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u64 nSuper){ |
| 59915 | +** Free a buffer allocated by the readSuperJournal() function. |
| 59916 | +*/ |
| 59917 | +static void freeSuperJournal(char *zSuper){ |
| 59918 | + if( zSuper ){ |
| 59919 | + sqlite3_free(&zSuper[-4]); |
| 59920 | + } |
| 59921 | +} |
| 59922 | + |
| 59923 | +/* |
| 59924 | +** Parameter pJrnl is a file-handle open on a journal file. This function |
| 59925 | +** attempts to read a super-journal file name from the end of the journal |
| 59926 | +** file. If successful, it sets output parameter (*pzSuper) to point to a |
| 59927 | +** buffer containing the super-journal name as a nul-terminated string. |
| 59928 | +** The caller is responsible for freeing the buffer using freeSuperJournal(). |
| 59929 | +** |
| 59930 | +** Refer to comments above writeSuperJournal() for the format used to store |
| 59931 | +** a super-journal file name at the end of a journal file. |
| 59932 | +** |
| 59933 | +** Parameter nSuper is passed the maximum allowable size of the super journal |
| 59934 | +** name in bytes. If the super-journal name in the journal is longer than |
| 59935 | +** nSuper bytes (including a nul-terminator), then this is handled as if no |
| 59936 | +** super-journal name were present in the journal. |
| 59937 | +** |
| 59938 | +** If there is no super-journal name at the end of pJrnl, (*pzSuper) is |
| 59939 | +** set to 0 and SQLITE_OK is returned. Or, if an error occurs while reading |
| 59940 | +** the super-journal name, an SQLite error code is returned and (*pzSuper) |
| 59941 | +** is set to 0. |
| 59942 | +*/ |
| 59943 | +static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){ |
| 59871 | 59944 | int rc; /* Return code */ |
| 59872 | 59945 | u32 len; /* Length in bytes of super-journal name */ |
| 59873 | 59946 | i64 szJ; /* Total size in bytes of journal file pJrnl */ |
| 59874 | 59947 | u32 cksum; /* MJ checksum value read from journal */ |
| 59875 | | - u32 u; /* Unsigned loop counter */ |
| 59876 | 59948 | unsigned char aMagic[8]; /* A buffer to hold the magic header */ |
| 59877 | | - zSuper[0] = '\0'; |
| 59949 | + char *zOut = 0; |
| 59878 | 59950 | |
| 59951 | + *pzSuper = 0; |
| 59879 | 59952 | if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) |
| 59880 | 59953 | || szJ<16 |
| 59881 | 59954 | || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) |
| 59882 | 59955 | || len>=nSuper |
| 59883 | 59956 | || len>szJ-16 |
| 59884 | 59957 | || len==0 |
| 59885 | 59958 | || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) |
| 59886 | 59959 | || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) |
| 59887 | 59960 | || memcmp(aMagic, aJournalMagic, 8) |
| 59888 | | - || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zSuper, len, szJ-16-len)) |
| 59889 | 59961 | ){ |
| 59890 | 59962 | return rc; |
| 59891 | 59963 | } |
| 59892 | 59964 | |
| 59893 | | - /* See if the checksum matches the super-journal name */ |
| 59894 | | - for(u=0; u<len; u++){ |
| 59895 | | - cksum -= zSuper[u]; |
| 59896 | | - } |
| 59897 | | - if( cksum ){ |
| 59898 | | - /* If the checksum doesn't add up, then one or more of the disk sectors |
| 59899 | | - ** containing the super-journal filename is corrupted. This means |
| 59900 | | - ** definitely roll back, so just return SQLITE_OK and report a (nul) |
| 59901 | | - ** super-journal filename. |
| 59902 | | - */ |
| 59903 | | - len = 0; |
| 59904 | | - } |
| 59905 | | - zSuper[len] = '\0'; |
| 59906 | | - zSuper[len+1] = '\0'; |
| 59907 | | - |
| 59908 | | - return SQLITE_OK; |
| 59965 | + zOut = (char*)sqlite3MallocZero(4 + len + 2); |
| 59966 | + if( !zOut ){ |
| 59967 | + rc = SQLITE_NOMEM_BKPT; |
| 59968 | + }else{ |
| 59969 | + zOut = &zOut[4]; |
| 59970 | + if( SQLITE_OK==(rc = sqlite3OsRead(pJrnl, zOut, len, szJ-16-len)) ){ |
| 59971 | + u32 u; /* Unsigned loop counter */ |
| 59972 | + /* See if the checksum matches the super-journal name */ |
| 59973 | + for(u=0; u<len; u++){ |
| 59974 | + cksum -= zOut[u]; |
| 59975 | + } |
| 59976 | + } |
| 59977 | + if( rc!=SQLITE_OK || cksum ){ |
| 59978 | + /* If the checksum doesn't add up, then one or more of the disk sectors |
| 59979 | + ** containing the super-journal filename is corrupted. This means |
| 59980 | + ** definitely roll back, so just return SQLITE_OK and report a (nul) |
| 59981 | + ** super-journal filename. */ |
| 59982 | + freeSuperJournal(zOut); |
| 59983 | + zOut = 0; |
| 59984 | + } |
| 59985 | + } |
| 59986 | + |
| 59987 | + *pzSuper = zOut; |
| 59988 | + return rc; |
| 59909 | 59989 | } |
| 59910 | 59990 | |
| 59911 | 59991 | /* |
| 59912 | 59992 | ** Return the offset of the sector boundary at or immediately |
| 59913 | 59993 | ** following the value in pPager->journalOff, assuming a sector |
| | @@ -61108,13 +61188,11 @@ |
| 61108 | 61188 | sqlite3_file *pSuper; /* Malloc'd super-journal file descriptor */ |
| 61109 | 61189 | sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ |
| 61110 | 61190 | char *zSuperJournal = 0; /* Contents of super-journal file */ |
| 61111 | 61191 | i64 nSuperJournal; /* Size of super-journal file */ |
| 61112 | 61192 | char *zJournal; /* Pointer to one journal within MJ file */ |
| 61113 | | - char *zSuperPtr; /* Space to hold super-journal filename */ |
| 61114 | 61193 | char *zFree = 0; /* Free this buffer */ |
| 61115 | | - i64 nSuperPtr; /* Amount of space allocated to zSuperPtr[] */ |
| 61116 | 61194 | |
| 61117 | 61195 | /* Allocate space for both the pJournal and pSuper file descriptors. |
| 61118 | 61196 | ** If successful, open the super-journal file for reading. |
| 61119 | 61197 | */ |
| 61120 | 61198 | pSuper = (sqlite3_file *)sqlite3MallocZero(2 * (i64)pVfs->szOsFile); |
| | @@ -61133,22 +61211,20 @@ |
| 61133 | 61211 | ** sufficient space (in zSuperPtr) to hold the names of super-journal |
| 61134 | 61212 | ** files extracted from regular rollback-journals. |
| 61135 | 61213 | */ |
| 61136 | 61214 | rc = sqlite3OsFileSize(pSuper, &nSuperJournal); |
| 61137 | 61215 | if( rc!=SQLITE_OK ) goto delsuper_out; |
| 61138 | | - nSuperPtr = 1 + (i64)pVfs->mxPathname; |
| 61139 | | - assert( nSuperJournal>=0 && nSuperPtr>0 ); |
| 61140 | | - zFree = sqlite3Malloc(4 + nSuperJournal + 2 + nSuperPtr + 2); |
| 61216 | + assert( nSuperJournal>=0 ); |
| 61217 | + zFree = sqlite3Malloc(4 + nSuperJournal + 2); |
| 61141 | 61218 | if( !zFree ){ |
| 61142 | 61219 | rc = SQLITE_NOMEM_BKPT; |
| 61143 | 61220 | goto delsuper_out; |
| 61144 | 61221 | }else{ |
| 61145 | 61222 | assert( nSuperJournal<=0x7fffffff ); |
| 61146 | 61223 | } |
| 61147 | 61224 | zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0; |
| 61148 | 61225 | zSuperJournal = &zFree[4]; |
| 61149 | | - zSuperPtr = &zSuperJournal[nSuperJournal+2]; |
| 61150 | 61226 | rc = sqlite3OsRead(pSuper, zSuperJournal, (int)nSuperJournal, 0); |
| 61151 | 61227 | if( rc!=SQLITE_OK ) goto delsuper_out; |
| 61152 | 61228 | zSuperJournal[nSuperJournal] = 0; |
| 61153 | 61229 | zSuperJournal[nSuperJournal+1] = 0; |
| 61154 | 61230 | |
| | @@ -61158,10 +61234,12 @@ |
| 61158 | 61234 | rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists); |
| 61159 | 61235 | if( rc!=SQLITE_OK ){ |
| 61160 | 61236 | goto delsuper_out; |
| 61161 | 61237 | } |
| 61162 | 61238 | if( exists ){ |
| 61239 | + char *zSuperPtr = 0; |
| 61240 | + |
| 61163 | 61241 | /* One of the journals pointed to by the super-journal exists. |
| 61164 | 61242 | ** Open it and check if it points at the super-journal. If |
| 61165 | 61243 | ** so, return without deleting the super-journal file. |
| 61166 | 61244 | ** NB: zJournal is really a MAIN_JOURNAL. But call it a |
| 61167 | 61245 | ** SUPER_JOURNAL here so that the VFS will not send the zJournal |
| | @@ -61172,17 +61250,19 @@ |
| 61172 | 61250 | rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); |
| 61173 | 61251 | if( rc!=SQLITE_OK ){ |
| 61174 | 61252 | goto delsuper_out; |
| 61175 | 61253 | } |
| 61176 | 61254 | |
| 61177 | | - rc = readSuperJournal(pJournal, zSuperPtr, nSuperPtr); |
| 61255 | + rc = readSuperJournal(pJournal, 1+(u64)pVfs->mxPathname, &zSuperPtr); |
| 61178 | 61256 | sqlite3OsClose(pJournal); |
| 61179 | 61257 | if( rc!=SQLITE_OK ){ |
| 61258 | + assert( zSuperPtr==0 ); |
| 61180 | 61259 | goto delsuper_out; |
| 61181 | 61260 | } |
| 61182 | 61261 | |
| 61183 | | - c = zSuperPtr[0]!=0 && strcmp(zSuperPtr, zSuper)==0; |
| 61262 | + c = zSuperPtr!=0 && strcmp(zSuperPtr, zSuper)==0; |
| 61263 | + freeSuperJournal(zSuperPtr); |
| 61184 | 61264 | if( c ){ |
| 61185 | 61265 | /* We have a match. Do not delete the super-journal file. */ |
| 61186 | 61266 | goto delsuper_out; |
| 61187 | 61267 | } |
| 61188 | 61268 | } |
| | @@ -61393,23 +61473,15 @@ |
| 61393 | 61473 | |
| 61394 | 61474 | /* Read the super-journal name from the journal, if it is present. |
| 61395 | 61475 | ** If a super-journal file name is specified, but the file is not |
| 61396 | 61476 | ** present on disk, then the journal is not hot and does not need to be |
| 61397 | 61477 | ** played back. |
| 61398 | | - ** |
| 61399 | | - ** TODO: Technically the following is an error because it assumes that |
| 61400 | | - ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that |
| 61401 | | - ** ((pPager->pageSize+8) >= pPager->pVfs->mxPathname+1). Using os_unix.c, |
| 61402 | | - ** mxPathname is 512, which is the same as the minimum allowable value |
| 61403 | | - ** for pageSize, and so this assumption holds. But it might not for some |
| 61404 | | - ** custom VFS. */ |
| 61405 | | - zSuper = pPager->pTmpSpace; |
| 61406 | | - rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname); |
| 61407 | | - if( rc==SQLITE_OK && zSuper[0] ){ |
| 61478 | + */ |
| 61479 | + rc = readSuperJournal(pPager->jfd, 1+(i64)pPager->pVfs->mxPathname, &zSuper); |
| 61480 | + if( rc==SQLITE_OK && zSuper ){ |
| 61408 | 61481 | rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res); |
| 61409 | 61482 | } |
| 61410 | | - zSuper = 0; |
| 61411 | 61483 | if( rc!=SQLITE_OK || !res ){ |
| 61412 | 61484 | goto end_playback; |
| 61413 | 61485 | } |
| 61414 | 61486 | pPager->journalOff = 0; |
| 61415 | 61487 | needPagerReset = isHot; |
| | @@ -61534,34 +61606,24 @@ |
| 61534 | 61606 | ** problems for other processes at some point in the future. So, just |
| 61535 | 61607 | ** in case this has happened, clear the changeCountDone flag now. |
| 61536 | 61608 | */ |
| 61537 | 61609 | pPager->changeCountDone = pPager->tempFile; |
| 61538 | 61610 | |
| 61539 | | - if( rc==SQLITE_OK ){ |
| 61540 | | - /* Leave 4 bytes of space before the super-journal filename in memory. |
| 61541 | | - ** This is because it may end up being passed to sqlite3OsOpen(), in |
| 61542 | | - ** which case it requires 4 0x00 bytes in memory immediately before |
| 61543 | | - ** the filename. */ |
| 61544 | | - zSuper = &pPager->pTmpSpace[4]; |
| 61545 | | - rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname); |
| 61546 | | - testcase( rc!=SQLITE_OK ); |
| 61547 | | - } |
| 61548 | 61611 | if( rc==SQLITE_OK |
| 61549 | 61612 | && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) |
| 61550 | 61613 | ){ |
| 61551 | 61614 | rc = sqlite3PagerSync(pPager, 0); |
| 61552 | 61615 | } |
| 61553 | 61616 | if( rc==SQLITE_OK ){ |
| 61554 | | - rc = pager_end_transaction(pPager, zSuper[0]!='\0', 0); |
| 61617 | + rc = pager_end_transaction(pPager, zSuper!=0, 0); |
| 61555 | 61618 | testcase( rc!=SQLITE_OK ); |
| 61556 | 61619 | } |
| 61557 | | - if( rc==SQLITE_OK && zSuper[0] && res ){ |
| 61620 | + if( rc==SQLITE_OK && zSuper && res ){ |
| 61558 | 61621 | /* If there was a super-journal and this routine will return success, |
| 61559 | 61622 | ** see if it is possible to delete the super-journal. |
| 61560 | 61623 | */ |
| 61561 | | - assert( zSuper==&pPager->pTmpSpace[4] ); |
| 61562 | | - memset(pPager->pTmpSpace, 0, 4); |
| 61624 | + assert( memcmp(&zSuper[-4], "\0\0\0\0", 4)==0 ); |
| 61563 | 61625 | rc = pager_delsuper(pPager, zSuper); |
| 61564 | 61626 | testcase( rc!=SQLITE_OK ); |
| 61565 | 61627 | } |
| 61566 | 61628 | if( isHot && nPlayback ){ |
| 61567 | 61629 | sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s", |
| | @@ -61570,10 +61632,11 @@ |
| 61570 | 61632 | |
| 61571 | 61633 | /* The Pager.sectorSize variable may have been updated while rolling |
| 61572 | 61634 | ** back a journal created by a process with a different sector size |
| 61573 | 61635 | ** value. Reset it to the correct value for this process. |
| 61574 | 61636 | */ |
| 61637 | + freeSuperJournal(zSuper); |
| 61575 | 61638 | setSectorSize(pPager); |
| 61576 | 61639 | return rc; |
| 61577 | 61640 | } |
| 61578 | 61641 | |
| 61579 | 61642 | |
| | @@ -67428,10 +67491,16 @@ |
| 67428 | 67491 | */ |
| 67429 | 67492 | pgno = sqlite3Get4byte(&aFrame[0]); |
| 67430 | 67493 | if( pgno==0 ){ |
| 67431 | 67494 | return 0; |
| 67432 | 67495 | } |
| 67496 | + |
| 67497 | + /* Need a valid page size |
| 67498 | + */ |
| 67499 | + if( !pWal->szPage ){ |
| 67500 | + return 0; |
| 67501 | + } |
| 67433 | 67502 | |
| 67434 | 67503 | /* A frame is only valid if a checksum of the WAL header, |
| 67435 | 67504 | ** all prior frames, the first 16 bytes of this frame-header, |
| 67436 | 67505 | ** and the frame-data matches the checksum in the last 8 |
| 67437 | 67506 | ** bytes of this frame-header. |
| | @@ -69283,11 +69352,11 @@ |
| 69283 | 69352 | goto begin_unreliable_shm_out; |
| 69284 | 69353 | } |
| 69285 | 69354 | |
| 69286 | 69355 | /* Allocate a buffer to read frames into */ |
| 69287 | 69356 | assert( (pWal->szPage & (pWal->szPage-1))==0 ); |
| 69288 | | - assert( pWal->szPage>=512 && pWal->szPage<=65536 ); |
| 69357 | + assert( (pWal->szPage>=512 && pWal->szPage<=65536) || pWal->szPage==0 ); |
| 69289 | 69358 | szFrame = pWal->szPage + WAL_FRAME_HDRSIZE; |
| 69290 | 69359 | aFrame = (u8 *)sqlite3_malloc64(szFrame); |
| 69291 | 69360 | if( aFrame==0 ){ |
| 69292 | 69361 | rc = SQLITE_NOMEM_BKPT; |
| 69293 | 69362 | goto begin_unreliable_shm_out; |
| | @@ -103044,11 +103113,11 @@ |
| 103044 | 103113 | if( pFrame ) break; |
| 103045 | 103114 | } |
| 103046 | 103115 | |
| 103047 | 103116 | if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ |
| 103048 | 103117 | rc = SQLITE_ERROR; |
| 103049 | | - sqlite3VdbeError(p, "too many levels of trigger recursion"); |
| 103118 | + sqlite3VdbeError(p, "triggers nested too deep"); |
| 103050 | 103119 | goto abort_due_to_error; |
| 103051 | 103120 | } |
| 103052 | 103121 | |
| 103053 | 103122 | /* Register pRt is used to store the memory required to save the state |
| 103054 | 103123 | ** of the current program, and the memory required at runtime to execute |
| | @@ -124393,21 +124462,21 @@ |
| 124393 | 124462 | }else{ |
| 124394 | 124463 | nIdxCol = pIdx->nColumn; |
| 124395 | 124464 | } |
| 124396 | 124465 | pIdx->nSampleCol = nIdxCol; |
| 124397 | 124466 | pIdx->mxSample = nSample; |
| 124398 | | - nByte = ROUND8(sizeof(IndexSample) * nSample); |
| 124399 | | - nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; |
| 124400 | | - nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ |
| 124467 | + nByte = ROUND8(sizeof64(IndexSample) * nSample); |
| 124468 | + nByte += sizeof64(tRowcnt) * nIdxCol * 3 * nSample; |
| 124469 | + nByte += nIdxCol * sizeof64(tRowcnt); /* Space for Index.aAvgEq[] */ |
| 124401 | 124470 | |
| 124402 | 124471 | pIdx->aSample = sqlite3DbMallocZero(db, nByte); |
| 124403 | 124472 | if( pIdx->aSample==0 ){ |
| 124404 | 124473 | sqlite3_finalize(pStmt); |
| 124405 | 124474 | return SQLITE_NOMEM_BKPT; |
| 124406 | 124475 | } |
| 124407 | 124476 | pPtr = (u8*)pIdx->aSample; |
| 124408 | | - pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0])); |
| 124477 | + pPtr += ROUND8(nSample*sizeof64(pIdx->aSample[0])); |
| 124409 | 124478 | pSpace = (tRowcnt*)pPtr; |
| 124410 | 124479 | assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); |
| 124411 | 124480 | pIdx->aAvgEq = pSpace; pSpace += nIdxCol; |
| 124412 | 124481 | pIdx->pTable->tabFlags |= TF_HasStat4; |
| 124413 | 124482 | for(i=0; i<nSample; i++){ |
| | @@ -134442,11 +134511,11 @@ |
| 134442 | 134511 | int nStr; /* Size of zStr */ |
| 134443 | 134512 | int nPattern; /* Size of zPattern */ |
| 134444 | 134513 | int nRep; /* Size of zRep */ |
| 134445 | 134514 | i64 nOut; /* Maximum size of zOut */ |
| 134446 | 134515 | int loopLimit; /* Last zStr[] that might match zPattern[] */ |
| 134447 | | - int i, j; /* Loop counters */ |
| 134516 | + i64 i, j; /* Loop counters */ |
| 134448 | 134517 | unsigned cntExpand; /* Number zOut expansions */ |
| 134449 | 134518 | sqlite3 *db = sqlite3_context_db_handle(context); |
| 134450 | 134519 | |
| 134451 | 134520 | assert( argc==3 ); |
| 134452 | 134521 | UNUSED_PARAMETER(argc); |
| | @@ -135896,12 +135965,21 @@ |
| 135896 | 135965 | ** from the standard library because: |
| 135897 | 135966 | ** |
| 135898 | 135967 | ** (1) To avoid a dependency on qsort() |
| 135899 | 135968 | ** (2) To avoid the function call to the comparison routine for each |
| 135900 | 135969 | ** comparison. |
| 135970 | +** |
| 135971 | +** If parameter iReq is non-negative, then the caller will only access |
| 135972 | +** elements a[iReq] and a[iReq+1] (if it exists) of the sorted array and |
| 135973 | +** so it is not necessary to position any other elements. Or if iReq is |
| 135974 | +** negative, then the final array must be fully sorted. |
| 135901 | 135975 | */ |
| 135902 | | -static void percentSort(double *a, unsigned int n){ |
| 135976 | +static void percentSort( |
| 135977 | + double *a, /* Array to sort */ |
| 135978 | + unsigned int n, /* Number of elements in array a[] */ |
| 135979 | + int iReq /* Element caller cares about (or -ve) */ |
| 135980 | +){ |
| 135903 | 135981 | int iLt; /* Entries before a[iLt] are less than rPivot */ |
| 135904 | 135982 | int iGt; /* Entries at or after a[iGt] are greater than rPivot */ |
| 135905 | 135983 | int i; /* Loop counter */ |
| 135906 | 135984 | double rPivot; /* The pivot value */ |
| 135907 | 135985 | |
| | @@ -135934,21 +136012,45 @@ |
| 135934 | 136012 | }else{ |
| 135935 | 136013 | i++; |
| 135936 | 136014 | } |
| 135937 | 136015 | }while( i<iGt ); |
| 135938 | 136016 | |
| 135939 | | - /* Recurse on the smaller partition only. The smaller partition |
| 135940 | | - ** will hold n/2 or fewer entries, which assures that the stack |
| 135941 | | - ** depth will not exceed O(log(n)), even for pathological cases. |
| 135942 | | - ** Loop without recursion for the larger partition. */ |
| 135943 | | - if( iLt>n/2 ){ |
| 135944 | | - if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); |
| 135945 | | - n = iLt; |
| 136017 | + assert( a[iLt]==rPivot ); |
| 136018 | + assert( iGt>iLt ); |
| 136019 | + |
| 136020 | + if( iReq>=0 ){ |
| 136021 | + /* In this case, the only elements that the caller requires sorted into |
| 136022 | + ** the correct positions are elements a[iReq] and a[iReq+1]. At this |
| 136023 | + ** point we know that element a[iLt] is in the correct position and |
| 136024 | + ** all elements smaller than a[iLt] are in the left-hand partition. |
| 136025 | + ** So if (iReq<iLt), then it is only necessary to sort the left |
| 136026 | + ** partition. |
| 136027 | + ** |
| 136028 | + ** If (iReq>=iLt), then elements iReq and iReq+1 are either in the |
| 136029 | + ** right partition or the equal partition (elements for which |
| 136030 | + ** iLt<=iElem<iGt). Therefore it is always sufficient to sort only |
| 136031 | + ** the right partition in this case. */ |
| 136032 | + if( iReq<iLt ){ |
| 136033 | + n = iLt; |
| 136034 | + }else{ |
| 136035 | + a += iGt; |
| 136036 | + n -= iGt; |
| 136037 | + iReq = MAX(0, iReq-iGt); |
| 136038 | + } |
| 135946 | 136039 | }else{ |
| 135947 | | - if( iLt>=2 ) percentSort(a, iLt); |
| 135948 | | - a += iGt; |
| 135949 | | - n -= iGt; |
| 136040 | + /* Recurse on the smaller partition only. The smaller partition |
| 136041 | + ** will hold n/2 or fewer entries, which assures that the stack |
| 136042 | + ** depth will not exceed O(log(n)), even for pathological cases. |
| 136043 | + ** Loop without recursion for the larger partition. */ |
| 136044 | + if( iLt>(int)(n/2) ){ |
| 136045 | + if( n-iGt>=2 ) percentSort(a+iGt, n-iGt, -1); |
| 136046 | + n = iLt; |
| 136047 | + }else{ |
| 136048 | + if( iLt>=2 ) percentSort(a, iLt, -1); |
| 136049 | + a += iGt; |
| 136050 | + n -= iGt; |
| 136051 | + } |
| 135950 | 136052 | } |
| 135951 | 136053 | }while( n>=2 ); |
| 135952 | 136054 | } |
| 135953 | 136055 | |
| 135954 | 136056 | /* |
| | @@ -135981,11 +136083,11 @@ |
| 135981 | 136083 | if( percentIsInfinity(y) ){ |
| 135982 | 136084 | return; |
| 135983 | 136085 | } |
| 135984 | 136086 | if( p->bSorted==0 ){ |
| 135985 | 136087 | assert( p->nUsed>1 ); |
| 135986 | | - percentSort(p->a, p->nUsed); |
| 136088 | + percentSort(p->a, p->nUsed, -1); |
| 135987 | 136089 | p->bSorted = 1; |
| 135988 | 136090 | } |
| 135989 | 136091 | p->bKeepSorted = 1; |
| 135990 | 136092 | |
| 135991 | 136093 | /* Find and remove the row */ |
| | @@ -136010,17 +136112,21 @@ |
| 136010 | 136112 | double ix, vx; |
| 136011 | 136113 | p = (Percentile*)sqlite3_aggregate_context(pCtx, 0); |
| 136012 | 136114 | if( p==0 ) return; |
| 136013 | 136115 | if( p->a==0 ) return; |
| 136014 | 136116 | if( p->nUsed ){ |
| 136117 | + ix = p->rPct*(p->nUsed-1); |
| 136118 | + i1 = (unsigned)ix; |
| 136015 | 136119 | if( p->bSorted==0 ){ |
| 136120 | + /* In cases where bIsFinal is non-zero, setting Percentile.bSorted |
| 136121 | + ** after the percentSort() call here is not technically correct, as |
| 136122 | + ** the array is not fully sorted. But in this case the object will be |
| 136123 | + ** freed below anyway, so it doesn't matter. */ |
| 136016 | 136124 | assert( p->nUsed>1 ); |
| 136017 | | - percentSort(p->a, p->nUsed); |
| 136125 | + percentSort(p->a, p->nUsed, (bIsFinal ? (int)i1 : -1)); |
| 136018 | 136126 | p->bSorted = 1; |
| 136019 | 136127 | } |
| 136020 | | - ix = p->rPct*(p->nUsed-1); |
| 136021 | | - i1 = (unsigned)ix; |
| 136022 | 136128 | if( settings & 1 ){ |
| 136023 | 136129 | vx = p->a[i1]; |
| 136024 | 136130 | }else{ |
| 136025 | 136131 | i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1; |
| 136026 | 136132 | v1 = p->a[i1]; |
| | @@ -150530,10 +150636,17 @@ |
| 150530 | 150636 | SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){ |
| 150531 | 150637 | Table *pTab; |
| 150532 | 150638 | sqlite3 *db = pParse->db; |
| 150533 | 150639 | u64 savedFlags; |
| 150534 | 150640 | |
| 150641 | + pParse->nNestSel++; |
| 150642 | +#if SQLITE_MAX_EXPR_DEPTH>0 |
| 150643 | + if( pParse->nNestSel >= db->aLimit[SQLITE_LIMIT_EXPR_DEPTH] ){ |
| 150644 | + sqlite3ErrorMsg(pParse, "VIEWs and/or subqueries nested too deep"); |
| 150645 | + return 0; |
| 150646 | + } |
| 150647 | +#endif |
| 150535 | 150648 | savedFlags = db->flags; |
| 150536 | 150649 | db->flags &= ~(u64)SQLITE_FullColNames; |
| 150537 | 150650 | db->flags |= SQLITE_ShortColNames; |
| 150538 | 150651 | sqlite3SelectPrep(pParse, pSelect, 0); |
| 150539 | 150652 | db->flags = savedFlags; |
| | @@ -150551,10 +150664,12 @@ |
| 150551 | 150664 | pTab->iPKey = -1; |
| 150552 | 150665 | if( db->mallocFailed ){ |
| 150553 | 150666 | sqlite3DeleteTable(db, pTab); |
| 150554 | 150667 | return 0; |
| 150555 | 150668 | } |
| 150669 | + pParse->nNestSel--; |
| 150670 | + assert( pParse->nNestSel>=0 ); |
| 150556 | 150671 | return pTab; |
| 150557 | 150672 | } |
| 150558 | 150673 | |
| 150559 | 150674 | /* |
| 150560 | 150675 | ** Get a VDBE for the given parser context. Create a new one if necessary. |
| | @@ -158494,22 +158609,36 @@ |
| 158494 | 158609 | Parse *pParse, /* Current parse context */ |
| 158495 | 158610 | Trigger *pTrigger, /* Trigger to code */ |
| 158496 | 158611 | Table *pTab, /* The table pTrigger is attached to */ |
| 158497 | 158612 | int orconf /* ON CONFLICT policy to code trigger program with */ |
| 158498 | 158613 | ){ |
| 158499 | | - Parse *pTop = sqlite3ParseToplevel(pParse); |
| 158614 | + Parse *pTop; /* Top level Parse object */ |
| 158500 | 158615 | sqlite3 *db = pParse->db; /* Database handle */ |
| 158501 | 158616 | TriggerPrg *pPrg; /* Value to return */ |
| 158502 | 158617 | Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ |
| 158503 | 158618 | Vdbe *v; /* Temporary VM */ |
| 158504 | 158619 | NameContext sNC; /* Name context for sub-vdbe */ |
| 158505 | 158620 | SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ |
| 158506 | 158621 | int iEndTrigger = 0; /* Label to jump to if WHEN is false */ |
| 158507 | 158622 | Parse sSubParse; /* Parse context for sub-vdbe */ |
| 158623 | + int nDepth; /* Trigger depth */ |
| 158508 | 158624 | |
| 158625 | + /* Ensure that triggers are not chained too deep. This test is linear |
| 158626 | + ** in the chaining depth, but sensible code ought not be chaining |
| 158627 | + ** triggers excessively, so that shouldn't be a problem. |
| 158628 | + */ |
| 158629 | + pTop = pParse; |
| 158630 | + for(nDepth=0; pTop->pOuterParse; pTop = pTop->pOuterParse, nDepth++){} |
| 158631 | + if( nDepth>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ |
| 158632 | + sqlite3ErrorMsg(pParse, "triggers nested too deep"); |
| 158633 | + return 0; |
| 158634 | + } |
| 158635 | + |
| 158636 | + pTop = sqlite3ParseToplevel(pParse); |
| 158509 | 158637 | assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); |
| 158510 | 158638 | assert( pTop->pVdbe ); |
| 158639 | + |
| 158511 | 158640 | |
| 158512 | 158641 | /* Allocate the TriggerPrg and SubProgram objects. To ensure that they |
| 158513 | 158642 | ** are freed if an error occurs, link them into the Parse.pTriggerPrg |
| 158514 | 158643 | ** list of the top-level Parse object sooner rather than later. */ |
| 158515 | 158644 | pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg)); |
| | @@ -160507,11 +160636,12 @@ |
| 160507 | 160636 | ** So we have to make a copy before passing it down into sqlite3Update() */ |
| 160508 | 160637 | pSrc = sqlite3SrcListDup(db, pTop->pUpsertSrc, 0); |
| 160509 | 160638 | /* excluded.* columns of type REAL need to be converted to a hard real */ |
| 160510 | 160639 | for(i=0; i<pTab->nCol; i++){ |
| 160511 | 160640 | if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ |
| 160512 | | - sqlite3VdbeAddOp1(v, OP_RealAffinity, pTop->regData+i); |
| 160641 | + int iStorage = pTop->regData + sqlite3TableColumnToStorage(pTab, i); |
| 160642 | + sqlite3VdbeAddOp1(v, OP_RealAffinity, iStorage); |
| 160513 | 160643 | } |
| 160514 | 160644 | } |
| 160515 | 160645 | sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db,pUpsert->pUpsertSet,0), |
| 160516 | 160646 | sqlite3ExprDup(db,pUpsert->pUpsertWhere,0), OE_Abort, 0, 0, pUpsert); |
| 160517 | 160647 | VdbeNoopComment((v, "End DO UPDATE of UPSERT")); |
| | @@ -195112,12 +195242,17 @@ |
| 195112 | 195242 | char **pp, /* IN/OUT: Output pointer */ |
| 195113 | 195243 | sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ |
| 195114 | 195244 | sqlite3_int64 iVal /* Write this value to the list */ |
| 195115 | 195245 | ){ |
| 195116 | 195246 | assert_fts3_nc( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) ); |
| 195117 | | - *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev); |
| 195118 | | - *piPrev = iVal; |
| 195247 | + if( iVal-(*piPrev)>=0 ){ |
| 195248 | + /* Refuse to write a negative delta integer. This only happens with a |
| 195249 | + ** corrupt db (see the assert above) and can cause buffer overwrites |
| 195250 | + ** in some cases. */ |
| 195251 | + *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev); |
| 195252 | + *piPrev = iVal; |
| 195253 | + } |
| 195119 | 195254 | } |
| 195120 | 195255 | |
| 195121 | 195256 | /* |
| 195122 | 195257 | ** When this function is called, *ppPoslist is assumed to point to the |
| 195123 | 195258 | ** start of a position-list. After it returns, *ppPoslist points to the |
| | @@ -206533,10 +206668,14 @@ |
| 206533 | 206668 | iMul = -1; |
| 206534 | 206669 | } |
| 206535 | 206670 | for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){ |
| 206536 | 206671 | iVal = iVal*10 + (zText[i] - '0'); |
| 206537 | 206672 | } |
| 206673 | + |
| 206674 | + /* This if() clause is just to avoid an integer overflow. The record is |
| 206675 | + ** corrupt in this case. */ |
| 206676 | + if( (i64)iVal==SMALLEST_INT64 ) iMul = 1; |
| 206538 | 206677 | *pnByte = ((i64)iVal * (i64)iMul); |
| 206539 | 206678 | } |
| 206540 | 206679 | } |
| 206541 | 206680 | |
| 206542 | 206681 | |
| | @@ -209395,14 +209534,13 @@ |
| 209395 | 209534 | */ |
| 209396 | 209535 | |
| 209397 | 209536 | /* |
| 209398 | 209537 | ** Allocate a two-slot MatchinfoBuffer object. |
| 209399 | 209538 | */ |
| 209400 | | -static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ |
| 209539 | +static MatchinfoBuffer *fts3MIBufferNew(i64 nElem, const char *zMatchinfo){ |
| 209401 | 209540 | MatchinfoBuffer *pRet; |
| 209402 | | - sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) |
| 209403 | | - + SZ_MATCHINFOBUFFER(1); |
| 209541 | + sqlite3_int64 nByte = sizeof(u32) * (2*(i64)nElem+1) + SZ_MATCHINFOBUFFER(1); |
| 209404 | 209542 | sqlite3_int64 nStr = strlen(zMatchinfo); |
| 209405 | 209543 | |
| 209406 | 209544 | pRet = sqlite3Fts3MallocZero(nByte + nStr+1); |
| 209407 | 209545 | if( pRet ){ |
| 209408 | 209546 | pRet->aMI[0] = (u8*)(&pRet->aMI[1]) - (u8*)pRet; |
| | @@ -210269,12 +210407,12 @@ |
| 210269 | 210407 | } |
| 210270 | 210408 | sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg); |
| 210271 | 210409 | return SQLITE_ERROR; |
| 210272 | 210410 | } |
| 210273 | 210411 | |
| 210274 | | -static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ |
| 210275 | | - size_t nVal; /* Number of integers output by cArg */ |
| 210412 | +static i64 fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ |
| 210413 | + i64 nVal; /* Number of integers output by cArg */ |
| 210276 | 210414 | |
| 210277 | 210415 | switch( cArg ){ |
| 210278 | 210416 | case FTS3_MATCHINFO_NDOC: |
| 210279 | 210417 | case FTS3_MATCHINFO_NPHRASE: |
| 210280 | 210418 | case FTS3_MATCHINFO_NCOL: |
| | @@ -210286,20 +210424,20 @@ |
| 210286 | 210424 | case FTS3_MATCHINFO_LCS: |
| 210287 | 210425 | nVal = pInfo->nCol; |
| 210288 | 210426 | break; |
| 210289 | 210427 | |
| 210290 | 210428 | case FTS3_MATCHINFO_LHITS: |
| 210291 | | - nVal = (size_t)pInfo->nCol * pInfo->nPhrase; |
| 210429 | + nVal = (i64)pInfo->nCol * pInfo->nPhrase; |
| 210292 | 210430 | break; |
| 210293 | 210431 | |
| 210294 | 210432 | case FTS3_MATCHINFO_LHITS_BM: |
| 210295 | | - nVal = (size_t)pInfo->nPhrase * ((pInfo->nCol + 31) / 32); |
| 210433 | + nVal = (i64)pInfo->nPhrase * ((pInfo->nCol + 31) / 32); |
| 210296 | 210434 | break; |
| 210297 | 210435 | |
| 210298 | 210436 | default: |
| 210299 | 210437 | assert( cArg==FTS3_MATCHINFO_HITS ); |
| 210300 | | - nVal = (size_t)pInfo->nCol * pInfo->nPhrase * 3; |
| 210438 | + nVal = (i64)pInfo->nCol * pInfo->nPhrase * 3; |
| 210301 | 210439 | break; |
| 210302 | 210440 | } |
| 210303 | 210441 | |
| 210304 | 210442 | return nVal; |
| 210305 | 210443 | } |
| | @@ -210577,11 +210715,11 @@ |
| 210577 | 210715 | } |
| 210578 | 210716 | break; |
| 210579 | 210717 | |
| 210580 | 210718 | case FTS3_MATCHINFO_LHITS_BM: |
| 210581 | 210719 | case FTS3_MATCHINFO_LHITS: { |
| 210582 | | - size_t nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32); |
| 210720 | + i64 nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32); |
| 210583 | 210721 | memset(pInfo->aMatchinfo, 0, nZero); |
| 210584 | 210722 | rc = fts3ExprLHitGather(pCsr->pExpr, pInfo); |
| 210585 | 210723 | break; |
| 210586 | 210724 | } |
| 210587 | 210725 | |
| | @@ -210646,11 +210784,11 @@ |
| 210646 | 210784 | ** matchinfo function has been called for this query. In this case |
| 210647 | 210785 | ** allocate the array used to accumulate the matchinfo data and |
| 210648 | 210786 | ** initialize those elements that are constant for every row. |
| 210649 | 210787 | */ |
| 210650 | 210788 | if( pCsr->pMIBuffer==0 ){ |
| 210651 | | - size_t nMatchinfo = 0; /* Number of u32 elements in match-info */ |
| 210789 | + i64 nMatchinfo = 0; /* Number of u32 elements in match-info */ |
| 210652 | 210790 | int i; /* Used to iterate through zArg */ |
| 210653 | 210791 | |
| 210654 | 210792 | /* Determine the number of phrases in the query */ |
| 210655 | 210793 | pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr); |
| 210656 | 210794 | sInfo.nPhrase = pCsr->nPhrase; |
| | @@ -218333,10 +218471,13 @@ |
| 218333 | 218471 | ** be because the shadow tables hold erroneous data. */ |
| 218334 | 218472 | if( rc==SQLITE_ERROR ){ |
| 218335 | 218473 | rc = SQLITE_CORRUPT_VTAB; |
| 218336 | 218474 | RTREE_IS_CORRUPT(pRtree); |
| 218337 | 218475 | } |
| 218476 | + }else if( iNode<=0 ){ |
| 218477 | + RTREE_IS_CORRUPT(pRtree); |
| 218478 | + rc = SQLITE_CORRUPT_VTAB; |
| 218338 | 218479 | }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){ |
| 218339 | 218480 | pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize); |
| 218340 | 218481 | if( !pNode ){ |
| 218341 | 218482 | rc = SQLITE_NOMEM; |
| 218342 | 218483 | }else{ |
| | @@ -225925,20 +226066,30 @@ |
| 225925 | 226066 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, |
| 225926 | 226067 | -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, |
| 225927 | 226068 | 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36, |
| 225928 | 226069 | -1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, |
| 225929 | 226070 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1, |
| 226071 | + |
| 226072 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| 226073 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| 226074 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| 226075 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| 226076 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| 226077 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| 226078 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| 226079 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| 225930 | 226080 | }; |
| 225931 | 226081 | unsigned int v = 0; |
| 225932 | 226082 | int c; |
| 225933 | 226083 | unsigned char *z = (unsigned char*)*pz; |
| 225934 | | - unsigned char *zStart = z; |
| 225935 | | - while( (c = zValue[0x7f&*(z++)])>=0 ){ |
| 225936 | | - v = (v<<6) + c; |
| 226084 | + unsigned char *zEnd = z + (*pLen); |
| 226085 | + while( z<zEnd && (c = zValue[*z])>=0 ){ |
| 226086 | + v = (v<<6) + c; |
| 226087 | + z++; |
| 225937 | 226088 | } |
| 225938 | | - z--; |
| 225939 | | - *pLen -= (int)(z - zStart); |
| 226089 | + |
| 226090 | + *pLen -= (int)(z - (unsigned char*)*pz); |
| 225940 | 226091 | *pz = (char*)z; |
| 225941 | 226092 | return v; |
| 225942 | 226093 | } |
| 225943 | 226094 | |
| 225944 | 226095 | #if RBU_ENABLE_DELTA_CKSUM |
| | @@ -226010,23 +226161,24 @@ |
| 226010 | 226161 | #if RBU_ENABLE_DELTA_CKSUM |
| 226011 | 226162 | char *zOrigOut = zOut; |
| 226012 | 226163 | #endif |
| 226013 | 226164 | |
| 226014 | 226165 | limit = rbuDeltaGetInt(&zDelta, &lenDelta); |
| 226015 | | - if( *zDelta!='\n' ){ |
| 226166 | + if( lenDelta<=0 || *zDelta!='\n' ){ |
| 226016 | 226167 | /* ERROR: size integer not terminated by "\n" */ |
| 226017 | 226168 | return -1; |
| 226018 | 226169 | } |
| 226019 | 226170 | zDelta++; lenDelta--; |
| 226020 | 226171 | while( *zDelta && lenDelta>0 ){ |
| 226021 | 226172 | unsigned int cnt, ofst; |
| 226022 | 226173 | cnt = rbuDeltaGetInt(&zDelta, &lenDelta); |
| 226174 | + if( lenDelta<=0 ) return -1; |
| 226023 | 226175 | switch( zDelta[0] ){ |
| 226024 | 226176 | case '@': { |
| 226025 | 226177 | zDelta++; lenDelta--; |
| 226026 | 226178 | ofst = rbuDeltaGetInt(&zDelta, &lenDelta); |
| 226027 | | - if( lenDelta>0 && zDelta[0]!=',' ){ |
| 226179 | + if( lenDelta>0 || zDelta[0]!=',' ){ |
| 226028 | 226180 | /* ERROR: copy command not terminated by ',' */ |
| 226029 | 226181 | return -1; |
| 226030 | 226182 | } |
| 226031 | 226183 | zDelta++; lenDelta--; |
| 226032 | 226184 | total += cnt; |
| | @@ -226047,11 +226199,11 @@ |
| 226047 | 226199 | total += cnt; |
| 226048 | 226200 | if( total>limit ){ |
| 226049 | 226201 | /* ERROR: insert command gives an output larger than predicted */ |
| 226050 | 226202 | return -1; |
| 226051 | 226203 | } |
| 226052 | | - if( (int)cnt>lenDelta ){ |
| 226204 | + if( (i64)cnt>(i64)lenDelta ){ |
| 226053 | 226205 | /* ERROR: insert count exceeds size of delta */ |
| 226054 | 226206 | return -1; |
| 226055 | 226207 | } |
| 226056 | 226208 | memcpy(zOut, zDelta, cnt); |
| 226057 | 226209 | zOut += cnt; |
| | @@ -226085,11 +226237,11 @@ |
| 226085 | 226237 | } |
| 226086 | 226238 | |
| 226087 | 226239 | static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){ |
| 226088 | 226240 | int size; |
| 226089 | 226241 | size = rbuDeltaGetInt(&zDelta, &lenDelta); |
| 226090 | | - if( *zDelta!='\n' ){ |
| 226242 | + if( lenDelta<=0 || *zDelta!='\n' ){ |
| 226091 | 226243 | /* ERROR: size integer not terminated by "\n" */ |
| 226092 | 226244 | return -1; |
| 226093 | 226245 | } |
| 226094 | 226246 | return size; |
| 226095 | 226247 | } |
| | @@ -226133,11 +226285,11 @@ |
| 226133 | 226285 | if( nOut<0 ){ |
| 226134 | 226286 | sqlite3_result_error(context, "corrupt fossil delta", -1); |
| 226135 | 226287 | return; |
| 226136 | 226288 | } |
| 226137 | 226289 | |
| 226138 | | - aOut = sqlite3_malloc(nOut+1); |
| 226290 | + aOut = sqlite3_malloc64((i64)nOut+1); |
| 226139 | 226291 | if( aOut==0 ){ |
| 226140 | 226292 | sqlite3_result_error_nomem(context); |
| 226141 | 226293 | }else{ |
| 226142 | 226294 | nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut); |
| 226143 | 226295 | if( nOut2!=nOut ){ |
| | @@ -247810,14 +247962,14 @@ |
| 247810 | 247962 | rc = SQLITE_NOMEM; |
| 247811 | 247963 | }else{ |
| 247812 | 247964 | memset(pSyn, 0, (size_t)nByte); |
| 247813 | 247965 | pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); |
| 247814 | 247966 | pSyn->nFullTerm = pSyn->nQueryTerm = nToken; |
| 247967 | + memcpy(pSyn->pTerm, pToken, nToken); |
| 247815 | 247968 | if( pCtx->pConfig->bTokendata ){ |
| 247816 | 247969 | pSyn->nQueryTerm = (int)strlen(pSyn->pTerm); |
| 247817 | 247970 | } |
| 247818 | | - memcpy(pSyn->pTerm, pToken, nToken); |
| 247819 | 247971 | pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym; |
| 247820 | 247972 | pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn; |
| 247821 | 247973 | } |
| 247822 | 247974 | }else{ |
| 247823 | 247975 | Fts5ExprTerm *pTerm; |
| | @@ -249662,11 +249814,11 @@ |
| 249662 | 249814 | ** + 1 byte for a "new column" byte, |
| 249663 | 249815 | ** + 3 bytes for a new column number (16-bit max) as a varint, |
| 249664 | 249816 | ** + 5 bytes for the new position offset (32-bit max). |
| 249665 | 249817 | */ |
| 249666 | 249818 | if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){ |
| 249667 | | - sqlite3_int64 nNew = p->nAlloc * 2; |
| 249819 | + sqlite3_int64 nNew = (i64)p->nAlloc * 2; |
| 249668 | 249820 | Fts5HashEntry *pNew; |
| 249669 | 249821 | Fts5HashEntry **pp; |
| 249670 | 249822 | pNew = (Fts5HashEntry*)sqlite3_realloc64(p, nNew); |
| 249671 | 249823 | if( pNew==0 ) return SQLITE_NOMEM; |
| 249672 | 249824 | pNew->nAlloc = (int)nNew; |
| | @@ -251096,11 +251248,11 @@ |
| 251096 | 251248 | }else{ |
| 251097 | 251249 | i += fts5GetVarint32(&pData[i], pLvl->nMerge); |
| 251098 | 251250 | i += fts5GetVarint32(&pData[i], nTotal); |
| 251099 | 251251 | if( nTotal<pLvl->nMerge ) rc = FTS5_CORRUPT; |
| 251100 | 251252 | pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, |
| 251101 | | - nTotal * sizeof(Fts5StructureSegment) |
| 251253 | + (i64)nTotal * sizeof(Fts5StructureSegment) |
| 251102 | 251254 | ); |
| 251103 | 251255 | nSegment -= nTotal; |
| 251104 | 251256 | } |
| 251105 | 251257 | |
| 251106 | 251258 | if( rc==SQLITE_OK ){ |
| | @@ -257921,12 +258073,12 @@ |
| 257921 | 258073 | int *pnOut, /* OUT: Number of output pages */ |
| 257922 | 258074 | Fts5Data ***papOut /* OUT: Output hash pages */ |
| 257923 | 258075 | ){ |
| 257924 | 258076 | const int MINSLOT = 32; |
| 257925 | 258077 | int nSlotPerPage = MAX(MINSLOT, (p->pConfig->pgsz - 8) / szKey); |
| 257926 | | - int nSlot = 0; /* Number of slots in each output page */ |
| 257927 | | - int nOut = 0; |
| 258078 | + i64 nSlot = 0; /* Number of slots in each output page */ |
| 258079 | + i64 nOut = 0; |
| 257928 | 258080 | |
| 257929 | 258081 | /* Figure out how many output pages (nOut) and how many slots per |
| 257930 | 258082 | ** page (nSlot). There are three possibilities: |
| 257931 | 258083 | ** |
| 257932 | 258084 | ** 1. The hash table does not yet exist. In this case the new hash |
| | @@ -257947,27 +258099,30 @@ |
| 257947 | 258099 | /* Case 1. */ |
| 257948 | 258100 | nOut = 1; |
| 257949 | 258101 | nSlot = MINSLOT; |
| 257950 | 258102 | }else if( pSeg->nPgTombstone==1 ){ |
| 257951 | 258103 | /* Case 2. */ |
| 257952 | | - int nElem = (int)fts5GetU32(&pData1->p[4]); |
| 258104 | + u32 nElem = fts5GetU32(&pData1->p[4]); |
| 257953 | 258105 | assert( pData1 && iPg1==0 ); |
| 257954 | | - nOut = 1; |
| 257955 | | - nSlot = MAX(nElem*4, MINSLOT); |
| 257956 | | - if( nSlot>nSlotPerPage ) nOut = 0; |
| 258106 | + if( nElem>((u32)nSlotPerPage/4) ){ |
| 258107 | + nOut = 0; |
| 258108 | + }else{ |
| 258109 | + nOut = 1; |
| 258110 | + nSlot = MAX((i64)nElem*4, MINSLOT); |
| 258111 | + } |
| 257957 | 258112 | } |
| 257958 | 258113 | if( nOut==0 ){ |
| 257959 | 258114 | /* Case 3. */ |
| 257960 | | - nOut = (pSeg->nPgTombstone * 2 + 1); |
| 258115 | + nOut = ((i64)pSeg->nPgTombstone * 2 + 1); |
| 257961 | 258116 | nSlot = nSlotPerPage; |
| 257962 | 258117 | } |
| 257963 | 258118 | |
| 257964 | 258119 | /* Allocate the required array and output pages */ |
| 257965 | 258120 | while( 1 ){ |
| 257966 | 258121 | int res = 0; |
| 257967 | | - int ii = 0; |
| 257968 | | - int szPage = 0; |
| 258122 | + i64 ii = 0; |
| 258123 | + i64 szPage = 0; |
| 257969 | 258124 | Fts5Data **apOut = 0; |
| 257970 | 258125 | |
| 257971 | 258126 | /* Allocate space for the new hash table */ |
| 257972 | 258127 | assert( nSlot>=MINSLOT ); |
| 257973 | 258128 | apOut = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data*) * nOut); |
| | @@ -263112,11 +263267,11 @@ |
| 263112 | 263267 | int nArg, /* Number of args */ |
| 263113 | 263268 | sqlite3_value **apUnused /* Function arguments */ |
| 263114 | 263269 | ){ |
| 263115 | 263270 | assert( nArg==0 ); |
| 263116 | 263271 | UNUSED_PARAM2(nArg, apUnused); |
| 263117 | | - sqlite3_result_text(pCtx, "fts5: 2026-06-08 18:15:27 4cb349370daab17123770c814c71872a3e4c616a3f984569b3d7f97f9c3f5ea0", -1, SQLITE_TRANSIENT); |
| 263272 | + sqlite3_result_text(pCtx, "fts5: 2026-06-16 13:43:08 3f3fb9b638f59ad982beafb7c117f24ddd3da612e62c862510805fa672ffae06", -1, SQLITE_TRANSIENT); |
| 263118 | 263273 | } |
| 263119 | 263274 | |
| 263120 | 263275 | /* |
| 263121 | 263276 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 263122 | 263277 | ** |
| 263123 | 263278 | |