| | @@ -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 | | -** bc0693c4633f545f09dbee702e25354504b. |
| 21 | +** c7eeb055bfb0e5a4467d8a45fa53d84bb8a. |
| 22 | 22 | */ |
| 23 | 23 | #define SQLITE_CORE 1 |
| 24 | 24 | #define SQLITE_AMALGAMATION 1 |
| 25 | 25 | #ifndef SQLITE_PRIVATE |
| 26 | 26 | # define SQLITE_PRIVATE static |
| | @@ -459,11 +459,11 @@ |
| 459 | 459 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 460 | 460 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 461 | 461 | */ |
| 462 | 462 | #define SQLITE_VERSION "3.43.0" |
| 463 | 463 | #define SQLITE_VERSION_NUMBER 3043000 |
| 464 | | -#define SQLITE_SOURCE_ID "2023-08-11 22:40:06 3bc0693c4633f545f09dbee702e25354504b20836373a068447e6c61cb2ebd79" |
| 464 | +#define SQLITE_SOURCE_ID "2023-08-18 12:15:44 ec7eeb055bfb0e5a4467d8a45fa53d84bb8ae80ca0474b687e2783e971648008" |
| 465 | 465 | |
| 466 | 466 | /* |
| 467 | 467 | ** CAPI3REF: Run-Time Library Version Numbers |
| 468 | 468 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 469 | 469 | ** |
| | @@ -13346,12 +13346,12 @@ |
| 13346 | 13346 | ** extra disk space, as no extra entries are added to the FTS index. |
| 13347 | 13347 | ** On the other hand, it may require more CPU cycles to run MATCH queries, |
| 13348 | 13348 | ** as separate queries of the FTS index are required for each synonym. |
| 13349 | 13349 | ** |
| 13350 | 13350 | ** When using methods (2) or (3), it is important that the tokenizer only |
| 13351 | | -** provide synonyms when tokenizing document text (method (2)) or query |
| 13352 | | -** text (method (3)), not both. Doing so will not cause any errors, but is |
| 13351 | +** provide synonyms when tokenizing document text (method (3)) or query |
| 13352 | +** text (method (2)), not both. Doing so will not cause any errors, but is |
| 13353 | 13353 | ** inefficient. |
| 13354 | 13354 | */ |
| 13355 | 13355 | typedef struct Fts5Tokenizer Fts5Tokenizer; |
| 13356 | 13356 | typedef struct fts5_tokenizer fts5_tokenizer; |
| 13357 | 13357 | struct fts5_tokenizer { |
| | @@ -34768,11 +34768,15 @@ |
| 34768 | 34768 | while( e<=-10 ){ e+=10; r *= 1.0e-10L; } |
| 34769 | 34769 | while( e<=-1 ){ e+=1; r *= 1.0e-01L; } |
| 34770 | 34770 | } |
| 34771 | 34771 | assert( r>=0.0 ); |
| 34772 | 34772 | if( r>+1.7976931348623157081452742373e+308L ){ |
| 34773 | +#ifdef INFINITY |
| 34773 | 34774 | *pResult = +INFINITY; |
| 34775 | +#else |
| 34776 | + *pResult = 1.0e308*10.0; |
| 34777 | +#endif |
| 34774 | 34778 | }else{ |
| 34775 | 34779 | *pResult = (double)r; |
| 34776 | 34780 | } |
| 34777 | 34781 | }else{ |
| 34778 | 34782 | double rr[2]; |
| | @@ -50534,10 +50538,11 @@ |
| 50534 | 50538 | static char zChars[] = |
| 50535 | 50539 | "abcdefghijklmnopqrstuvwxyz" |
| 50536 | 50540 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 50537 | 50541 | "0123456789"; |
| 50538 | 50542 | size_t i, j; |
| 50543 | + DWORD pid; |
| 50539 | 50544 | int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); |
| 50540 | 50545 | int nMax, nBuf, nDir, nLen; |
| 50541 | 50546 | char *zBuf; |
| 50542 | 50547 | |
| 50543 | 50548 | /* It's odd to simulate an io-error here, but really this is just |
| | @@ -50746,11 +50751,14 @@ |
| 50746 | 50751 | |
| 50747 | 50752 | sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); |
| 50748 | 50753 | |
| 50749 | 50754 | j = sqlite3Strlen30(zBuf); |
| 50750 | 50755 | sqlite3_randomness(15, &zBuf[j]); |
| 50756 | + pid = osGetCurrentProcessId(); |
| 50751 | 50757 | for(i=0; i<15; i++, j++){ |
| 50758 | + zBuf[j] += pid & 0xff; |
| 50759 | + pid >>= 8; |
| 50752 | 50760 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 50753 | 50761 | } |
| 50754 | 50762 | zBuf[j] = 0; |
| 50755 | 50763 | zBuf[j+1] = 0; |
| 50756 | 50764 | *pzBuf = zBuf; |
| | @@ -64488,10 +64496,12 @@ |
| 64488 | 64496 | const char *zWalName; /* Name of WAL file */ |
| 64489 | 64497 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ |
| 64490 | 64498 | #ifdef SQLITE_USE_SEH |
| 64491 | 64499 | u32 lockMask; /* Mask of locks held */ |
| 64492 | 64500 | void *pFree; /* Pointer to sqlite3_free() if exception thrown */ |
| 64501 | + u32 *pWiValue; /* Value to write into apWiData[iWiPg] */ |
| 64502 | + int iWiPg; /* Write pWiValue into apWiData[iWiPg] */ |
| 64493 | 64503 | int iSysErrno; /* System error code following exception */ |
| 64494 | 64504 | #endif |
| 64495 | 64505 | #ifdef SQLITE_DEBUG |
| 64496 | 64506 | int nSehTry; /* Number of nested SEH_TRY{} blocks */ |
| 64497 | 64507 | u8 lockError; /* True if a locking error has occurred */ |
| | @@ -64659,15 +64669,28 @@ |
| 64659 | 64669 | ** be freed. In the second case, pPtr must be the registered pointer. |
| 64660 | 64670 | */ |
| 64661 | 64671 | #define SEH_FREE_ON_ERROR(X,Y) \ |
| 64662 | 64672 | assert( (X==0 || Y==0) && pWal->pFree==X ); pWal->pFree = Y |
| 64663 | 64673 | |
| 64674 | +/* |
| 64675 | +** There are two ways to use this macro. To arrange for pWal->apWiData[iPg] |
| 64676 | +** to be set to pValue if an exception is thrown: |
| 64677 | +** |
| 64678 | +** SEH_SET_ON_ERROR(iPg, pValue); |
| 64679 | +** |
| 64680 | +** and to cancel the same: |
| 64681 | +** |
| 64682 | +** SEH_SET_ON_ERROR(0, 0); |
| 64683 | +*/ |
| 64684 | +#define SEH_SET_ON_ERROR(X,Y) pWal->iWiPg = X; pWal->pWiValue = Y |
| 64685 | + |
| 64664 | 64686 | #else |
| 64665 | 64687 | # define SEH_TRY VVA_ONLY(pWal->nSehTry++); |
| 64666 | 64688 | # define SEH_EXCEPT(X) VVA_ONLY(pWal->nSehTry--); assert( pWal->nSehTry==0 ); |
| 64667 | 64689 | # define SEH_INJECT_FAULT assert( pWal->nSehTry>0 ); |
| 64668 | 64690 | # define SEH_FREE_ON_ERROR(X,Y) |
| 64691 | +# define SEH_SET_ON_ERROR(X,Y) |
| 64669 | 64692 | #endif /* ifdef SQLITE_USE_SEH */ |
| 64670 | 64693 | |
| 64671 | 64694 | |
| 64672 | 64695 | /* |
| 64673 | 64696 | ** Obtain a pointer to the iPage'th page of the wal-index. The wal-index |
| | @@ -65424,10 +65447,11 @@ |
| 65424 | 65447 | u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE); |
| 65425 | 65448 | u32 nHdr, nHdr32; |
| 65426 | 65449 | rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare); |
| 65427 | 65450 | assert( aShare!=0 || rc!=SQLITE_OK ); |
| 65428 | 65451 | if( aShare==0 ) break; |
| 65452 | + SEH_SET_ON_ERROR(iPg, aShare); |
| 65429 | 65453 | pWal->apWiData[iPg] = aPrivate; |
| 65430 | 65454 | |
| 65431 | 65455 | for(iFrame=iFirst; iFrame<=iLast; iFrame++){ |
| 65432 | 65456 | i64 iOffset = walFrameOffset(iFrame, szPage); |
| 65433 | 65457 | u32 pgno; /* Database page number for frame */ |
| | @@ -65451,10 +65475,11 @@ |
| 65451 | 65475 | aFrameCksum[0] = pWal->hdr.aFrameCksum[0]; |
| 65452 | 65476 | aFrameCksum[1] = pWal->hdr.aFrameCksum[1]; |
| 65453 | 65477 | } |
| 65454 | 65478 | } |
| 65455 | 65479 | pWal->apWiData[iPg] = aShare; |
| 65480 | + SEH_SET_ON_ERROR(0,0); |
| 65456 | 65481 | nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0); |
| 65457 | 65482 | nHdr32 = nHdr / sizeof(u32); |
| 65458 | 65483 | #ifndef SQLITE_SAFER_WALINDEX_RECOVERY |
| 65459 | 65484 | /* Memcpy() should work fine here, on all reasonable implementations. |
| 65460 | 65485 | ** Technically, memcpy() might change the destination to some |
| | @@ -66344,11 +66369,13 @@ |
| 66344 | 66369 | ** held locks are assumed to be transient locks that would have been |
| 66345 | 66370 | ** released had the exception not been thrown and are dropped. |
| 66346 | 66371 | ** |
| 66347 | 66372 | ** 2) Frees the pointer at Wal.pFree, if any, using sqlite3_free(). |
| 66348 | 66373 | ** |
| 66349 | | -** 3) Returns SQLITE_IOERR. |
| 66374 | +** 3) Set pWal->apWiData[pWal->iWiPg] to pWal->pWiValue if not NULL |
| 66375 | +** |
| 66376 | +** 4) Returns SQLITE_IOERR. |
| 66350 | 66377 | */ |
| 66351 | 66378 | static int walHandleException(Wal *pWal){ |
| 66352 | 66379 | if( pWal->exclusiveMode==0 ){ |
| 66353 | 66380 | static const int S = 1; |
| 66354 | 66381 | static const int E = (1<<SQLITE_SHM_NLOCK); |
| | @@ -66363,10 +66390,14 @@ |
| 66363 | 66390 | if( (E<<ii) & mUnlock ) walUnlockExclusive(pWal, ii, 1); |
| 66364 | 66391 | } |
| 66365 | 66392 | } |
| 66366 | 66393 | sqlite3_free(pWal->pFree); |
| 66367 | 66394 | pWal->pFree = 0; |
| 66395 | + if( pWal->pWiValue ){ |
| 66396 | + pWal->apWiData[pWal->iWiPg] = pWal->pWiValue; |
| 66397 | + pWal->pWiValue = 0; |
| 66398 | + } |
| 66368 | 66399 | return SQLITE_IOERR_IN_PAGE; |
| 66369 | 66400 | } |
| 66370 | 66401 | |
| 66371 | 66402 | /* |
| 66372 | 66403 | ** Assert that the Wal.lockMask mask, which indicates the locks held |
| | @@ -67120,11 +67151,12 @@ |
| 67120 | 67151 | i64 iDbOff; /* Offset of db file entry */ |
| 67121 | 67152 | i64 iWalOff; /* Offset of wal file entry */ |
| 67122 | 67153 | |
| 67123 | 67154 | rc = walHashGet(pWal, walFramePage(i), &sLoc); |
| 67124 | 67155 | if( rc!=SQLITE_OK ) break; |
| 67125 | | - pgno = sLoc.aPgno[i-sLoc.iZero]; |
| 67156 | + assert( i - sLoc.iZero - 1 >=0 ); |
| 67157 | + pgno = sLoc.aPgno[i-sLoc.iZero-1]; |
| 67126 | 67158 | iDbOff = (i64)(pgno-1) * szPage; |
| 67127 | 67159 | |
| 67128 | 67160 | if( iDbOff+szPage<=szDb ){ |
| 67129 | 67161 | iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; |
| 67130 | 67162 | rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); |
| | @@ -91009,11 +91041,11 @@ |
| 91009 | 91041 | */ |
| 91010 | 91042 | SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){ |
| 91011 | 91043 | Vdbe *v = (Vdbe*)pStmt; |
| 91012 | 91044 | int rc; |
| 91013 | 91045 | sqlite3_mutex_enter(v->db->mutex); |
| 91014 | | - if( v->explain==eMode ){ |
| 91046 | + if( ((int)v->explain)==eMode ){ |
| 91015 | 91047 | rc = SQLITE_OK; |
| 91016 | 91048 | }else if( eMode<0 || eMode>2 ){ |
| 91017 | 91049 | rc = SQLITE_ERROR; |
| 91018 | 91050 | }else if( (v->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ |
| 91019 | 91051 | rc = SQLITE_ERROR; |
| | @@ -128754,23 +128786,28 @@ |
| 128754 | 128786 | ** Re-register the built-in LIKE functions. The caseSensitive |
| 128755 | 128787 | ** parameter determines whether or not the LIKE operator is case |
| 128756 | 128788 | ** sensitive. |
| 128757 | 128789 | */ |
| 128758 | 128790 | SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ |
| 128791 | + FuncDef *pDef; |
| 128759 | 128792 | struct compareInfo *pInfo; |
| 128760 | 128793 | int flags; |
| 128794 | + int nArg; |
| 128761 | 128795 | if( caseSensitive ){ |
| 128762 | 128796 | pInfo = (struct compareInfo*)&likeInfoAlt; |
| 128763 | 128797 | flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE; |
| 128764 | 128798 | }else{ |
| 128765 | 128799 | pInfo = (struct compareInfo*)&likeInfoNorm; |
| 128766 | 128800 | flags = SQLITE_FUNC_LIKE; |
| 128767 | 128801 | } |
| 128768 | | - sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); |
| 128769 | | - sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); |
| 128770 | | - sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags; |
| 128771 | | - sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags; |
| 128802 | + for(nArg=2; nArg<=3; nArg++){ |
| 128803 | + sqlite3CreateFunc(db, "like", nArg, SQLITE_UTF8, pInfo, likeFunc, |
| 128804 | + 0, 0, 0, 0, 0); |
| 128805 | + pDef = sqlite3FindFunction(db, "like", nArg, SQLITE_UTF8, 0); |
| 128806 | + pDef->funcFlags |= flags; |
| 128807 | + pDef->funcFlags &= ~SQLITE_FUNC_UNSAFE; |
| 128808 | + } |
| 128772 | 128809 | } |
| 128773 | 128810 | |
| 128774 | 128811 | /* |
| 128775 | 128812 | ** pExpr points to an expression which implements a function. If |
| 128776 | 128813 | ** it is appropriate to apply the LIKE optimization to that function |
| | @@ -134435,10 +134472,12 @@ |
| 134435 | 134472 | const char *(*db_name)(sqlite3*,int); |
| 134436 | 134473 | /* Version 3.40.0 and later */ |
| 134437 | 134474 | int (*value_encoding)(sqlite3_value*); |
| 134438 | 134475 | /* Version 3.41.0 and later */ |
| 134439 | 134476 | int (*is_interrupted)(sqlite3*); |
| 134477 | + /* Version 3.43.0 and later */ |
| 134478 | + int (*stmt_explain)(sqlite3_stmt*,int); |
| 134440 | 134479 | }; |
| 134441 | 134480 | |
| 134442 | 134481 | /* |
| 134443 | 134482 | ** This is the function signature used for all extension entry points. It |
| 134444 | 134483 | ** is also defined in the file "loadext.c". |
| | @@ -134763,10 +134802,12 @@ |
| 134763 | 134802 | #define sqlite3_db_name sqlite3_api->db_name |
| 134764 | 134803 | /* Version 3.40.0 and later */ |
| 134765 | 134804 | #define sqlite3_value_encoding sqlite3_api->value_encoding |
| 134766 | 134805 | /* Version 3.41.0 and later */ |
| 134767 | 134806 | #define sqlite3_is_interrupted sqlite3_api->is_interrupted |
| 134807 | +/* Version 3.43.0 and later */ |
| 134808 | +#define sqlite3_stmt_explain sqlite3_api->stmt_explain |
| 134768 | 134809 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 134769 | 134810 | |
| 134770 | 134811 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 134771 | 134812 | /* This case when the file really is being compiled as a loadable |
| 134772 | 134813 | ** extension */ |
| | @@ -135279,11 +135320,13 @@ |
| 135279 | 135320 | #endif |
| 135280 | 135321 | sqlite3_db_name, |
| 135281 | 135322 | /* Version 3.40.0 and later */ |
| 135282 | 135323 | sqlite3_value_encoding, |
| 135283 | 135324 | /* Version 3.41.0 and later */ |
| 135284 | | - sqlite3_is_interrupted |
| 135325 | + sqlite3_is_interrupted, |
| 135326 | + /* Version 3.43.0 and later */ |
| 135327 | + sqlite3_stmt_explain |
| 135285 | 135328 | }; |
| 135286 | 135329 | |
| 135287 | 135330 | /* True if x is the directory separator character |
| 135288 | 135331 | */ |
| 135289 | 135332 | #if SQLITE_OS_WIN |
| | @@ -151690,13 +151733,13 @@ |
| 151690 | 151733 | if( aXRef[i]>=0 ){ |
| 151691 | 151734 | pList = sqlite3ExprListAppend(pParse, pList, |
| 151692 | 151735 | sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0) |
| 151693 | 151736 | ); |
| 151694 | 151737 | }else{ |
| 151695 | | - Expr *pRow = exprRowColumn(pParse, i); |
| 151696 | | - if( pRow ) pRow->op2 = OPFLAG_NOCHNG; |
| 151697 | | - pList = sqlite3ExprListAppend(pParse, pList, pRow); |
| 151738 | + Expr *pRowExpr = exprRowColumn(pParse, i); |
| 151739 | + if( pRowExpr ) pRowExpr->op2 = OPFLAG_NOCHNG; |
| 151740 | + pList = sqlite3ExprListAppend(pParse, pList, pRowExpr); |
| 151698 | 151741 | } |
| 151699 | 151742 | } |
| 151700 | 151743 | |
| 151701 | 151744 | updateFromSelect(pParse, ephemTab, pPk, pList, pSrc, pWhere, 0, 0); |
| 151702 | 151745 | sqlite3ExprListDelete(db, pList); |
| | @@ -151977,11 +152020,11 @@ |
| 151977 | 152020 | sCol[0].pLeft = &sCol[1]; |
| 151978 | 152021 | sCol[1].iColumn = pIdx->aiColumn[ii]; |
| 151979 | 152022 | pExpr = &sCol[0]; |
| 151980 | 152023 | } |
| 151981 | 152024 | for(jj=0; jj<nn; jj++){ |
| 151982 | | - if( sqlite3ExprCompare(pParse,pTarget->a[jj].pExpr,pExpr,iCursor)<2 ){ |
| 152025 | + if( sqlite3ExprCompare(0,pTarget->a[jj].pExpr,pExpr,iCursor)<2 ){ |
| 151983 | 152026 | break; /* Column ii of the index matches column jj of target */ |
| 151984 | 152027 | } |
| 151985 | 152028 | } |
| 151986 | 152029 | if( jj>=nn ){ |
| 151987 | 152030 | /* The target contains no match for column jj of the index */ |
| | @@ -226230,12 +226273,12 @@ |
| 226230 | 226273 | ** extra disk space, as no extra entries are added to the FTS index. |
| 226231 | 226274 | ** On the other hand, it may require more CPU cycles to run MATCH queries, |
| 226232 | 226275 | ** as separate queries of the FTS index are required for each synonym. |
| 226233 | 226276 | ** |
| 226234 | 226277 | ** When using methods (2) or (3), it is important that the tokenizer only |
| 226235 | | -** provide synonyms when tokenizing document text (method (2)) or query |
| 226236 | | -** text (method (3)), not both. Doing so will not cause any errors, but is |
| 226278 | +** provide synonyms when tokenizing document text (method (3)) or query |
| 226279 | +** text (method (2)), not both. Doing so will not cause any errors, but is |
| 226237 | 226280 | ** inefficient. |
| 226238 | 226281 | */ |
| 226239 | 226282 | typedef struct Fts5Tokenizer Fts5Tokenizer; |
| 226240 | 226283 | typedef struct fts5_tokenizer fts5_tokenizer; |
| 226241 | 226284 | struct fts5_tokenizer { |
| | @@ -233429,10 +233472,12 @@ |
| 233429 | 233472 | |
| 233430 | 233473 | if( zRet ) zRet = fts5PrintfAppend(zRet, "}"); |
| 233431 | 233474 | if( zRet==0 ) return 0; |
| 233432 | 233475 | } |
| 233433 | 233476 | |
| 233477 | + }else if( pExpr->eType==0 ){ |
| 233478 | + zRet = sqlite3_mprintf("{}"); |
| 233434 | 233479 | }else{ |
| 233435 | 233480 | char const *zOp = 0; |
| 233436 | 233481 | int i; |
| 233437 | 233482 | switch( pExpr->eType ){ |
| 233438 | 233483 | case FTS5_AND: zOp = "AND"; break; |
| | @@ -242379,11 +242424,11 @@ |
| 242379 | 242424 | iTermOff = szLeaf; |
| 242380 | 242425 | } |
| 242381 | 242426 | fts5DecodeRowidList(&rc, &s, &a[4], iTermOff-4); |
| 242382 | 242427 | |
| 242383 | 242428 | iOff = iTermOff; |
| 242384 | | - while( iOff<szLeaf ){ |
| 242429 | + while( iOff<szLeaf && rc==SQLITE_OK ){ |
| 242385 | 242430 | int nAppend; |
| 242386 | 242431 | |
| 242387 | 242432 | /* Read the term data for the next term*/ |
| 242388 | 242433 | iOff += fts5GetVarint32(&a[iOff], nAppend); |
| 242389 | 242434 | term.n = nKeep; |
| | @@ -242399,12 +242444,15 @@ |
| 242399 | 242444 | iPgidxOff += fts5GetVarint32(&a[iPgidxOff], nIncr); |
| 242400 | 242445 | iTermOff += nIncr; |
| 242401 | 242446 | }else{ |
| 242402 | 242447 | iTermOff = szLeaf; |
| 242403 | 242448 | } |
| 242404 | | - |
| 242405 | | - fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff); |
| 242449 | + if( iTermOff>szLeaf ){ |
| 242450 | + rc = FTS5_CORRUPT; |
| 242451 | + }else{ |
| 242452 | + fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff); |
| 242453 | + } |
| 242406 | 242454 | iOff = iTermOff; |
| 242407 | 242455 | if( iOff<szLeaf ){ |
| 242408 | 242456 | iOff += fts5GetVarint32(&a[iOff], nKeep); |
| 242409 | 242457 | } |
| 242410 | 242458 | } |
| | @@ -245683,11 +245731,11 @@ |
| 245683 | 245731 | int nArg, /* Number of args */ |
| 245684 | 245732 | sqlite3_value **apUnused /* Function arguments */ |
| 245685 | 245733 | ){ |
| 245686 | 245734 | assert( nArg==0 ); |
| 245687 | 245735 | UNUSED_PARAM2(nArg, apUnused); |
| 245688 | | - sqlite3_result_text(pCtx, "fts5: 2023-08-11 22:40:06 3bc0693c4633f545f09dbee702e25354504b20836373a068447e6c61cb2ebd79", -1, SQLITE_TRANSIENT); |
| 245736 | + sqlite3_result_text(pCtx, "fts5: 2023-08-17 17:48:20 3c06709335eb4b98e3a684e3ebbae69eeb6a21b452bce29159c82bb632d6a042", -1, SQLITE_TRANSIENT); |
| 245689 | 245737 | } |
| 245690 | 245738 | |
| 245691 | 245739 | /* |
| 245692 | 245740 | ** Return true if zName is the extension on one of the shadow tables used |
| 245693 | 245741 | ** by this module. |
| 245694 | 245742 | |