414 lines
15 KiB
Diff
414 lines
15 KiB
Diff
From 39264f1ed3bef5622f1fb1e302a074ae1c4f4054 Mon Sep 17 00:00:00 2001
|
|
From: tjuhasz <tjuhasz@redhat.com>
|
|
Date: Tue, 18 Aug 2026 14:59:41 +0200
|
|
Subject: [PATCH] update sqlite to 3.53.4
|
|
|
|
---
|
|
deps/sqlite/sqlite3.c | 140 ++++++++++++++++++++++++++----------------
|
|
deps/sqlite/sqlite3.h | 10 +--
|
|
2 files changed, 93 insertions(+), 57 deletions(-)
|
|
|
|
diff --git a/deps/sqlite/sqlite3.c b/deps/sqlite/sqlite3.c
|
|
index 09f3e4a..0644a39 100644
|
|
--- a/deps/sqlite/sqlite3.c
|
|
+++ b/deps/sqlite/sqlite3.c
|
|
@@ -1,6 +1,6 @@
|
|
/******************************************************************************
|
|
** This file is an amalgamation of many separate C source files from SQLite
|
|
-** version 3.53.3. By combining all the individual C code files into this
|
|
+** version 3.53.4. By combining all the individual C code files into this
|
|
** single large file, the entire code can be compiled as a single translation
|
|
** unit. This allows many compilers to do optimizations that would not be
|
|
** possible if the files were compiled separately. Performance improvements
|
|
@@ -18,7 +18,7 @@
|
|
** separate file. This file contains only code for the core SQLite library.
|
|
**
|
|
** The content in this amalgamation comes from Fossil check-in
|
|
-** d4c0e51e4aeb96955b99185ab9cde75c339e with changes in files:
|
|
+** bf7c7f30031888f4e796e429ab3978879485 with changes in files:
|
|
**
|
|
**
|
|
*/
|
|
@@ -467,12 +467,12 @@ extern "C" {
|
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
|
** [sqlite_version()] and [sqlite_source_id()].
|
|
*/
|
|
-#define SQLITE_VERSION "3.53.3"
|
|
-#define SQLITE_VERSION_NUMBER 3053003
|
|
-#define SQLITE_SOURCE_ID "2026-06-26 20:14:12 d4c0e51e4aeb96955b99185ab9cde75c339e2c29c3f3f12428d364a10d782c62"
|
|
+#define SQLITE_VERSION "3.53.4"
|
|
+#define SQLITE_VERSION_NUMBER 3053004
|
|
+#define SQLITE_SOURCE_ID "2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc"
|
|
#define SQLITE_SCM_BRANCH "branch-3.53"
|
|
-#define SQLITE_SCM_TAGS "release version-3.53.3"
|
|
-#define SQLITE_SCM_DATETIME "2026-06-26T20:14:12.354Z"
|
|
+#define SQLITE_SCM_TAGS "release version-3.53.4"
|
|
+#define SQLITE_SCM_DATETIME "2026-07-24T19:02:57.525Z"
|
|
|
|
/*
|
|
** CAPI3REF: Run-Time Library Version Numbers
|
|
@@ -27591,7 +27591,7 @@ SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p
|
|
}else{
|
|
double r;
|
|
rc = pVfs->xCurrentTime(pVfs, &r);
|
|
- *pTimeOut = (sqlite3_int64)(r*86400000.0);
|
|
+ *pTimeOut = sqlite3RealToI64(r*86400000.0);
|
|
}
|
|
return rc;
|
|
}
|
|
@@ -60969,7 +60969,7 @@ static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){
|
|
cksum -= zOut[u];
|
|
}
|
|
}
|
|
- if( rc!=SQLITE_OK || cksum ){
|
|
+ if( rc!=SQLITE_OK || cksum || zOut[0]==0 ){
|
|
/* If the checksum doesn't add up, then one or more of the disk sectors
|
|
** containing the super-journal filename is corrupted. This means
|
|
** definitely roll back, so just return SQLITE_OK and report a (nul)
|
|
@@ -111437,11 +111437,20 @@ static SQLITE_NOINLINE void resolveSetExprSubtypeArg(ExprList *pList){
|
|
nn = pList ? pList->nExpr : 0;
|
|
for(ii=0; ii<nn; ii++){
|
|
Expr *pExpr = pList->a[ii].pExpr;
|
|
- ExprSetProperty(pExpr, EP_SubtArg);
|
|
- if( pExpr->op==TK_SELECT ){
|
|
- assert( ExprUseXSelect(pExpr) );
|
|
- assert( pExpr->x.pSelect!=0 );
|
|
- resolveSetExprSubtypeArg(pExpr->x.pSelect->pEList);
|
|
+ while( 1 /*exit-by-break*/ ){
|
|
+ ExprSetProperty(pExpr, EP_SubtArg);
|
|
+ if( pExpr->op==TK_SELECT ){
|
|
+ assert( ExprUseXSelect(pExpr) );
|
|
+ assert( pExpr->x.pSelect!=0 );
|
|
+ resolveSetExprSubtypeArg(pExpr->x.pSelect->pEList);
|
|
+ break;
|
|
+ }
|
|
+ if( pExpr->op==TK_UPLUS ){
|
|
+ pExpr = pExpr->pLeft;
|
|
+ assert( pExpr!=0 );
|
|
+ }else{
|
|
+ break;
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
@@ -176954,7 +176963,7 @@ static void nth_valueStepFunc(
|
|
break;
|
|
case SQLITE_FLOAT: {
|
|
double fVal = sqlite3_value_double(apArg[1]);
|
|
- if( ((i64)fVal)!=fVal ) goto error_out;
|
|
+ if( sqlite3RealToI64(fVal)!=fVal ) goto error_out;
|
|
iVal = (i64)fVal;
|
|
break;
|
|
}
|
|
@@ -210776,8 +210785,8 @@ static int fts3StringAppend(
|
|
** to grow the buffer until so that it is big enough to accommodate the
|
|
** appended data.
|
|
*/
|
|
- if( pStr->n+nAppend+1>=pStr->nAlloc ){
|
|
- sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100;
|
|
+ if( (i64)pStr->n+(i64)nAppend+1>=(i64)pStr->nAlloc ){
|
|
+ i64 nAlloc = pStr->nAlloc+(i64)nAppend+100;
|
|
char *zNew = sqlite3_realloc64(pStr->z, nAlloc);
|
|
if( !zNew ){
|
|
return SQLITE_NOMEM;
|
|
@@ -214981,7 +214990,8 @@ static u32 jsonTranslateBlobToText(
|
|
if( sz==0 ) goto malformed_jsonb;
|
|
if( zIn[0]=='-' ){
|
|
jsonAppendChar(pOut, '-');
|
|
- k++;
|
|
+ if( sz<=1 ) goto malformed_jsonb;
|
|
+ k = 1;
|
|
}
|
|
if( zIn[k]=='.' ){
|
|
jsonAppendChar(pOut, '0');
|
|
@@ -217945,7 +217955,9 @@ static int jsonSkipLabel(JsonEachCursor *p){
|
|
if( p->eType==JSONB_OBJECT ){
|
|
u32 sz = 0;
|
|
u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz);
|
|
- return p->i + n + sz;
|
|
+ sz += p->i + n;
|
|
+ if( sz >= p->sParse.nBlob ) sz = p->i;
|
|
+ return sz;
|
|
}else{
|
|
return p->i;
|
|
}
|
|
@@ -226906,8 +226918,8 @@ static int rbuDeltaApply(
|
|
int lenDelta, /* Length of the delta */
|
|
char *zOut /* Write the output into this preallocated buffer */
|
|
){
|
|
- unsigned int limit;
|
|
- unsigned int total = 0;
|
|
+ sqlite3_uint64 limit;
|
|
+ sqlite3_uint64 total = 0;
|
|
#if RBU_ENABLE_DELTA_CKSUM
|
|
char *zOrigOut = zOut;
|
|
#endif
|
|
@@ -226917,8 +226929,8 @@ static int rbuDeltaApply(
|
|
/* ERROR: size integer not terminated by "\n" */
|
|
return -1;
|
|
}
|
|
- zDelta++; lenDelta--;
|
|
- while( *zDelta && lenDelta>0 ){
|
|
+ zDelta++; lenDelta--; /* Skip the \n */
|
|
+ while( lenDelta>0 && zDelta[0] ){
|
|
unsigned int cnt, ofst;
|
|
cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
|
|
if( lenDelta<=0 ) return -1;
|
|
@@ -226926,7 +226938,7 @@ static int rbuDeltaApply(
|
|
case '@': {
|
|
zDelta++; lenDelta--;
|
|
ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
|
|
- if( lenDelta>0 || zDelta[0]!=',' ){
|
|
+ if( lenDelta>0 && zDelta[0]!=',' ){
|
|
/* ERROR: copy command not terminated by ',' */
|
|
return -1;
|
|
}
|
|
@@ -226951,7 +226963,7 @@ static int rbuDeltaApply(
|
|
/* ERROR: insert command gives an output larger than predicted */
|
|
return -1;
|
|
}
|
|
- if( (i64)cnt>(i64)lenDelta ){
|
|
+ if( cnt>lenDelta ){
|
|
/* ERROR: insert count exceeds size of delta */
|
|
return -1;
|
|
}
|
|
@@ -228964,13 +228976,13 @@ static int rbuGetUpdateStmt(
|
|
char *zUpdate = 0;
|
|
|
|
pUp->zMask = (char*)&pUp[1];
|
|
- memcpy(pUp->zMask, zMask, pIter->nTblCol);
|
|
pUp->pNext = pIter->pRbuUpdate;
|
|
pIter->pRbuUpdate = pUp;
|
|
|
|
if( zSet ){
|
|
const char *zPrefix = "";
|
|
-
|
|
+ assert( p->rc==SQLITE_OK );
|
|
+ memcpy(pUp->zMask, zMask, pIter->nTblCol);
|
|
if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_";
|
|
zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s",
|
|
zPrefix, pIter->zTbl, zSet, zWhere
|
|
@@ -229060,6 +229072,9 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
|
|
|
|
case RBU_STATE_ROW:
|
|
pRet->nRow = sqlite3_column_int(pStmt, 1);
|
|
+ if( pRet->nRow<0 ){
|
|
+ rc = SQLITE_CORRUPT;
|
|
+ }
|
|
break;
|
|
|
|
case RBU_STATE_PROGRESS:
|
|
@@ -240296,7 +240311,12 @@ static int sessionChangesetToHash(
|
|
|
|
pIter->in.bNoDiscard = 1;
|
|
while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){
|
|
- rc = sessionOneChangeIterToHash(pGrp, pIter, bRebase);
|
|
+ if( bRebase && pIter->bPatchset ){
|
|
+ /* A patchset may not be used as a rebase */
|
|
+ rc = SQLITE_ERROR;
|
|
+ }else{
|
|
+ rc = sessionOneChangeIterToHash(pGrp, pIter, bRebase);
|
|
+ }
|
|
if( rc!=SQLITE_OK ) break;
|
|
}
|
|
|
|
@@ -240673,13 +240693,14 @@ static void sessionAppendPartialUpdate(
|
|
int i;
|
|
u8 *a1 = aRec;
|
|
u8 *a2 = aChange;
|
|
+ u8 *a2Eof = &a2[nChange];
|
|
|
|
*pOut++ = SQLITE_UPDATE;
|
|
*pOut++ = pIter->bIndirect;
|
|
for(i=0; i<pIter->nCol; i++){
|
|
int n1 = sessionSerialLen(a1);
|
|
- int n2 = sessionSerialLen(a2);
|
|
- if( pIter->abPK[i] || a2[0]==0 ){
|
|
+ int n2 = (a2>=a2Eof) ? 0 : sessionSerialLen(a2);
|
|
+ if( n2<=0 || pIter->abPK[i] || a2[0]==0 ){
|
|
if( !pIter->abPK[i] && a1[0] ) bData = 1;
|
|
memcpy(pOut, a1, n1);
|
|
pOut += n1;
|
|
@@ -240880,8 +240901,8 @@ SQLITE_API int sqlite3rebaser_configure(
|
|
sqlite3_rebaser *p,
|
|
int nRebase, const void *pRebase
|
|
){
|
|
- sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
|
|
int rc; /* Return code */
|
|
+ sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
|
|
rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
|
|
if( rc==SQLITE_OK ){
|
|
rc = sessionChangesetToHash(pIter, &p->grp, 1);
|
|
@@ -251701,6 +251722,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
|
|
pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
|
|
if( pRet ){
|
|
pRet->nn = nByte;
|
|
+ pRet->szLeaf = 0;
|
|
aOut = pRet->p = (u8*)pRet + szData;
|
|
}else{
|
|
rc = SQLITE_NOMEM;
|
|
@@ -251713,10 +251735,8 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
|
|
sqlite3_free(pRet);
|
|
pRet = 0;
|
|
}else{
|
|
- /* TODO1: Fix this */
|
|
pRet->p[nByte] = 0x00;
|
|
pRet->p[nByte+1] = 0x00;
|
|
- pRet->szLeaf = fts5GetU16(&pRet->p[2]);
|
|
}
|
|
}
|
|
p->rc = rc;
|
|
@@ -251737,9 +251757,17 @@ static void fts5DataRelease(Fts5Data *pData){
|
|
sqlite3_free(pData);
|
|
}
|
|
|
|
+/*
|
|
+** Read a leaf-page record. This is similar to fts5DataRead(), except that
|
|
+** it fills in the Fts5Data.szLeaf value before returning.
|
|
+*/
|
|
static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
|
|
Fts5Data *pRet = fts5DataRead(p, iRowid);
|
|
if( pRet ){
|
|
+ assert( pRet->szLeaf==0 );
|
|
+ if( pRet->nn>=4 ){
|
|
+ pRet->szLeaf = fts5GetU16(&pRet->p[2]);
|
|
+ }
|
|
if( pRet->szLeaf<4 || pRet->szLeaf>pRet->nn ){
|
|
FTS5_CORRUPT_ROWID(p, iRowid);
|
|
fts5DataRelease(pRet);
|
|
@@ -253649,6 +253677,10 @@ static void fts5SegIterNextInit(
|
|
|
|
pIter->iPgidxOff = pIter->pLeaf->szLeaf;
|
|
pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], iTermOff);
|
|
+ if( iTermOff > pIter->pLeaf->szLeaf ){
|
|
+ p->rc = FTS5_CORRUPT;
|
|
+ return;
|
|
+ }
|
|
pIter->iLeafOffset = iTermOff;
|
|
fts5SegIterLoadTerm(p, pIter, 0);
|
|
fts5SegIterLoadNPos(p, pIter);
|
|
@@ -255975,7 +256007,7 @@ static void fts5SecureDeleteOverflow(
|
|
int iNext = 0;
|
|
u8 *aPg = 0;
|
|
|
|
- pLeaf = fts5DataRead(p, iRowid);
|
|
+ pLeaf = fts5LeafRead(p, iRowid);
|
|
if( pLeaf==0 ) break;
|
|
aPg = pLeaf->p;
|
|
|
|
@@ -255983,7 +256015,7 @@ static void fts5SecureDeleteOverflow(
|
|
if( iNext!=0 ){
|
|
*pbLastInDoclist = 0;
|
|
}
|
|
- if( iNext==0 && pLeaf->szLeaf!=pLeaf->nn ){
|
|
+ if( iNext==0 && pLeaf->szLeaf<pLeaf->nn ){
|
|
fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext);
|
|
}
|
|
|
|
@@ -256270,7 +256302,7 @@ static void fts5DoSecureDelete(
|
|
/* The entry being removed may be the only position list in
|
|
** its doclist. */
|
|
for(iPgno=pSeg->iLeafPgno-1; iPgno>pSeg->iTermLeafPgno; iPgno-- ){
|
|
- Fts5Data *pPg = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno));
|
|
+ Fts5Data *pPg = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno));
|
|
int bEmpty = (pPg && pPg->nn==4);
|
|
fts5DataRelease(pPg);
|
|
if( bEmpty==0 ) break;
|
|
@@ -256278,7 +256310,7 @@ static void fts5DoSecureDelete(
|
|
|
|
if( iPgno==pSeg->iTermLeafPgno ){
|
|
i64 iId = FTS5_SEGMENT_ROWID(iSegid, pSeg->iTermLeafPgno);
|
|
- Fts5Data *pTerm = fts5DataRead(p, iId);
|
|
+ Fts5Data *pTerm = fts5LeafRead(p, iId);
|
|
if( pTerm && pTerm->szLeaf==pSeg->iTermLeafOffset ){
|
|
u8 *aTermIdx = &pTerm->p[pTerm->szLeaf];
|
|
int nTermIdx = pTerm->nn - pTerm->szLeaf;
|
|
@@ -259230,7 +259262,7 @@ static void fts5IndexIntegrityCheckEmpty(
|
|
/* Now check that the iter.nEmpty leaves following the current leaf
|
|
** (a) exist and (b) contain no terms. */
|
|
for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){
|
|
- Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
|
|
+ Fts5Data *pLeaf = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
|
|
if( pLeaf ){
|
|
if( !fts5LeafIsTermless(pLeaf)
|
|
|| (i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf))
|
|
@@ -259358,7 +259390,7 @@ static void fts5IndexIntegrityCheckSegment(
|
|
FTS5_CORRUPT_ROWID(p, iRow);
|
|
}else{
|
|
iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
|
|
- if( iOff+nTerm>pLeaf->szLeaf ){
|
|
+ if( (i64)iOff+(i64)nTerm>(i64)pLeaf->szLeaf ){
|
|
FTS5_CORRUPT_ROWID(p, iRow);
|
|
}else{
|
|
res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
|
|
@@ -263086,19 +263118,23 @@ static int fts5ApiPhraseFirstColumn(
|
|
|
|
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
|
|
Fts5Sorter *pSorter = pCsr->pSorter;
|
|
- int n;
|
|
- if( pSorter ){
|
|
- int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
|
|
- n = pSorter->aIdx[iPhrase] - i1;
|
|
- pIter->a = &pSorter->aPoslist[i1];
|
|
+ if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
|
|
+ rc = SQLITE_RANGE;
|
|
}else{
|
|
- rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
|
|
- }
|
|
- if( rc==SQLITE_OK ){
|
|
- assert( pIter->a || n==0 );
|
|
- pIter->b = (pIter->a ? &pIter->a[n] : 0);
|
|
- *piCol = 0;
|
|
- fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
|
|
+ int n;
|
|
+ if( pSorter ){
|
|
+ int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
|
|
+ n = pSorter->aIdx[iPhrase] - i1;
|
|
+ pIter->a = &pSorter->aPoslist[i1];
|
|
+ }else{
|
|
+ rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
|
|
+ }
|
|
+ if( rc==SQLITE_OK ){
|
|
+ assert( pIter->a || n==0 );
|
|
+ pIter->b = (pIter->a ? &pIter->a[n] : 0);
|
|
+ *piCol = 0;
|
|
+ fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
|
|
+ }
|
|
}
|
|
}else{
|
|
int n;
|
|
@@ -264006,7 +264042,7 @@ static void fts5SourceIdFunc(
|
|
){
|
|
assert( nArg==0 );
|
|
UNUSED_PARAM2(nArg, apUnused);
|
|
- sqlite3_result_text(pCtx, "fts5: 2026-06-26 20:14:12 d4c0e51e4aeb96955b99185ab9cde75c339e2c29c3f3f12428d364a10d782c62", -1, SQLITE_TRANSIENT);
|
|
+ sqlite3_result_text(pCtx, "fts5: 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc", -1, SQLITE_TRANSIENT);
|
|
}
|
|
|
|
/*
|
|
diff --git a/deps/sqlite/sqlite3.h b/deps/sqlite/sqlite3.h
|
|
index 00b22d9..c91b81c 100644
|
|
--- a/deps/sqlite/sqlite3.h
|
|
+++ b/deps/sqlite/sqlite3.h
|
|
@@ -146,12 +146,12 @@ extern "C" {
|
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
|
** [sqlite_version()] and [sqlite_source_id()].
|
|
*/
|
|
-#define SQLITE_VERSION "3.53.3"
|
|
-#define SQLITE_VERSION_NUMBER 3053003
|
|
-#define SQLITE_SOURCE_ID "2026-06-26 20:14:12 d4c0e51e4aeb96955b99185ab9cde75c339e2c29c3f3f12428d364a10d782c62"
|
|
+#define SQLITE_VERSION "3.53.4"
|
|
+#define SQLITE_VERSION_NUMBER 3053004
|
|
+#define SQLITE_SOURCE_ID "2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc"
|
|
#define SQLITE_SCM_BRANCH "branch-3.53"
|
|
-#define SQLITE_SCM_TAGS "release version-3.53.3"
|
|
-#define SQLITE_SCM_DATETIME "2026-06-26T20:14:12.354Z"
|
|
+#define SQLITE_SCM_TAGS "release version-3.53.4"
|
|
+#define SQLITE_SCM_DATETIME "2026-07-24T19:02:57.525Z"
|
|
|
|
/*
|
|
** CAPI3REF: Run-Time Library Version Numbers
|
|
--
|
|
2.55.0
|
|
|