Index: ext/fts5/fts5_index.c ================================================================== --- ext/fts5/fts5_index.c +++ ext/fts5/fts5_index.c @@ -3398,10 +3398,16 @@ if( (ret + i) > nMax ) break; ret += i; } return ret; } + +#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) { \ + assert( pBuf->nSpace>=(pBuf->n+nBlob) ); \ + memcpy(&pBuf->p[pBuf->n], pBlob, nBlob); \ + pBuf->n += nBlob; \ +} /* ** Flush the contents of in-memory hash table iHash to a new level-0 ** segment on disk. Also update the corresponding structure record. ** @@ -3458,10 +3464,11 @@ if( (pBuf->n + nTerm + 2) > pgsz ){ fts5WriteFlushLeaf(p, &writer); pBuf = &writer.aWriter[0].buf; if( (nTerm + 32) > pBuf->nSpace ){ fts5BufferGrow(&p->rc, pBuf, nTerm + 32 - pBuf->n); + if( p->rc ) break; } } /* Write the term to the leaf. And push it up into the b-tree hierarchy */ if( writer.bFirstTermInPage==0 ){ @@ -3478,17 +3485,15 @@ assert( nPren += sqlite3PutVarint(&pBuf->p[pBuf->n], nSuffix); - fts5BufferAppendBlob(&p->rc, pBuf, - nSuffix, (const u8*)&zTerm[nTerm-nSuffix] - ); + fts5BufferSafeAppendBlob(pBuf, (const u8*)&zTerm[nTerm-nSuffix], nSuffix); if( pgsz>=(pBuf->n + nDoclist + 1) ){ /* The entire doclist will fit on the current leaf. */ - fts5BufferAppendBlob(&p->rc, pBuf, nDoclist, pDoclist); + fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); }else{ i64 iRowid = 0; i64 iDelta = 0; int iOff = 0; int bFirstDocid = 0; @@ -3514,11 +3519,11 @@ assert( pBuf->n<=pBuf->nSpace ); if( (pBuf->n + nCopy) <= pgsz ){ /* The entire poslist will fit on the current leaf. So copy ** it in one go. */ - fts5BufferAppendBlob(&p->rc, pBuf, nCopy, &pDoclist[iOff]); + fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy); }else{ /* The entire poslist will not fit on this leaf. So it needs ** to be broken into sections. The only qualification being ** that each varint must be stored contiguously. */ const u8 *pPoslist = &pDoclist[iOff]; @@ -3529,11 +3534,11 @@ if( (nCopy - iPos)<=nSpace ){ n = nCopy - iPos; }else{ n = fts5PoslistPrefix(&pPoslist[iPos], nSpace); } - fts5BufferAppendBlob(&p->rc, pBuf, n, &pPoslist[iPos]); + fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n); iPos += n; if( iPos>=nCopy ) break; fts5WriteFlushLeaf(p, &writer); pBuf = &writer.aWriter[0].buf; }