11#ifndef USE_LIBSQLITE3
22/******************************************************************************
33** This file is an amalgamation of many separate C source files from SQLite
4- ** version 3.53.3 . By combining all the individual C code files into this
4+ ** version 3.53.4 . By combining all the individual C code files into this
55** single large file, the entire code can be compiled as a single translation
66** unit. This allows many compilers to do optimizations that would not be
77** possible if the files were compiled separately. Performance improvements
1919** separate file. This file contains only code for the core SQLite library.
2020**
2121** The content in this amalgamation comes from Fossil check-in
22- ** d4c0e51e4aeb96955b99185ab9cde75c339e with changes in files:
22+ ** bf7c7f30031888f4e796e429ab3978879485 with changes in files:
2323**
2424**
2525*/
@@ -468,12 +468,12 @@ extern "C" {
468468** [sqlite3_libversion_number()], [sqlite3_sourceid()],
469469** [sqlite_version()] and [sqlite_source_id()].
470470*/
471- #define SQLITE_VERSION "3.53.3 "
472- #define SQLITE_VERSION_NUMBER 3053003
473- #define SQLITE_SOURCE_ID "2026-06-26 20:14:12 d4c0e51e4aeb96955b99185ab9cde75c339e2c29c3f3f12428d364a10d782c62 "
471+ #define SQLITE_VERSION "3.53.4 "
472+ #define SQLITE_VERSION_NUMBER 3053004
473+ #define SQLITE_SOURCE_ID "2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc "
474474#define SQLITE_SCM_BRANCH "branch-3.53"
475- #define SQLITE_SCM_TAGS "release version-3.53.3 "
476- #define SQLITE_SCM_DATETIME "2026-06-26T20:14:12.354Z "
475+ #define SQLITE_SCM_TAGS "release version-3.53.4 "
476+ #define SQLITE_SCM_DATETIME "2026-07-24T19:02:57.525Z "
477477
478478/*
479479** CAPI3REF: Run-Time Library Version Numbers
@@ -27592,7 +27592,7 @@ SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p
2759227592 }else{
2759327593 double r;
2759427594 rc = pVfs->xCurrentTime(pVfs, &r);
27595- *pTimeOut = (sqlite3_int64) (r*86400000.0);
27595+ *pTimeOut = sqlite3RealToI64 (r*86400000.0);
2759627596 }
2759727597 return rc;
2759827598}
@@ -60970,7 +60970,7 @@ static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){
6097060970 cksum -= zOut[u];
6097160971 }
6097260972 }
60973- if( rc!=SQLITE_OK || cksum ){
60973+ if( rc!=SQLITE_OK || cksum || zOut[0]==0 ){
6097460974 /* If the checksum doesn't add up, then one or more of the disk sectors
6097560975 ** containing the super-journal filename is corrupted. This means
6097660976 ** definitely roll back, so just return SQLITE_OK and report a (nul)
@@ -111438,11 +111438,20 @@ static SQLITE_NOINLINE void resolveSetExprSubtypeArg(ExprList *pList){
111438111438 nn = pList ? pList->nExpr : 0;
111439111439 for(ii=0; ii<nn; ii++){
111440111440 Expr *pExpr = pList->a[ii].pExpr;
111441- ExprSetProperty(pExpr, EP_SubtArg);
111442- if( pExpr->op==TK_SELECT ){
111443- assert( ExprUseXSelect(pExpr) );
111444- assert( pExpr->x.pSelect!=0 );
111445- resolveSetExprSubtypeArg(pExpr->x.pSelect->pEList);
111441+ while( 1 /*exit-by-break*/ ){
111442+ ExprSetProperty(pExpr, EP_SubtArg);
111443+ if( pExpr->op==TK_SELECT ){
111444+ assert( ExprUseXSelect(pExpr) );
111445+ assert( pExpr->x.pSelect!=0 );
111446+ resolveSetExprSubtypeArg(pExpr->x.pSelect->pEList);
111447+ break;
111448+ }
111449+ if( pExpr->op==TK_UPLUS ){
111450+ pExpr = pExpr->pLeft;
111451+ assert( pExpr!=0 );
111452+ }else{
111453+ break;
111454+ }
111446111455 }
111447111456 }
111448111457}
@@ -176955,7 +176964,7 @@ static void nth_valueStepFunc(
176955176964 break;
176956176965 case SQLITE_FLOAT: {
176957176966 double fVal = sqlite3_value_double(apArg[1]);
176958- if( ((i64) fVal)!=fVal ) goto error_out;
176967+ if( sqlite3RealToI64( fVal)!=fVal ) goto error_out;
176959176968 iVal = (i64)fVal;
176960176969 break;
176961176970 }
@@ -210777,8 +210786,8 @@ static int fts3StringAppend(
210777210786 ** to grow the buffer until so that it is big enough to accommodate the
210778210787 ** appended data.
210779210788 */
210780- if( pStr->n+nAppend+1>=pStr->nAlloc ){
210781- sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64 )nAppend+100;
210789+ if( (i64) pStr->n+(i64) nAppend+1>=(i64) pStr->nAlloc ){
210790+ i64 nAlloc = pStr->nAlloc+(i64 )nAppend+100;
210782210791 char *zNew = sqlite3_realloc64(pStr->z, nAlloc);
210783210792 if( !zNew ){
210784210793 return SQLITE_NOMEM;
@@ -214982,7 +214991,8 @@ static u32 jsonTranslateBlobToText(
214982214991 if( sz==0 ) goto malformed_jsonb;
214983214992 if( zIn[0]=='-' ){
214984214993 jsonAppendChar(pOut, '-');
214985- k++;
214994+ if( sz<=1 ) goto malformed_jsonb;
214995+ k = 1;
214986214996 }
214987214997 if( zIn[k]=='.' ){
214988214998 jsonAppendChar(pOut, '0');
@@ -217946,7 +217956,9 @@ static int jsonSkipLabel(JsonEachCursor *p){
217946217956 if( p->eType==JSONB_OBJECT ){
217947217957 u32 sz = 0;
217948217958 u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz);
217949- return p->i + n + sz;
217959+ sz += p->i + n;
217960+ if( sz >= p->sParse.nBlob ) sz = p->i;
217961+ return sz;
217950217962 }else{
217951217963 return p->i;
217952217964 }
@@ -226907,8 +226919,8 @@ static int rbuDeltaApply(
226907226919 int lenDelta, /* Length of the delta */
226908226920 char *zOut /* Write the output into this preallocated buffer */
226909226921){
226910- unsigned int limit;
226911- unsigned int total = 0;
226922+ sqlite3_uint64 limit;
226923+ sqlite3_uint64 total = 0;
226912226924#if RBU_ENABLE_DELTA_CKSUM
226913226925 char *zOrigOut = zOut;
226914226926#endif
@@ -226918,16 +226930,16 @@ static int rbuDeltaApply(
226918226930 /* ERROR: size integer not terminated by "\n" */
226919226931 return -1;
226920226932 }
226921- zDelta++; lenDelta--;
226922- while( *zDelta && lenDelta>0 ){
226933+ zDelta++; lenDelta--; /* Skip the \n */
226934+ while( lenDelta>0 && zDelta[0] ){
226923226935 unsigned int cnt, ofst;
226924226936 cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
226925226937 if( lenDelta<=0 ) return -1;
226926226938 switch( zDelta[0] ){
226927226939 case '@': {
226928226940 zDelta++; lenDelta--;
226929226941 ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
226930- if( lenDelta>0 || zDelta[0]!=',' ){
226942+ if( lenDelta>0 && zDelta[0]!=',' ){
226931226943 /* ERROR: copy command not terminated by ',' */
226932226944 return -1;
226933226945 }
@@ -226952,7 +226964,7 @@ static int rbuDeltaApply(
226952226964 /* ERROR: insert command gives an output larger than predicted */
226953226965 return -1;
226954226966 }
226955- if( (i64) cnt>(i64) lenDelta ){
226967+ if( cnt>lenDelta ){
226956226968 /* ERROR: insert count exceeds size of delta */
226957226969 return -1;
226958226970 }
@@ -228965,13 +228977,13 @@ static int rbuGetUpdateStmt(
228965228977 char *zUpdate = 0;
228966228978
228967228979 pUp->zMask = (char*)&pUp[1];
228968- memcpy(pUp->zMask, zMask, pIter->nTblCol);
228969228980 pUp->pNext = pIter->pRbuUpdate;
228970228981 pIter->pRbuUpdate = pUp;
228971228982
228972228983 if( zSet ){
228973228984 const char *zPrefix = "";
228974-
228985+ assert( p->rc==SQLITE_OK );
228986+ memcpy(pUp->zMask, zMask, pIter->nTblCol);
228975228987 if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_";
228976228988 zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s",
228977228989 zPrefix, pIter->zTbl, zSet, zWhere
@@ -229061,6 +229073,9 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
229061229073
229062229074 case RBU_STATE_ROW:
229063229075 pRet->nRow = sqlite3_column_int(pStmt, 1);
229076+ if( pRet->nRow<0 ){
229077+ rc = SQLITE_CORRUPT;
229078+ }
229064229079 break;
229065229080
229066229081 case RBU_STATE_PROGRESS:
@@ -240297,7 +240312,12 @@ static int sessionChangesetToHash(
240297240312
240298240313 pIter->in.bNoDiscard = 1;
240299240314 while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){
240300- rc = sessionOneChangeIterToHash(pGrp, pIter, bRebase);
240315+ if( bRebase && pIter->bPatchset ){
240316+ /* A patchset may not be used as a rebase */
240317+ rc = SQLITE_ERROR;
240318+ }else{
240319+ rc = sessionOneChangeIterToHash(pGrp, pIter, bRebase);
240320+ }
240301240321 if( rc!=SQLITE_OK ) break;
240302240322 }
240303240323
@@ -240674,13 +240694,14 @@ static void sessionAppendPartialUpdate(
240674240694 int i;
240675240695 u8 *a1 = aRec;
240676240696 u8 *a2 = aChange;
240697+ u8 *a2Eof = &a2[nChange];
240677240698
240678240699 *pOut++ = SQLITE_UPDATE;
240679240700 *pOut++ = pIter->bIndirect;
240680240701 for(i=0; i<pIter->nCol; i++){
240681240702 int n1 = sessionSerialLen(a1);
240682- int n2 = sessionSerialLen(a2);
240683- if( pIter->abPK[i] || a2[0]==0 ){
240703+ int n2 = (a2>=a2Eof) ? 0 : sessionSerialLen(a2);
240704+ if( n2<=0 || pIter->abPK[i] || a2[0]==0 ){
240684240705 if( !pIter->abPK[i] && a1[0] ) bData = 1;
240685240706 memcpy(pOut, a1, n1);
240686240707 pOut += n1;
@@ -240881,8 +240902,8 @@ SQLITE_API int sqlite3rebaser_configure(
240881240902 sqlite3_rebaser *p,
240882240903 int nRebase, const void *pRebase
240883240904){
240884- sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
240885240905 int rc; /* Return code */
240906+ sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
240886240907 rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
240887240908 if( rc==SQLITE_OK ){
240888240909 rc = sessionChangesetToHash(pIter, &p->grp, 1);
@@ -251702,6 +251723,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
251702251723 pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
251703251724 if( pRet ){
251704251725 pRet->nn = nByte;
251726+ pRet->szLeaf = 0;
251705251727 aOut = pRet->p = (u8*)pRet + szData;
251706251728 }else{
251707251729 rc = SQLITE_NOMEM;
@@ -251714,10 +251736,8 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
251714251736 sqlite3_free(pRet);
251715251737 pRet = 0;
251716251738 }else{
251717- /* TODO1: Fix this */
251718251739 pRet->p[nByte] = 0x00;
251719251740 pRet->p[nByte+1] = 0x00;
251720- pRet->szLeaf = fts5GetU16(&pRet->p[2]);
251721251741 }
251722251742 }
251723251743 p->rc = rc;
@@ -251738,9 +251758,17 @@ static void fts5DataRelease(Fts5Data *pData){
251738251758 sqlite3_free(pData);
251739251759}
251740251760
251761+ /*
251762+ ** Read a leaf-page record. This is similar to fts5DataRead(), except that
251763+ ** it fills in the Fts5Data.szLeaf value before returning.
251764+ */
251741251765static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
251742251766 Fts5Data *pRet = fts5DataRead(p, iRowid);
251743251767 if( pRet ){
251768+ assert( pRet->szLeaf==0 );
251769+ if( pRet->nn>=4 ){
251770+ pRet->szLeaf = fts5GetU16(&pRet->p[2]);
251771+ }
251744251772 if( pRet->szLeaf<4 || pRet->szLeaf>pRet->nn ){
251745251773 FTS5_CORRUPT_ROWID(p, iRowid);
251746251774 fts5DataRelease(pRet);
@@ -253650,6 +253678,10 @@ static void fts5SegIterNextInit(
253650253678
253651253679 pIter->iPgidxOff = pIter->pLeaf->szLeaf;
253652253680 pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], iTermOff);
253681+ if( iTermOff > pIter->pLeaf->szLeaf ){
253682+ p->rc = FTS5_CORRUPT;
253683+ return;
253684+ }
253653253685 pIter->iLeafOffset = iTermOff;
253654253686 fts5SegIterLoadTerm(p, pIter, 0);
253655253687 fts5SegIterLoadNPos(p, pIter);
@@ -255976,15 +256008,15 @@ static void fts5SecureDeleteOverflow(
255976256008 int iNext = 0;
255977256009 u8 *aPg = 0;
255978256010
255979- pLeaf = fts5DataRead (p, iRowid);
256011+ pLeaf = fts5LeafRead (p, iRowid);
255980256012 if( pLeaf==0 ) break;
255981256013 aPg = pLeaf->p;
255982256014
255983256015 iNext = fts5GetU16(&aPg[0]);
255984256016 if( iNext!=0 ){
255985256017 *pbLastInDoclist = 0;
255986256018 }
255987- if( iNext==0 && pLeaf->szLeaf!= pLeaf->nn ){
256019+ if( iNext==0 && pLeaf->szLeaf< pLeaf->nn ){
255988256020 fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext);
255989256021 }
255990256022
@@ -256271,15 +256303,15 @@ static void fts5DoSecureDelete(
256271256303 /* The entry being removed may be the only position list in
256272256304 ** its doclist. */
256273256305 for(iPgno=pSeg->iLeafPgno-1; iPgno>pSeg->iTermLeafPgno; iPgno-- ){
256274- Fts5Data *pPg = fts5DataRead (p, FTS5_SEGMENT_ROWID(iSegid, iPgno));
256306+ Fts5Data *pPg = fts5LeafRead (p, FTS5_SEGMENT_ROWID(iSegid, iPgno));
256275256307 int bEmpty = (pPg && pPg->nn==4);
256276256308 fts5DataRelease(pPg);
256277256309 if( bEmpty==0 ) break;
256278256310 }
256279256311
256280256312 if( iPgno==pSeg->iTermLeafPgno ){
256281256313 i64 iId = FTS5_SEGMENT_ROWID(iSegid, pSeg->iTermLeafPgno);
256282- Fts5Data *pTerm = fts5DataRead (p, iId);
256314+ Fts5Data *pTerm = fts5LeafRead (p, iId);
256283256315 if( pTerm && pTerm->szLeaf==pSeg->iTermLeafOffset ){
256284256316 u8 *aTermIdx = &pTerm->p[pTerm->szLeaf];
256285256317 int nTermIdx = pTerm->nn - pTerm->szLeaf;
@@ -259231,7 +259263,7 @@ static void fts5IndexIntegrityCheckEmpty(
259231259263 /* Now check that the iter.nEmpty leaves following the current leaf
259232259264 ** (a) exist and (b) contain no terms. */
259233259265 for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){
259234- Fts5Data *pLeaf = fts5DataRead (p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
259266+ Fts5Data *pLeaf = fts5LeafRead (p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
259235259267 if( pLeaf ){
259236259268 if( !fts5LeafIsTermless(pLeaf)
259237259269 || (i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf))
@@ -259359,7 +259391,7 @@ static void fts5IndexIntegrityCheckSegment(
259359259391 FTS5_CORRUPT_ROWID(p, iRow);
259360259392 }else{
259361259393 iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
259362- if( iOff+nTerm>pLeaf->szLeaf ){
259394+ if( (i64) iOff+(i64) nTerm>(i64) pLeaf->szLeaf ){
259363259395 FTS5_CORRUPT_ROWID(p, iRow);
259364259396 }else{
259365259397 res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
@@ -263087,19 +263119,23 @@ static int fts5ApiPhraseFirstColumn(
263087263119
263088263120 if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
263089263121 Fts5Sorter *pSorter = pCsr->pSorter;
263090- int n;
263091- if( pSorter ){
263092- int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
263093- n = pSorter->aIdx[iPhrase] - i1;
263094- pIter->a = &pSorter->aPoslist[i1];
263122+ if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
263123+ rc = SQLITE_RANGE;
263095263124 }else{
263096- rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
263097- }
263098- if( rc==SQLITE_OK ){
263099- assert( pIter->a || n==0 );
263100- pIter->b = (pIter->a ? &pIter->a[n] : 0);
263101- *piCol = 0;
263102- fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
263125+ int n;
263126+ if( pSorter ){
263127+ int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
263128+ n = pSorter->aIdx[iPhrase] - i1;
263129+ pIter->a = &pSorter->aPoslist[i1];
263130+ }else{
263131+ rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
263132+ }
263133+ if( rc==SQLITE_OK ){
263134+ assert( pIter->a || n==0 );
263135+ pIter->b = (pIter->a ? &pIter->a[n] : 0);
263136+ *piCol = 0;
263137+ fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
263138+ }
263103263139 }
263104263140 }else{
263105263141 int n;
@@ -264007,7 +264043,7 @@ static void fts5SourceIdFunc(
264007264043){
264008264044 assert( nArg==0 );
264009264045 UNUSED_PARAM2(nArg, apUnused);
264010- sqlite3_result_text(pCtx, "fts5: 2026-06-26 20:14:12 d4c0e51e4aeb96955b99185ab9cde75c339e2c29c3f3f12428d364a10d782c62 ", -1, SQLITE_TRANSIENT);
264046+ sqlite3_result_text(pCtx, "fts5: 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc ", -1, SQLITE_TRANSIENT);
264011264047}
264012264048
264013264049/*
0 commit comments