mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-27 20:41:58 +03:00
Fix a use-after-free error that could occur if an fts5 table is written while scanning it using an fts5vocab cursor.
FossilOrigin-Name: e751c2ec786b5c1a1c9640fdc3fde036879a2c32db2bd67fe7c72604780f67b8
This commit is contained in:
@ -837,6 +837,40 @@ int sqlite3Fts5StructureTest(Fts5Index *p, void *pStruct){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Ensure that structure object (*pp) is writable.
|
||||
**
|
||||
** This function is a no-op if (*pRc) is not SQLITE_OK when it is called. If
|
||||
** an error occurs, (*pRc) is set to an SQLite error code before returning.
|
||||
*/
|
||||
static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){
|
||||
Fts5Structure *p = *pp;
|
||||
if( *pRc==SQLITE_OK && p->nRef>1 ){
|
||||
int nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel);
|
||||
Fts5Structure *pNew;
|
||||
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte);
|
||||
if( pNew ){
|
||||
int i;
|
||||
memcpy(pNew, p, nByte);
|
||||
for(i=0; i<p->nLevel; i++) pNew->aLevel[i].aSeg = 0;
|
||||
for(i=0; i<p->nLevel; i++){
|
||||
Fts5StructureLevel *pLvl = &pNew->aLevel[i];
|
||||
int nByte = sizeof(Fts5StructureSegment) * pNew->aLevel[i].nSeg;
|
||||
pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(pRc, nByte);
|
||||
if( pLvl->aSeg==0 ){
|
||||
for(i=0; i<p->nLevel; i++){
|
||||
sqlite3_free(pNew->aLevel[i].aSeg);
|
||||
}
|
||||
sqlite3_free(pNew);
|
||||
return;
|
||||
}
|
||||
memcpy(pLvl->aSeg, p->aLevel[i].aSeg, nByte);
|
||||
}
|
||||
}
|
||||
*pp = pNew;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Deserialize and return the structure record currently stored in serialized
|
||||
** form within buffer pData/nData.
|
||||
@ -938,9 +972,11 @@ static int fts5StructureDecode(
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** Add a level to the Fts5Structure.aLevel[] array of structure object
|
||||
** (*ppStruct).
|
||||
*/
|
||||
static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
|
||||
fts5StructureMakeWritable(pRc, ppStruct);
|
||||
if( *pRc==SQLITE_OK ){
|
||||
Fts5Structure *pStruct = *ppStruct;
|
||||
int nLevel = pStruct->nLevel;
|
||||
|
Reference in New Issue
Block a user