|
1 | 1 | /****************************************************************************** |
2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
3 | | -** version 3.51.2. By combining all the individual C code files into this |
| 3 | +** version 3.51.3. By combining all the individual C code files into this |
4 | 4 | ** single large file, the entire code can be compiled as a single translation |
5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
6 | 6 | ** possible if the files were compiled separately. Performance improvements |
|
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 | | -** b270f8339eb13b504d0b2ba154ebca966b7d with changes in files: |
| 21 | +** 737ae4a34738ffa0c3ff7f9bb18df914dd1c with changes in files: |
22 | 22 | ** |
23 | 23 | ** |
24 | 24 | */ |
@@ -467,12 +467,12 @@ extern "C" { |
467 | 467 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
468 | 468 | ** [sqlite_version()] and [sqlite_source_id()]. |
469 | 469 | */ |
470 | | -#define SQLITE_VERSION "3.51.2" |
471 | | -#define SQLITE_VERSION_NUMBER 3051002 |
472 | | -#define SQLITE_SOURCE_ID "2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075" |
| 470 | +#define SQLITE_VERSION "3.51.3" |
| 471 | +#define SQLITE_VERSION_NUMBER 3051003 |
| 472 | +#define SQLITE_SOURCE_ID "2026-03-13 10:38:09 737ae4a34738ffa0c3ff7f9bb18df914dd1cad163f28fd6b6e114a344fe6d618" |
473 | 473 | #define SQLITE_SCM_BRANCH "branch-3.51" |
474 | | -#define SQLITE_SCM_TAGS "release version-3.51.2" |
475 | | -#define SQLITE_SCM_DATETIME "2026-01-09T17:27:48.405Z" |
| 474 | +#define SQLITE_SCM_TAGS "release version-3.51.3" |
| 475 | +#define SQLITE_SCM_DATETIME "2026-03-13T10:38:09.694Z" |
476 | 476 |
|
477 | 477 | /* |
478 | 478 | ** CAPI3REF: Run-Time Library Version Numbers |
@@ -14334,6 +14334,27 @@ struct fts5_api { |
14334 | 14334 | #endif |
14335 | 14335 | #define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */ |
14336 | 14336 |
|
| 14337 | +/* |
| 14338 | +** Maximum size of any single memory allocation. |
| 14339 | +** |
| 14340 | +** This is not a limit on the total amount of memory used. This is |
| 14341 | +** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc(). |
| 14342 | +** |
| 14343 | +** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391 |
| 14344 | +** This provides a 256-byte safety margin for defense against 32-bit |
| 14345 | +** signed integer overflow bugs when computing memory allocation sizes. |
| 14346 | +** Paranoid applications might want to reduce the maximum allocation size |
| 14347 | +** further for an even larger safety margin. 0x3fffffff or 0x0fffffff |
| 14348 | +** or even smaller would be reasonable upper bounds on the size of a memory |
| 14349 | +** allocations for most applications. |
| 14350 | +*/ |
| 14351 | +#ifndef SQLITE_MAX_ALLOCATION_SIZE |
| 14352 | +# define SQLITE_MAX_ALLOCATION_SIZE 2147483391 |
| 14353 | +#endif |
| 14354 | +#if SQLITE_MAX_ALLOCATION_SIZE>2147483391 |
| 14355 | +# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 |
| 14356 | +#endif |
| 14357 | + |
14337 | 14358 | /* |
14338 | 14359 | ** This is the maximum number of |
14339 | 14360 | ** |
@@ -21664,6 +21685,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList |
21664 | 21685 | Expr*,ExprList*,u32,Expr*); |
21665 | 21686 | SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); |
21666 | 21687 | SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3*,void*); |
| 21688 | +SQLITE_PRIVATE void sqlite3SelectCheckOnClauses(Parse *pParse, Select *pSelect); |
21667 | 21689 | SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); |
21668 | 21690 | SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); |
21669 | 21691 | SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); |
@@ -31310,27 +31332,6 @@ static void mallocWithAlarm(int n, void **pp){ |
31310 | 31332 | *pp = p; |
31311 | 31333 | } |
31312 | 31334 |
|
31313 | | -/* |
31314 | | -** Maximum size of any single memory allocation. |
31315 | | -** |
31316 | | -** This is not a limit on the total amount of memory used. This is |
31317 | | -** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc(). |
31318 | | -** |
31319 | | -** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391 |
31320 | | -** This provides a 256-byte safety margin for defense against 32-bit |
31321 | | -** signed integer overflow bugs when computing memory allocation sizes. |
31322 | | -** Paranoid applications might want to reduce the maximum allocation size |
31323 | | -** further for an even larger safety margin. 0x3fffffff or 0x0fffffff |
31324 | | -** or even smaller would be reasonable upper bounds on the size of a memory |
31325 | | -** allocations for most applications. |
31326 | | -*/ |
31327 | | -#ifndef SQLITE_MAX_ALLOCATION_SIZE |
31328 | | -# define SQLITE_MAX_ALLOCATION_SIZE 2147483391 |
31329 | | -#endif |
31330 | | -#if SQLITE_MAX_ALLOCATION_SIZE>2147483391 |
31331 | | -# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 |
31332 | | -#endif |
31333 | | - |
31334 | 31335 | /* |
31335 | 31336 | ** Allocate memory. This routine is like sqlite3_malloc() except that it |
31336 | 31337 | ** assumes the memory subsystem has already been initialized. |
@@ -31554,8 +31555,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ |
31554 | 31555 | sqlite3_free(pOld); /* IMP: R-26507-47431 */ |
31555 | 31556 | return 0; |
31556 | 31557 | } |
31557 | | - if( nBytes>=0x7fffff00 ){ |
31558 | | - /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */ |
| 31558 | + if( nBytes>SQLITE_MAX_ALLOCATION_SIZE ){ |
31559 | 31559 | return 0; |
31560 | 31560 | } |
31561 | 31561 | nOld = sqlite3MallocSize(pOld); |
@@ -69010,68 +69010,82 @@ static int walCheckpoint( |
69010 | 69010 | && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK |
69011 | 69011 | ){ |
69012 | 69012 | u32 nBackfill = pInfo->nBackfill; |
69013 | | - pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT; |
69014 | | - |
69015 | | - /* Sync the WAL to disk */ |
69016 | | - rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); |
69017 | | - |
69018 | | - /* If the database may grow as a result of this checkpoint, hint |
69019 | | - ** about the eventual size of the db file to the VFS layer. |
69020 | | - */ |
69021 | | - if( rc==SQLITE_OK ){ |
69022 | | - i64 nReq = ((i64)mxPage * szPage); |
69023 | | - i64 nSize; /* Current size of database file */ |
69024 | | - sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0); |
69025 | | - rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); |
69026 | | - if( rc==SQLITE_OK && nSize<nReq ){ |
69027 | | - if( (nSize+65536+(i64)pWal->hdr.mxFrame*szPage)<nReq ){ |
69028 | | - /* If the size of the final database is larger than the current |
69029 | | - ** database plus the amount of data in the wal file, plus the |
69030 | | - ** maximum size of the pending-byte page (65536 bytes), then |
69031 | | - ** must be corruption somewhere. */ |
69032 | | - rc = SQLITE_CORRUPT_BKPT; |
69033 | | - }else{ |
69034 | | - sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT,&nReq); |
| 69013 | + WalIndexHdr *pLive = (WalIndexHdr*)walIndexHdr(pWal); |
| 69014 | + |
| 69015 | + /* Now that read-lock slot 0 is locked, check that the wal has not been |
| 69016 | + ** wrapped since the header was read for this checkpoint. If it was, then |
| 69017 | + ** there was no work to do anyway. In this case the |
| 69018 | + ** (pInfo->nBackfill<pWal->hdr.mxFrame) test above only passed because |
| 69019 | + ** pInfo->nBackfill had already been set to 0 by the writer that wrapped |
| 69020 | + ** the wal file. It would also be dangerous to proceed, as there may be |
| 69021 | + ** fewer than pWal->hdr.mxFrame valid frames in the wal file. */ |
| 69022 | + int bChg = memcmp(pLive->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)); |
| 69023 | + if( 0==bChg ){ |
| 69024 | + pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT; |
| 69025 | + |
| 69026 | + /* Sync the WAL to disk */ |
| 69027 | + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); |
| 69028 | + |
| 69029 | + /* If the database may grow as a result of this checkpoint, hint |
| 69030 | + ** about the eventual size of the db file to the VFS layer. |
| 69031 | + */ |
| 69032 | + if( rc==SQLITE_OK ){ |
| 69033 | + i64 nReq = ((i64)mxPage * szPage); |
| 69034 | + i64 nSize; /* Current size of database file */ |
| 69035 | + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0); |
| 69036 | + rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); |
| 69037 | + if( rc==SQLITE_OK && nSize<nReq ){ |
| 69038 | + if( (nSize+65536+(i64)pWal->hdr.mxFrame*szPage)<nReq ){ |
| 69039 | + /* If the size of the final database is larger than the current |
| 69040 | + ** database plus the amount of data in the wal file, plus the |
| 69041 | + ** maximum size of the pending-byte page (65536 bytes), then |
| 69042 | + ** must be corruption somewhere. */ |
| 69043 | + rc = SQLITE_CORRUPT_BKPT; |
| 69044 | + }else{ |
| 69045 | + sqlite3OsFileControlHint( |
| 69046 | + pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); |
| 69047 | + } |
69035 | 69048 | } |
69036 | | - } |
69037 | | - |
69038 | | - } |
69039 | 69049 |
|
69040 | | - /* Iterate through the contents of the WAL, copying data to the db file */ |
69041 | | - while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ |
69042 | | - i64 iOffset; |
69043 | | - assert( walFramePgno(pWal, iFrame)==iDbpage ); |
69044 | | - SEH_INJECT_FAULT; |
69045 | | - if( AtomicLoad(&db->u1.isInterrupted) ){ |
69046 | | - rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; |
69047 | | - break; |
69048 | 69050 | } |
69049 | | - if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){ |
69050 | | - continue; |
69051 | | - } |
69052 | | - iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; |
69053 | | - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ |
69054 | | - rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); |
69055 | | - if( rc!=SQLITE_OK ) break; |
69056 | | - iOffset = (iDbpage-1)*(i64)szPage; |
69057 | | - testcase( IS_BIG_INT(iOffset) ); |
69058 | | - rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); |
69059 | | - if( rc!=SQLITE_OK ) break; |
69060 | | - } |
69061 | | - sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0); |
69062 | 69051 |
|
69063 | | - /* If work was actually accomplished... */ |
69064 | | - if( rc==SQLITE_OK ){ |
69065 | | - if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ |
69066 | | - i64 szDb = pWal->hdr.nPage*(i64)szPage; |
69067 | | - testcase( IS_BIG_INT(szDb) ); |
69068 | | - rc = sqlite3OsTruncate(pWal->pDbFd, szDb); |
69069 | | - if( rc==SQLITE_OK ){ |
69070 | | - rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); |
| 69052 | + /* Iterate through the contents of the WAL, copying data to the |
| 69053 | + ** db file */ |
| 69054 | + while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ |
| 69055 | + i64 iOffset; |
| 69056 | + assert( walFramePgno(pWal, iFrame)==iDbpage ); |
| 69057 | + SEH_INJECT_FAULT; |
| 69058 | + if( AtomicLoad(&db->u1.isInterrupted) ){ |
| 69059 | + rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; |
| 69060 | + break; |
69071 | 69061 | } |
| 69062 | + if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){ |
| 69063 | + continue; |
| 69064 | + } |
| 69065 | + iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; |
| 69066 | + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ |
| 69067 | + rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); |
| 69068 | + if( rc!=SQLITE_OK ) break; |
| 69069 | + iOffset = (iDbpage-1)*(i64)szPage; |
| 69070 | + testcase( IS_BIG_INT(iOffset) ); |
| 69071 | + rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); |
| 69072 | + if( rc!=SQLITE_OK ) break; |
69072 | 69073 | } |
| 69074 | + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0); |
| 69075 | + |
| 69076 | + /* If work was actually accomplished... */ |
69073 | 69077 | if( rc==SQLITE_OK ){ |
69074 | | - AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT; |
| 69078 | + if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ |
| 69079 | + i64 szDb = pWal->hdr.nPage*(i64)szPage; |
| 69080 | + testcase( IS_BIG_INT(szDb) ); |
| 69081 | + rc = sqlite3OsTruncate(pWal->pDbFd, szDb); |
| 69082 | + if( rc==SQLITE_OK ){ |
| 69083 | + rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); |
| 69084 | + } |
| 69085 | + } |
| 69086 | + if( rc==SQLITE_OK ){ |
| 69087 | + AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT; |
| 69088 | + } |
69075 | 69089 | } |
69076 | 69090 | } |
69077 | 69091 |
|
@@ -71121,6 +71135,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( |
71121 | 71135 |
|
71122 | 71136 | /* Copy data from the log to the database file. */ |
71123 | 71137 | if( rc==SQLITE_OK ){ |
| 71138 | + sqlite3FaultSim(660); |
71124 | 71139 | if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ |
71125 | 71140 | rc = SQLITE_CORRUPT_BKPT; |
71126 | 71141 | }else if( eMode2!=SQLITE_CHECKPOINT_NOOP ){ |
@@ -77556,7 +77571,7 @@ static int accessPayload( |
77556 | 77571 |
|
77557 | 77572 | getCellInfo(pCur); |
77558 | 77573 | aPayload = pCur->info.pPayload; |
77559 | | - assert( offset+amt <= pCur->info.nPayload ); |
| 77574 | + assert( (u64)offset+(u64)amt <= (u64)pCur->info.nPayload ); |
77560 | 77575 |
|
77561 | 77576 | assert( aPayload > pPage->aData ); |
77562 | 77577 | if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ |
@@ -86030,7 +86045,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( |
86030 | 86045 | ){ |
86031 | 86046 | int rc; |
86032 | 86047 | pMem->flags = MEM_Null; |
86033 | | - if( sqlite3BtreeMaxRecordSize(pCur)<offset+amt ){ |
| 86048 | + testcase( amt==SQLITE_MAX_ALLOCATION_SIZE-1 ); |
| 86049 | + testcase( amt==SQLITE_MAX_ALLOCATION_SIZE ); |
| 86050 | + if( amt>=SQLITE_MAX_ALLOCATION_SIZE ){ |
| 86051 | + return SQLITE_NOMEM_BKPT; |
| 86052 | + } |
| 86053 | + if( (u64)amt + (u64)offset > (u64)sqlite3BtreeMaxRecordSize(pCur) ){ |
86034 | 86054 | return SQLITE_CORRUPT_BKPT; |
86035 | 86055 | } |
86036 | 86056 | if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){ |
@@ -93443,7 +93463,7 @@ static int valueFromValueList( |
93443 | 93463 | Mem sMem; /* Raw content of current row */ |
93444 | 93464 | memset(&sMem, 0, sizeof(sMem)); |
93445 | 93465 | sz = sqlite3BtreePayloadSize(pRhs->pCsr); |
93446 | | - rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem); |
| 93466 | + rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,sz,&sMem); |
93447 | 93467 | if( rc==SQLITE_OK ){ |
93448 | 93468 | u8 *zBuf = (u8*)sMem.z; |
93449 | 93469 | u32 iSerial; |
@@ -111185,6 +111205,14 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ |
111185 | 111205 | return WRC_Abort; |
111186 | 111206 | } |
111187 | 111207 |
|
| 111208 | + /* If the SELECT statement contains ON clauses that were moved into |
| 111209 | + ** the WHERE clause, go through and verify that none of the terms |
| 111210 | + ** in the ON clauses reference tables to the right of the ON clause. */ |
| 111211 | + if( (p->selFlags & SF_OnToWhere) ){ |
| 111212 | + sqlite3SelectCheckOnClauses(pParse, p); |
| 111213 | + if( pParse->nErr ) return WRC_Abort; |
| 111214 | + } |
| 111215 | + |
111188 | 111216 | /* Advance to the next term of the compound |
111189 | 111217 | */ |
111190 | 111218 | p = p->pPrior; |
@@ -154356,7 +154384,7 @@ static int selectCheckOnClausesSelect(Walker *pWalker, Select *pSelect){ |
154356 | 154384 | ** Check all ON clauses in pSelect to verify that they do not reference |
154357 | 154385 | ** columns to the right. |
154358 | 154386 | */ |
154359 | | -static void selectCheckOnClauses(Parse *pParse, Select *pSelect){ |
| 154387 | +SQLITE_PRIVATE void sqlite3SelectCheckOnClauses(Parse *pParse, Select *pSelect){ |
154360 | 154388 | Walker w; |
154361 | 154389 | CheckOnCtx sCtx; |
154362 | 154390 | assert( pSelect->selFlags & SF_OnToWhere ); |
@@ -154499,18 +154527,6 @@ SQLITE_PRIVATE int sqlite3Select( |
154499 | 154527 | } |
154500 | 154528 | #endif |
154501 | 154529 |
|
154502 | | - /* If the SELECT statement contains ON clauses that were moved into |
154503 | | - ** the WHERE clause, go through and verify that none of the terms |
154504 | | - ** in the ON clauses reference tables to the right of the ON clause. |
154505 | | - ** Do this now, after name resolution, but before query flattening |
154506 | | - */ |
154507 | | - if( p->selFlags & SF_OnToWhere ){ |
154508 | | - selectCheckOnClauses(pParse, p); |
154509 | | - if( pParse->nErr ){ |
154510 | | - goto select_end; |
154511 | | - } |
154512 | | - } |
154513 | | - |
154514 | 154530 | /* If the SF_UFSrcCheck flag is set, then this function is being called |
154515 | 154531 | ** as part of populating the temp table for an UPDATE...FROM statement. |
154516 | 154532 | ** In this case, it is an error if the target object (pSrc->a[0]) name |
@@ -164677,6 +164693,15 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( |
164677 | 164693 | sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); |
164678 | 164694 | } |
164679 | 164695 | } |
| 164696 | + if( pLevel->iIdxCur ){ |
| 164697 | + /* pSubWhere may contain expressions that read from an index on the |
| 164698 | + ** table on the RHS of the right join. All such expressions first test |
| 164699 | + ** if the index is pointing at a NULL row, and if so, read from the |
| 164700 | + ** table cursor instead. So ensure that the index cursor really is |
| 164701 | + ** pointing at a NULL row here, so that no values are read from it during |
| 164702 | + ** the scan of the RHS of the RIGHT join below. */ |
| 164703 | + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); |
| 164704 | + } |
164680 | 164705 | pFrom = &uSrc.sSrc; |
164681 | 164706 | pFrom->nSrc = 1; |
164682 | 164707 | pFrom->nAlloc = 1; |
@@ -224163,7 +224188,7 @@ static int rbuDeltaApply( |
224163 | 224188 | /* ERROR: copy exceeds output file size */ |
224164 | 224189 | return -1; |
224165 | 224190 | } |
224166 | | - if( (int)(ofst+cnt) > lenSrc ){ |
| 224191 | + if( (u64)ofst+(u64)cnt > (u64)lenSrc ){ |
224167 | 224192 | /* ERROR: copy extends past end of input */ |
224168 | 224193 | return -1; |
224169 | 224194 | } |
@@ -252450,7 +252475,7 @@ static void fts5DoSecureDelete( |
252450 | 252475 | int iSegid = pSeg->pSeg->iSegid; |
252451 | 252476 | u8 *aPg = pSeg->pLeaf->p; |
252452 | 252477 | int nPg = pSeg->pLeaf->nn; |
252453 | | - int iPgIdx = pSeg->pLeaf->szLeaf; |
| 252478 | + int iPgIdx = pSeg->pLeaf->szLeaf; /* Offset of page footer */ |
252454 | 252479 |
|
252455 | 252480 | u64 iDelta = 0; |
252456 | 252481 | int iNextOff = 0; |
@@ -252529,7 +252554,7 @@ static void fts5DoSecureDelete( |
252529 | 252554 | iSOP += fts5GetVarint32(&aPg[iSOP], nPos); |
252530 | 252555 | } |
252531 | 252556 | assert_nc( iSOP==pSeg->iLeafOffset ); |
252532 | | - iNextOff = pSeg->iLeafOffset + pSeg->nPos; |
| 252557 | + iNextOff = iSOP + pSeg->nPos; |
252533 | 252558 | } |
252534 | 252559 | } |
252535 | 252560 |
|
@@ -260348,7 +260373,7 @@ static void fts5SourceIdFunc( |
260348 | 260373 | ){ |
260349 | 260374 | assert( nArg==0 ); |
260350 | 260375 | UNUSED_PARAM2(nArg, apUnused); |
260351 | | - sqlite3_result_text(pCtx, "fts5: 2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075", -1, SQLITE_TRANSIENT); |
| 260376 | + sqlite3_result_text(pCtx, "fts5: 2026-03-13 10:38:09 737ae4a34738ffa0c3ff7f9bb18df914dd1cad163f28fd6b6e114a344fe6d618", -1, SQLITE_TRANSIENT); |
260352 | 260377 | } |
260353 | 260378 |
|
260354 | 260379 | /* |
|
0 commit comments