From: dan Date: Thu, 9 Jul 2026 20:56:29 +0000 (+0000) Subject: Ensure that the "leaf-size" field of an fts5 record is only read from records that... X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=951de300afd5909ec269f67c03e7faf9b661b63b;p=thirdparty%2Fsqlite.git Ensure that the "leaf-size" field of an fts5 record is only read from records that are actually leaves and are large enough to contain it. Bug [bugs:/info/2026-07-09T20:15:55Z | 2026-07-09T20:15:55Z]. FossilOrigin-Name: fe52900694e045231e91047fbfd82577c7fa347d7352bd048867a9e95299a0d0 --- diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index c0aa45a492..05a61aeb9a 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -883,6 +883,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; @@ -895,10 +896,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; @@ -919,9 +918,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); @@ -5162,7 +5169,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; @@ -5457,7 +5464,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; @@ -5465,7 +5472,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; @@ -8417,7 +8424,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)) diff --git a/manifest b/manifest index 3435f31a13..3cb2ec6f70 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\ssqlite3_rsync\sutility\sprogram,\sfix\sthree\sdefects\sidentified\sby\n[bugs:/info/e2dfadf51209f12b|Bug\se2dfadf51209f12b]. -D 2026-07-09T16:34:26.844 +C Ensure\sthat\sthe\s"leaf-size"\sfield\sof\san\sfts5\srecord\sis\sonly\sread\sfrom\srecords\sthat\sare\sactually\sleaves\sand\sare\slarge\senough\sto\scontain\sit.\sBug\s[bugs:/info/2026-07-09T20:15:55Z\s|\s2026-07-09T20:15:55Z]. +D 2026-07-09T20:56:29.034 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -114,7 +114,7 @@ F ext/fts5/fts5_buffer.c dcc3f0352339fe79c9d8abbc1c2009bc3469206467880bf43558447 F ext/fts5/fts5_config.c bfba970fe1e4eed18ee57c8d51458e226db9a960ddf775c5e50e3d76603a667e F ext/fts5/fts5_expr.c b906c59e9e842805cc3eea4e131b822e586bb01260e542f67920c61798dcb53d F ext/fts5/fts5_hash.c 341a08ad0153b397b819ef3d7a7959c1dc3c84a6988a431d93dece8bd62ae10e -F ext/fts5/fts5_index.c 8be7cc58317fdef4dc4a352fcfdd7811b74b9b6be08bf6edeb237459bd045cc5 +F ext/fts5/fts5_index.c 0e3877bc71177fd70494a405d0c60572bf30184e953e7bc1268725c3bc8d23a6 F ext/fts5/fts5_main.c 7819fc80808a135c3ad7bec65071a053827d1e8fe7b77ddfd734ed451c2db7a9 F ext/fts5/fts5_storage.c 46b0024fdd8002fbfba162230e5cc212c8f019ba4075396860354bfaf549a546 F ext/fts5/fts5_tcl.c 2be6cc14f9448f720fd4418339cd202961a0801ea9424cb3d9de946f8f5a051c @@ -2214,8 +2214,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 1ce57ba94b63796d5c9b913e3973751ee4f146bdc452ce8b408d2c0cff7f598d -R 56866d483b0ee0d1f429199514cac299 -U drh -Z 8080e1abb61cdac3fcd460835fd18131 +P 805f3acd2b0e81c8274680cbc4cdd6b7b9246df8075ed9caba9e2780729a2740 +R 5be2523d6c3a388b70da09abeb3ec96a +U dan +Z 99f0e0d83d4051cee1aaca6f9271c8c5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index db7aeb38b6..58d062489e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -805f3acd2b0e81c8274680cbc4cdd6b7b9246df8075ed9caba9e2780729a2740 +fe52900694e045231e91047fbfd82577c7fa347d7352bd048867a9e95299a0d0