Index: ext/fts5/fts5_index.c ================================================================== --- ext/fts5/fts5_index.c +++ ext/fts5/fts5_index.c @@ -520,11 +520,12 @@ ** page. This macro evaluates to true if the leaf contains no terms, or ** false if it contains at least one term. */ #define fts5LeafIsTermless(x) ((x)->szLeaf >= (x)->nn) -#define fts5LeafFirstTermOff(x) (fts5GetU16(&x->p[(x)->szLeaf])) +#define fts5LeafFirstTermOff(x) (fts5GetU16(&(x)->p[(x)->szLeaf])) +#define fts5LeafFirstRowidOff(x) (fts5GetU16((x)->p)) /* ** poslist: ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. ** There is no way to tell if this is populated or not. @@ -1583,12 +1584,12 @@ fts5SegIterNextPage(p, pIter); } if( p->rc==SQLITE_OK ){ u8 *a = pIter->pLeaf->p; - pIter->iLeafOffset = fts5GetU16(&a[pIter->pLeaf->szLeaf]); - assert( pIter->iLeafOffset==4 ); + pIter->iLeafOffset = 4; + assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 ); fts5SegIterLoadTerm(p, pIter, 0); fts5SegIterLoadNPos(p, pIter); } } @@ -1785,16 +1786,16 @@ while( iOff==0 ){ fts5SegIterNextPage(p, pIter); pLeaf = pIter->pLeaf; if( pLeaf==0 ) break; ASSERT_SZLEAF_OK(pLeaf); - if( (iOff = fts5GetU16(&pLeaf->p[0])) && iOffszLeaf ){ + if( (iOff = fts5LeafFirstRowidOff(pLeaf)) && iOffszLeaf ){ iOff += sqlite3Fts5GetVarint(&pLeaf->p[iOff], (u64*)&pIter->iRowid); pIter->iLeafOffset = iOff; } else if( pLeaf->nn>pLeaf->szLeaf ){ - iOff = fts5GetU16(&pLeaf->p[pLeaf->szLeaf]); + iOff = fts5LeafFirstTermOff(pLeaf); pIter->iLeafOffset = iOff; bNewTerm = 1; } if( iOff>=pLeaf->szLeaf ){ p->rc = FTS5_CORRUPT; @@ -1879,11 +1880,11 @@ for(pgno=pIter->iLeafPgno+1; !p->rc && pgno<=pSeg->pgnoLast; pgno++){ i64 iAbs = FTS5_SEGMENT_ROWID(pSeg->iSegid, 0, pgno); Fts5Data *pNew = fts5DataRead(p, iAbs); if( pNew ){ int iRowid, bTermless; - iRowid = fts5GetU16(pNew->p); + iRowid = fts5LeafFirstRowidOff(pNew); bTermless = fts5LeafIsTermless(pNew); if( iRowid ){ SWAPVAL(Fts5Data*, pNew, pLast); pgnoLast = pgno; } @@ -1997,11 +1998,11 @@ int nPgTerm = (pIter->pLeaf->nn - pIter->pLeaf->szLeaf) >> 1; assert( p->rc==SQLITE_OK ); assert( pIter->pLeaf ); - iOff = fts5GetU16(&a[n]); + iOff = fts5LeafFirstTermOff(pIter->pLeaf); if( iOff<4 || iOff>=n ){ p->rc = FTS5_CORRUPT; return; } @@ -2432,11 +2433,11 @@ if( p->rc==SQLITE_OK ){ int iOff; u8 *a = pIter->pLeaf->p; int n = pIter->pLeaf->szLeaf; - iOff = fts5GetU16(&a[0]); + iOff = fts5LeafFirstRowidOff(pIter->pLeaf); if( iOff<4 || iOff>=n ){ p->rc = FTS5_CORRUPT; }else{ iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid); pIter->iLeafOffset = iOff; @@ -4961,11 +4962,11 @@ ** (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, 0, i)); if( pLeaf ){ if( !fts5LeafIsTermless(pLeaf) ) p->rc = FTS5_CORRUPT; - if( i>=iNoRowid && 0!=fts5GetU16(&pLeaf->p[0]) ) p->rc = FTS5_CORRUPT; + if( i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf) ) p->rc = FTS5_CORRUPT; } fts5DataRelease(pLeaf); if( p->rc ) break; } } @@ -5015,11 +5016,11 @@ int iRowidOff; /* Offset of first rowid on leaf */ int nTerm; /* Size of term on leaf in bytes */ int res; /* Comparison of term and split-key */ iOff = fts5LeafFirstTermOff(pLeaf); - iRowidOff = fts5GetU16(&pLeaf->p[0]); + iRowidOff = fts5LeafFirstRowidOff(pLeaf); if( iRowidOff>=iOff ){ p->rc = FTS5_CORRUPT; }else{ iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm); res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm)); @@ -5054,11 +5055,11 @@ /* Check any rowid-less pages that occur before the current leaf. */ for(iPg=iPrevLeaf+1; iPgp[0])!=0 ) p->rc = FTS5_CORRUPT; + if( fts5LeafFirstRowidOff(pLeaf)!=0 ) p->rc = FTS5_CORRUPT; fts5DataRelease(pLeaf); } } iPrevLeaf = fts5DlidxIterPgno(pDlidx); @@ -5066,11 +5067,11 @@ ** contain the rowid suggested by the same. */ iKey = FTS5_SEGMENT_ROWID(iSegid, 0, iPrevLeaf); pLeaf = fts5DataRead(p, iKey); if( pLeaf ){ i64 iRowid; - int iRowidOff = fts5GetU16(&pLeaf->p[0]); + int iRowidOff = fts5LeafFirstRowidOff(pLeaf); ASSERT_SZLEAF_OK(pLeaf); if( iRowidOff>=pLeaf->szLeaf ){ p->rc = FTS5_CORRUPT; }else{ fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);