88 lines
3.3 KiB
Diff
88 lines
3.3 KiB
Diff
From ec2409b34e42389034ecf6ae616a85de97c0fd8c Mon Sep 17 00:00:00 2001
|
|
From: Dan Kennedy <danielk1977@gmail.com>
|
|
Date: Tue, 22 Jan 2019 21:17:40 +0000
|
|
Subject: [PATCH 0820/1009] Fix a buffer overrun that could occur in fts5 if a
|
|
prefix query is made on a corrupt database.
|
|
|
|
https://github.com/mackyle/sqlite/commit/ec2409b34e42389034ecf6ae616a85de97c0fd8c
|
|
|
|
---
|
|
ext/fts5/fts5.h | 8 +-
|
|
ext/fts5/fts5Int.h | 2 +-
|
|
ext/fts5/fts5_index.c | 2 +-
|
|
ext/fts5/fts5_main.c | 5 +
|
|
ext/fts5/test/fts5corrupt3.test | 217 ++++++++++++++++++++++++++++++++++++++++
|
|
5 files changed, 226 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/ext/fts5/fts5.h b/ext/fts5/fts5.h
|
|
index 8273785..f0b7d55 100644
|
|
--- a/ext/fts5/fts5.h
|
|
+++ b/ext/fts5/fts5.h
|
|
@@ -120,12 +120,8 @@ struct Fts5PhraseIter {
|
|
**
|
|
** Usually, output parameter *piPhrase is set to the phrase number, *piCol
|
|
** to the column in which it occurs and *piOff the token offset of the
|
|
-** first token of the phrase. The exception is if the table was created
|
|
-** with the offsets=0 option specified. In this case *piOff is always
|
|
-** set to -1.
|
|
-**
|
|
-** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
|
|
-** if an error occurs.
|
|
+** first token of the phrase. Returns SQLITE_OK if successful, or an error
|
|
+** code (i.e. SQLITE_NOMEM) if an error occurs.
|
|
**
|
|
** This API can be quite slow if used with an FTS5 table created with the
|
|
** "detail=none" or "detail=column" option.
|
|
diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h
|
|
index 4855abe..629bcf0 100644
|
|
--- a/ext/fts5/fts5Int.h
|
|
+++ b/ext/fts5/fts5Int.h
|
|
@@ -274,7 +274,7 @@ void sqlite3Fts5Put32(u8*, int);
|
|
int sqlite3Fts5Get32(const u8*);
|
|
|
|
#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
|
|
-#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
|
|
+#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF)
|
|
|
|
typedef struct Fts5PoslistReader Fts5PoslistReader;
|
|
struct Fts5PoslistReader {
|
|
diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c
|
|
index 66ab9be..165d094 100644
|
|
--- a/ext/fts5/fts5_index.c
|
|
+++ b/ext/fts5/fts5_index.c
|
|
@@ -5122,7 +5122,7 @@ static void fts5SetupPrefixIter(
|
|
}
|
|
fts5MultiIterFree(p1);
|
|
|
|
- pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n);
|
|
+ pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING);
|
|
if( pData ){
|
|
pData->p = (u8*)&pData[1];
|
|
pData->nn = pData->szLeaf = doclist.n;
|
|
diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c
|
|
index bb34234..c98df4f 100644
|
|
--- a/ext/fts5/fts5_main.c
|
|
+++ b/ext/fts5/fts5_main.c
|
|
@@ -1777,6 +1777,7 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
|
|
int rc = SQLITE_OK;
|
|
Fts5PoslistReader *aIter; /* One iterator for each phrase */
|
|
int nIter; /* Number of iterators/phrases */
|
|
+ int nCol = ((Fts5Table*)pCsr->base.pVtab)->pConfig->nCol;
|
|
|
|
nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
|
|
if( pCsr->aInstIter==0 ){
|
|
@@ -1830,6 +1831,10 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
|
|
aInst[0] = iBest;
|
|
aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
|
|
aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
|
|
+ if( aInst[1]<0 || aInst[1]>=nCol ){
|
|
+ rc = FTS5_CORRUPT;
|
|
+ break;
|
|
+ }
|
|
sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
|
|
}
|
|
}
|
|
--
|
|
1.8.3.1
|
|
|