import sqlite-3.26.0-10.el8
This commit is contained in:
parent
0033e729da
commit
be34a1dec9
|
@ -0,0 +1,149 @@
|
||||||
|
From 92b243715eea17997ed9707540757d0667ad9eb2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Thu, 2 Jan 2020 09:54:41 +0100
|
||||||
|
Subject: [PATCH] Improved detection of corrupt shadow tables in FTS3. Enable
|
||||||
|
the debugging special-inserts for FTS3 for both SQLITE_DEBUG and SQLITE_TEST.
|
||||||
|
|
||||||
|
Resolves: CVE-2019-13752
|
||||||
|
---
|
||||||
|
ext/fts3/fts3.c | 2 +-
|
||||||
|
ext/fts3/fts3Int.h | 2 +-
|
||||||
|
ext/fts3/fts3_write.c | 42 +++++++++++++++++++++++++++---------------
|
||||||
|
3 files changed, 29 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c
|
||||||
|
index f6fb931..6d6bd46 100644
|
||||||
|
--- a/ext/fts3/fts3.c
|
||||||
|
+++ b/ext/fts3/fts3.c
|
||||||
|
@@ -4304,7 +4304,7 @@ static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){
|
||||||
|
int bIncrOk = (bOptOk
|
||||||
|
&& pCsr->bDesc==pTab->bDescIdx
|
||||||
|
&& p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0
|
||||||
|
-#ifdef SQLITE_TEST
|
||||||
|
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||||
|
&& pTab->bNoIncrDoclist==0
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h
|
||||||
|
index 077bad7..6f5a7a0 100644
|
||||||
|
--- a/ext/fts3/fts3Int.h
|
||||||
|
+++ b/ext/fts3/fts3Int.h
|
||||||
|
@@ -283,7 +283,7 @@ struct Fts3Table {
|
||||||
|
int mxSavepoint; /* Largest valid xSavepoint integer */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#ifdef SQLITE_TEST
|
||||||
|
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||||
|
/* True to disable the incremental doclist optimization. This is controled
|
||||||
|
** by special insert command 'test-no-incr-doclist'. */
|
||||||
|
int bNoIncrDoclist;
|
||||||
|
diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c
|
||||||
|
index 8fc6589..ee668aa 100644
|
||||||
|
--- a/ext/fts3/fts3_write.c
|
||||||
|
+++ b/ext/fts3/fts3_write.c
|
||||||
|
@@ -23,7 +23,7 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
-
|
||||||
|
+#include <stdio.h>
|
||||||
|
|
||||||
|
#define FTS_MAX_APPENDABLE_HEIGHT 16
|
||||||
|
|
||||||
|
@@ -2021,6 +2021,11 @@ static int fts3NodeAddTerm(
|
||||||
|
nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm);
|
||||||
|
nSuffix = nTerm-nPrefix;
|
||||||
|
|
||||||
|
+ /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of
|
||||||
|
+ ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when
|
||||||
|
+ ** compared with BINARY collation. This indicates corruption. */
|
||||||
|
+ if( nSuffix<=0 ) return FTS_CORRUPT_VTAB;
|
||||||
|
+
|
||||||
|
nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix;
|
||||||
|
if( nReq<=p->nNodeSize || !pTree->zTerm ){
|
||||||
|
|
||||||
|
@@ -2309,9 +2314,11 @@ static int fts3SegWriterAdd(
|
||||||
|
/* Append the prefix-compressed term and doclist to the buffer. */
|
||||||
|
nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix);
|
||||||
|
nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix);
|
||||||
|
+ assert( nSuffix>0 );
|
||||||
|
memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix);
|
||||||
|
nData += nSuffix;
|
||||||
|
nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist);
|
||||||
|
+ assert( nDoclist>0 );
|
||||||
|
memcpy(&pWriter->aData[nData], aDoclist, nDoclist);
|
||||||
|
pWriter->nData = nData + nDoclist;
|
||||||
|
|
||||||
|
@@ -2331,6 +2338,7 @@ static int fts3SegWriterAdd(
|
||||||
|
pWriter->zTerm = zNew;
|
||||||
|
}
|
||||||
|
assert( pWriter->zTerm==pWriter->zMalloc );
|
||||||
|
+ assert( nTerm>0 );
|
||||||
|
memcpy(pWriter->zTerm, zTerm, nTerm);
|
||||||
|
}else{
|
||||||
|
pWriter->zTerm = (char *)zTerm;
|
||||||
|
@@ -2639,6 +2647,7 @@ static int fts3MsrBufferData(
|
||||||
|
pMsr->aBuffer = pNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ assert( nList>0 );
|
||||||
|
memcpy(pMsr->aBuffer, pList, nList);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
@@ -3821,6 +3830,7 @@ static int fts3IncrmergePush(
|
||||||
|
** be added to. */
|
||||||
|
nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm);
|
||||||
|
nSuffix = nTerm - nPrefix;
|
||||||
|
+ if( NEVER(nSuffix<=0) ) return FTS_CORRUPT_VTAB;
|
||||||
|
nSpace = sqlite3Fts3VarintLen(nPrefix);
|
||||||
|
nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
|
||||||
|
|
||||||
|
@@ -5300,7 +5310,7 @@ static int fts3DoIntegrityCheck(
|
||||||
|
** meaningful value to insert is the text 'optimize'.
|
||||||
|
*/
|
||||||
|
static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
|
||||||
|
- int rc; /* Return Code */
|
||||||
|
+ int rc = SQLITE_ERROR; /* Return Code */
|
||||||
|
const char *zVal = (const char *)sqlite3_value_text(pVal);
|
||||||
|
int nVal = sqlite3_value_bytes(pVal);
|
||||||
|
|
||||||
|
@@ -5316,21 +5326,23 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
|
||||||
|
rc = fts3DoIncrmerge(p, &zVal[6]);
|
||||||
|
}else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){
|
||||||
|
rc = fts3DoAutoincrmerge(p, &zVal[10]);
|
||||||
|
-#ifdef SQLITE_TEST
|
||||||
|
- }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
|
||||||
|
- p->nNodeSize = atoi(&zVal[9]);
|
||||||
|
- rc = SQLITE_OK;
|
||||||
|
- }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
|
||||||
|
- p->nMaxPendingData = atoi(&zVal[11]);
|
||||||
|
- rc = SQLITE_OK;
|
||||||
|
- }else if( nVal>21 && 0==sqlite3_strnicmp(zVal, "test-no-incr-doclist=", 21) ){
|
||||||
|
- p->bNoIncrDoclist = atoi(&zVal[21]);
|
||||||
|
- rc = SQLITE_OK;
|
||||||
|
-#endif
|
||||||
|
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||||
|
}else{
|
||||||
|
- rc = SQLITE_ERROR;
|
||||||
|
+ int v;
|
||||||
|
+ if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
|
||||||
|
+ v = atoi(&zVal[9]);
|
||||||
|
+ if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v;
|
||||||
|
+ rc = SQLITE_OK;
|
||||||
|
+ }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
|
||||||
|
+ v = atoi(&zVal[11]);
|
||||||
|
+ if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v;
|
||||||
|
+ rc = SQLITE_OK;
|
||||||
|
+ }else if( nVal>21 && 0==sqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){
|
||||||
|
+ p->bNoIncrDoclist = atoi(&zVal[21]);
|
||||||
|
+ rc = SQLITE_OK;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
-
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
From 0b3ba64a9c7f785f6b3f1c1c15c5b0f1e41e0461 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Thu, 2 Jan 2020 10:25:58 +0100
|
||||||
|
Subject: [PATCH] Remove a reachable NEVER() in FTS3.
|
||||||
|
|
||||||
|
---
|
||||||
|
ext/fts3/fts3_write.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c
|
||||||
|
index ee668aa..8624329 100644
|
||||||
|
--- a/ext/fts3/fts3_write.c
|
||||||
|
+++ b/ext/fts3/fts3_write.c
|
||||||
|
@@ -3830,7 +3830,7 @@ static int fts3IncrmergePush(
|
||||||
|
** be added to. */
|
||||||
|
nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm);
|
||||||
|
nSuffix = nTerm - nPrefix;
|
||||||
|
- if( NEVER(nSuffix<=0) ) return FTS_CORRUPT_VTAB;
|
||||||
|
+ if(nSuffix<=0 ) return FTS_CORRUPT_VTAB;
|
||||||
|
nSpace = sqlite3Fts3VarintLen(nPrefix);
|
||||||
|
nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
From 5f4ce30babee8085fc36680c6103d9a06be49ef7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Thu, 2 Jan 2020 11:58:39 +0100
|
||||||
|
Subject: [PATCH] More improvements to shadow table corruption detection in
|
||||||
|
FTS3.
|
||||||
|
|
||||||
|
---
|
||||||
|
ext/fts3/fts3.c | 4 ++++
|
||||||
|
ext/fts3/fts3Int.h | 10 ++++++++++
|
||||||
|
ext/fts3/fts3_write.c | 14 +++++++++++---
|
||||||
|
3 files changed, 25 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c
|
||||||
|
index 6d6bd46..84fc8a5 100644
|
||||||
|
--- a/ext/fts3/fts3.c
|
||||||
|
+++ b/ext/fts3/fts3.c
|
||||||
|
@@ -1460,6 +1460,10 @@ static int fts3InitVtab(
|
||||||
|
fts3DatabasePageSize(&rc, p);
|
||||||
|
p->nNodeSize = p->nPgsz-35;
|
||||||
|
|
||||||
|
+#if defined(SQLITE_DEBUG)||defined(SQLITE_TEST)
|
||||||
|
+ p->nMergeCount = FTS3_MERGE_COUNT;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Declare the table schema to SQLite. */
|
||||||
|
fts3DeclareVtab(&rc, p);
|
||||||
|
|
||||||
|
diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h
|
||||||
|
index 6f5a7a0..0d1b491 100644
|
||||||
|
--- a/ext/fts3/fts3Int.h
|
||||||
|
+++ b/ext/fts3/fts3Int.h
|
||||||
|
@@ -287,9 +287,19 @@ struct Fts3Table {
|
||||||
|
/* True to disable the incremental doclist optimization. This is controled
|
||||||
|
** by special insert command 'test-no-incr-doclist'. */
|
||||||
|
int bNoIncrDoclist;
|
||||||
|
+
|
||||||
|
+ /* Number of segments in a level */
|
||||||
|
+ int nMergeCount;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* Macro to find the number of segments to merge */
|
||||||
|
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||||
|
+# define MergeCount(P) ((P)->nMergeCount)
|
||||||
|
+#else
|
||||||
|
+# define MergeCount(P) FTS3_MERGE_COUNT
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
** When the core wants to read from the virtual table, it creates a
|
||||||
|
** virtual table cursor (an instance of the following structure) using
|
||||||
|
diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c
|
||||||
|
index 8624329..d57d265 100644
|
||||||
|
--- a/ext/fts3/fts3_write.c
|
||||||
|
+++ b/ext/fts3/fts3_write.c
|
||||||
|
@@ -1152,7 +1152,7 @@ static int fts3AllocateSegdirIdx(
|
||||||
|
** segment and allocate (newly freed) index 0 at level iLevel. Otherwise,
|
||||||
|
** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext.
|
||||||
|
*/
|
||||||
|
- if( iNext>=FTS3_MERGE_COUNT ){
|
||||||
|
+ if( iNext>=MergeCount(p) ){
|
||||||
|
fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel));
|
||||||
|
rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel);
|
||||||
|
*piIdx = 0;
|
||||||
|
@@ -4259,6 +4259,10 @@ static int fts3IncrmergeLoad(
|
||||||
|
int i;
|
||||||
|
int nHeight = (int)aRoot[0];
|
||||||
|
NodeWriter *pNode;
|
||||||
|
+ if( nHeight<1 || nHeight>FTS_MAX_APPENDABLE_HEIGHT ){
|
||||||
|
+ sqlite3_reset(pSelect);
|
||||||
|
+ return FTS_CORRUPT_VTAB;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT;
|
||||||
|
pWriter->iStart = iStart;
|
||||||
|
@@ -5007,7 +5011,7 @@ static int fts3DoIncrmerge(
|
||||||
|
const char *zParam /* Nul-terminated string containing "A,B" */
|
||||||
|
){
|
||||||
|
int rc;
|
||||||
|
- int nMin = (FTS3_MERGE_COUNT / 2);
|
||||||
|
+ int nMin = (MergeCount(p) / 2);
|
||||||
|
int nMerge = 0;
|
||||||
|
const char *z = zParam;
|
||||||
|
|
||||||
|
@@ -5052,7 +5056,7 @@ static int fts3DoAutoincrmerge(
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
sqlite3_stmt *pStmt = 0;
|
||||||
|
p->nAutoincrmerge = fts3Getint(&zParam);
|
||||||
|
- if( p->nAutoincrmerge==1 || p->nAutoincrmerge>FTS3_MERGE_COUNT ){
|
||||||
|
+ if( p->nAutoincrmerge==1 || p->nAutoincrmerge>MergeCount(p) ){
|
||||||
|
p->nAutoincrmerge = 8;
|
||||||
|
}
|
||||||
|
if( !p->bHasStat ){
|
||||||
|
@@ -5340,6 +5344,10 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
|
||||||
|
}else if( nVal>21 && 0==sqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){
|
||||||
|
p->bNoIncrDoclist = atoi(&zVal[21]);
|
||||||
|
rc = SQLITE_OK;
|
||||||
|
+ }else if( nVal>11 && 0==sqlite3_strnicmp(zVal,"mergecount=",11) ){
|
||||||
|
+ v = atoi(&zVal[11]);
|
||||||
|
+ if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v;
|
||||||
|
+ rc = SQLITE_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
From ab17169870e985b062e520ecf95e6c79ad784f38 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Thu, 23 Apr 2020 11:25:13 +0200
|
||||||
|
Subject: [PATCH] fixed CVE-2019-16168 (rhbz#1826897)
|
||||||
|
|
||||||
|
---
|
||||||
|
src/analyze.c | 4 +++-
|
||||||
|
src/where.c | 1 +
|
||||||
|
test/analyzeC.test | 13 +++++++++++++
|
||||||
|
3 files changed, 17 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/analyze.c b/src/analyze.c
|
||||||
|
index 5075b57..e47c0f5 100644
|
||||||
|
--- a/src/analyze.c
|
||||||
|
+++ b/src/analyze.c
|
||||||
|
@@ -1497,7 +1497,9 @@ static void decodeIntArray(
|
||||||
|
if( sqlite3_strglob("unordered*", z)==0 ){
|
||||||
|
pIndex->bUnordered = 1;
|
||||||
|
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
|
||||||
|
- pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
|
||||||
|
+ int sz = sqlite3Atoi(z+3);
|
||||||
|
+ if( sz<2 ) sz = 2;
|
||||||
|
+ pIndex->szIdxRow = sqlite3LogEst(sz);
|
||||||
|
}else if( sqlite3_strglob("noskipscan*", z)==0 ){
|
||||||
|
pIndex->noSkipScan = 1;
|
||||||
|
}
|
||||||
|
diff --git a/src/where.c b/src/where.c
|
||||||
|
index 8e01660..1a4fa51 100644
|
||||||
|
--- a/src/where.c
|
||||||
|
+++ b/src/where.c
|
||||||
|
@@ -2655,6 +2655,7 @@ static int whereLoopAddBtreeIndex(
|
||||||
|
** it to pNew->rRun, which is currently set to the cost of the index
|
||||||
|
** seek only. Then, if this is a non-covering index, add the cost of
|
||||||
|
** visiting the rows in the main table. */
|
||||||
|
+ assert( pSrc->pTab->szTabRow>0 );
|
||||||
|
rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
|
||||||
|
pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
|
||||||
|
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
|
||||||
|
diff --git a/test/analyzeC.test b/test/analyzeC.test
|
||||||
|
index 02faa9c..3595c9d 100644
|
||||||
|
--- a/test/analyzeC.test
|
||||||
|
+++ b/test/analyzeC.test
|
||||||
|
@@ -132,6 +132,19 @@ do_execsql_test 4.3 {
|
||||||
|
SELECT count(a) FROM t1;
|
||||||
|
} {/.*INDEX t1ca.*/}
|
||||||
|
|
||||||
|
+# 2019-08-15.
|
||||||
|
+# Ticket https://www.sqlite.org/src/tktview/e4598ecbdd18bd82945f602901
|
||||||
|
+# The sz=N parameter in the sqlite_stat1 table needs to have a value of
|
||||||
|
+# 2 or more to avoid a division by zero in the query planner.
|
||||||
|
+#
|
||||||
|
+do_execsql_test 4.4 {
|
||||||
|
+ DROP TABLE IF EXISTS t44;
|
||||||
|
+ CREATE TABLE t44(a PRIMARY KEY);
|
||||||
|
+ INSERT INTO sqlite_stat1 VALUES('t44',null,'sz=0');
|
||||||
|
+ ANALYZE sqlite_master;
|
||||||
|
+ SELECT 0 FROM t44 WHERE a IN(1,2,3);
|
||||||
|
+} {}
|
||||||
|
+
|
||||||
|
|
||||||
|
# The sz=NNN parameter works even if there is other extraneous text
|
||||||
|
# in the sqlite_stat1.stat column.
|
||||||
|
--
|
||||||
|
2.24.1
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
From 7d47517d579601bb6e59e33bf0896f0ed36aa0aa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Mon, 20 Jan 2020 09:34:41 +0100
|
||||||
|
Subject: [PATCH] Continue to back away from the LEFT JOIN optimization of
|
||||||
|
check-in
|
||||||
|
|
||||||
|
by disallowing query flattening if the outer query is DISTINCT. Without this fix,
|
||||||
|
if an index scan is run on the table within the view on the right-hand side of the
|
||||||
|
LEFT JOIN, stale result registers might be accessed yielding incorrect results,
|
||||||
|
and/or an OP_IfNullRow opcode might be invoked on the un-opened table, resulting
|
||||||
|
in a NULL-pointer dereference. This problem was found by the Yongheng and Rui fuzzer.
|
||||||
|
---
|
||||||
|
src/select.c | 8 ++++++--
|
||||||
|
test/join.test | 13 +++++++++++++
|
||||||
|
2 files changed, 19 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/select.c b/src/select.c
|
||||||
|
index c60ff27..0205a08 100644
|
||||||
|
--- a/src/select.c
|
||||||
|
+++ b/src/select.c
|
||||||
|
@@ -3569,6 +3569,7 @@ static void substSelect(
|
||||||
|
** (3b) the FROM clause of the subquery may not contain a virtual
|
||||||
|
** table and
|
||||||
|
** (3c) the outer query may not be an aggregate.
|
||||||
|
+** (3d) the outer query may not be DISTINCT.
|
||||||
|
**
|
||||||
|
** (4) The subquery can not be DISTINCT.
|
||||||
|
**
|
||||||
|
@@ -3765,8 +3766,11 @@ static int flattenSubquery(
|
||||||
|
*/
|
||||||
|
if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
|
||||||
|
isLeftJoin = 1;
|
||||||
|
- if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){
|
||||||
|
- /* (3a) (3c) (3b) */
|
||||||
|
+ if( pSubSrc->nSrc>1 /* (3a) */
|
||||||
|
+ || isAgg /* (3b) */
|
||||||
|
+ || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */
|
||||||
|
+ || (p->selFlags & SF_Distinct)!=0 /* (3d) */
|
||||||
|
+ ){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/test/join.test b/test/join.test
|
||||||
|
index 8c6f463..8c6a53d 100644
|
||||||
|
--- a/test/join.test
|
||||||
|
+++ b/test/join.test
|
||||||
|
@@ -844,4 +844,17 @@ do_execsql_test join-15.110 {
|
||||||
|
ORDER BY a1, a2, a3, a4, a5;
|
||||||
|
} {1 {} {} {} {} 1 11 {} {} {} 1 12 {} {} {} 1 12 121 {} {} 1 13 {} {} {}}
|
||||||
|
|
||||||
|
+# 2019-12-18 problem with a LEFT JOIN where the RHS is a view.
|
||||||
|
+# Detected by Yongheng and Rui.
|
||||||
|
+# Follows from the optimization attempt of check-in 41c27bc0ff1d3135
|
||||||
|
+# on 2017-04-18
|
||||||
|
+#
|
||||||
|
+reset_db
|
||||||
|
+do_execsql_test join-22.10 {
|
||||||
|
+ CREATE TABLE t0(a, b);
|
||||||
|
+ CREATE INDEX t0a ON t0(a);
|
||||||
|
+ INSERT INTO t0 VALUES(10,10),(10,11),(10,12);
|
||||||
|
+ SELECT DISTINCT c FROM t0 LEFT JOIN (SELECT a+1 AS c FROM t0) ORDER BY c ;
|
||||||
|
+} {11}
|
||||||
|
+
|
||||||
|
finish_test
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
From 6b06304c2a46e17a6dc4402eadc75ccac24da893 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Fri, 17 Jan 2020 13:03:54 +0100
|
||||||
|
Subject: [PATCH] When an error occurs while rewriting the parser tree for
|
||||||
|
window functions in the sqlite3WindowRewrite() routine, make sure that
|
||||||
|
pParse->nErr is set, and make sure that this shuts down any subsequent code
|
||||||
|
generation that might depend on the transformations that were implemented.
|
||||||
|
This fixes a problem discovered by the Yongheng and Rui fuzzer.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/expr.c | 1 +
|
||||||
|
src/vdbeaux.c | 3 ++-
|
||||||
|
src/window.c | 5 +++++
|
||||||
|
3 files changed, 8 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/expr.c b/src/expr.c
|
||||||
|
index d4eb9de..b081ca2 100644
|
||||||
|
--- a/src/expr.c
|
||||||
|
+++ b/src/expr.c
|
||||||
|
@@ -344,6 +344,7 @@ static int codeCompare(
|
||||||
|
int addr;
|
||||||
|
CollSeq *p4;
|
||||||
|
|
||||||
|
+ if( pParse->nErr ) return 0;
|
||||||
|
p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
|
||||||
|
p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
|
||||||
|
addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
|
||||||
|
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
|
||||||
|
index f1496a3..b74141b 100644
|
||||||
|
--- a/src/vdbeaux.c
|
||||||
|
+++ b/src/vdbeaux.c
|
||||||
|
@@ -1160,7 +1160,8 @@ void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
|
||||||
|
*/
|
||||||
|
static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
|
||||||
|
assert( p->nOp>0 || p->aOp==0 );
|
||||||
|
- assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
|
||||||
|
+ assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed
|
||||||
|
+ || p->pParse->nErr>0 );
|
||||||
|
if( p->nOp ){
|
||||||
|
assert( p->aOp );
|
||||||
|
sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
|
||||||
|
diff --git a/src/window.c b/src/window.c
|
||||||
|
index f5deae9..56c0145 100644
|
||||||
|
--- a/src/window.c
|
||||||
|
+++ b/src/window.c
|
||||||
|
@@ -843,6 +843,11 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||||
|
if( db->mallocFailed ) rc = SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if( rc && pParse->nErr==0 ){
|
||||||
|
+ assert( pParse->db->mallocFailed );
|
||||||
|
+ return SQLITE_NOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
From 1986c6384122947b10804cbc5c4d7af85e097404 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Mon, 20 Jan 2020 10:09:55 +0100
|
||||||
|
Subject: [PATCH] Fix the zipfile extension so that INSERT works even if the
|
||||||
|
pathname of
|
||||||
|
|
||||||
|
the file being inserted is a NULL. Bug discovered by the
|
||||||
|
Yongheng and Rui fuzzer.
|
||||||
|
---
|
||||||
|
ext/misc/zipfile.c | 1 +
|
||||||
|
test/zipfile.test | 13 +++++++++++++
|
||||||
|
2 files changed, 14 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c
|
||||||
|
index e57dc38..6f48d0f 100644
|
||||||
|
--- a/ext/misc/zipfile.c
|
||||||
|
+++ b/ext/misc/zipfile.c
|
||||||
|
@@ -1618,6 +1618,7 @@ static int zipfileUpdate(
|
||||||
|
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
zPath = (const char*)sqlite3_value_text(apVal[2]);
|
||||||
|
+ if( zPath==0 ) zPath = "";
|
||||||
|
nPath = (int)strlen(zPath);
|
||||||
|
mTime = zipfileGetTime(apVal[4]);
|
||||||
|
}
|
||||||
|
diff --git a/test/zipfile.test b/test/zipfile.test
|
||||||
|
index 2bab066..5bca10b 100644
|
||||||
|
--- a/test/zipfile.test
|
||||||
|
+++ b/test/zipfile.test
|
||||||
|
@@ -795,4 +795,17 @@ if {$tcl_platform(platform)!="windows"} {
|
||||||
|
} {. ./x1.txt ./x2.txt}
|
||||||
|
}
|
||||||
|
|
||||||
|
+# 2019-12-18 Yongheng and Rui fuzzer
|
||||||
|
+#
|
||||||
|
+do_execsql_test 13.10 {
|
||||||
|
+ DROP TABLE IF EXISTS t0;
|
||||||
|
+ DROP TABLE IF EXISTS t1;
|
||||||
|
+ CREATE TABLE t0(a,b,c,d,e,f,g);
|
||||||
|
+ REPLACE INTO t0(c,b,f) VALUES(10,10,10);
|
||||||
|
+ CREATE VIRTUAL TABLE t1 USING zipfile('h.zip');
|
||||||
|
+ REPLACE INTO t1 SELECT * FROM t0;
|
||||||
|
+ SELECT quote(name),quote(mode),quote(mtime),quote(sz),quote(rawdata),
|
||||||
|
+ quote(data),quote(method) FROM t1;
|
||||||
|
+} {'' 10 10 2 X'3130' X'3130' 0}
|
||||||
|
+
|
||||||
|
finish_test
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
From 16c5290d72cb8059e9dfe545613183b850fc44e4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Mon, 20 Jan 2020 10:26:35 +0100
|
||||||
|
Subject: [PATCH] Fix the zipfile() function in the zipfile extension so that
|
||||||
|
it is able to
|
||||||
|
|
||||||
|
deal with goofy filenames that contain embedded zeros.
|
||||||
|
---
|
||||||
|
ext/misc/zipfile.c | 4 ++--
|
||||||
|
test/zipfile.test | 13 +++++++++++++
|
||||||
|
2 files changed, 15 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c
|
||||||
|
index 6f48d0f..e6141ef 100644
|
||||||
|
--- a/ext/misc/zipfile.c
|
||||||
|
+++ b/ext/misc/zipfile.c
|
||||||
|
@@ -1632,7 +1632,7 @@ static int zipfileUpdate(
|
||||||
|
zFree = sqlite3_mprintf("%s/", zPath);
|
||||||
|
if( zFree==0 ){ rc = SQLITE_NOMEM; }
|
||||||
|
zPath = (const char*)zFree;
|
||||||
|
- nPath++;
|
||||||
|
+ nPath = (int)strlen(zPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2033,11 +2033,11 @@ void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
|
||||||
|
}else{
|
||||||
|
if( zName[nName-1]!='/' ){
|
||||||
|
zName = zFree = sqlite3_mprintf("%s/", zName);
|
||||||
|
- nName++;
|
||||||
|
if( zName==0 ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
goto zipfile_step_out;
|
||||||
|
}
|
||||||
|
+ nName = (int)strlen(zName);
|
||||||
|
}else{
|
||||||
|
while( nName>1 && zName[nName-2]=='/' ) nName--;
|
||||||
|
}
|
||||||
|
diff --git a/test/zipfile.test b/test/zipfile.test
|
||||||
|
index 5bca10b..e4b8088 100644
|
||||||
|
--- a/test/zipfile.test
|
||||||
|
+++ b/test/zipfile.test
|
||||||
|
@@ -808,4 +808,17 @@ do_execsql_test 13.10 {
|
||||||
|
quote(data),quote(method) FROM t1;
|
||||||
|
} {'' 10 10 2 X'3130' X'3130' 0}
|
||||||
|
|
||||||
|
+# 2019-12-23 Yongheng and Rui fuzzer
|
||||||
|
+# Run using valgrind to see the problem.
|
||||||
|
+#
|
||||||
|
+do_execsql_test 14.10 {
|
||||||
|
+ DROP TABLE t1;
|
||||||
|
+ CREATE TABLE t1(x char);
|
||||||
|
+ INSERT INTO t1(x) VALUES('1');
|
||||||
|
+ INSERT INTO t1(x) SELECT zipfile(x, 'xyz') FROM t1;
|
||||||
|
+ INSERT INTO t1(x) SELECT zipfile(x, 'uvw') FROM t1;
|
||||||
|
+ SELECT count(*) FROM t1;
|
||||||
|
+ PRAGMA integrity_check;
|
||||||
|
+} {3 ok}
|
||||||
|
+
|
||||||
|
finish_test
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
From 8fd3688e01f5839120d7477ca94e013f5809edcf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Tue, 24 Mar 2020 11:33:04 +0100
|
||||||
|
Subject: [PATCH] Do not attempt to unwind the WITH stack in the Parse object
|
||||||
|
following an error.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/select.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/select.c b/src/select.c
|
||||||
|
index 0205a08..bbd13a4 100644
|
||||||
|
--- a/src/select.c
|
||||||
|
+++ b/src/select.c
|
||||||
|
@@ -4910,7 +4910,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||||
|
|
||||||
|
/* Process NATURAL keywords, and ON and USING clauses of joins.
|
||||||
|
*/
|
||||||
|
- if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){
|
||||||
|
+ if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){
|
||||||
|
return WRC_Abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.24.1
|
||||||
|
|
|
@ -0,0 +1,281 @@
|
||||||
|
Subject: [PATCH] Prevent aliases of window functions expressions from being
|
||||||
|
used as arguments to aggregate or other window functions.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/resolve.c | 21 ++++++---
|
||||||
|
src/sqliteInt.h | 2 +
|
||||||
|
test/windowerr.tcl | 59 ++++++++++++++++++++++++++
|
||||||
|
test/windowerr.test | 99 ++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 176 insertions(+), 5 deletions(-)
|
||||||
|
create mode 100644 test/windowerr.tcl
|
||||||
|
create mode 100644 test/windowerr.test
|
||||||
|
|
||||||
|
diff --git a/src/resolve.c b/src/resolve.c
|
||||||
|
index 0c7dfc0..cdcf4d9 100644
|
||||||
|
--- a/src/resolve.c
|
||||||
|
+++ b/src/resolve.c
|
||||||
|
@@ -436,6 +436,10 @@ static int lookupName(
|
||||||
|
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
|
||||||
|
return WRC_Abort;
|
||||||
|
}
|
||||||
|
+ if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){
|
||||||
|
+ sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs);
|
||||||
|
+ return WRC_Abort;
|
||||||
|
+ }
|
||||||
|
if( sqlite3ExprVectorSize(pOrig)!=1 ){
|
||||||
|
sqlite3ErrorMsg(pParse, "row value misused");
|
||||||
|
return WRC_Abort;
|
||||||
|
@@ -707,6 +711,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||||
|
const char *zId; /* The function name. */
|
||||||
|
FuncDef *pDef; /* Information about the function */
|
||||||
|
u8 enc = ENC(pParse->db); /* The database encoding */
|
||||||
|
+ int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
|
||||||
|
|
||||||
|
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||||
|
zId = pExpr->u.zToken;
|
||||||
|
@@ -828,8 +833,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||||
|
pNC->nErr++;
|
||||||
|
}
|
||||||
|
if( is_agg ){
|
||||||
|
+ /* Window functions may not be arguments of aggregate functions.
|
||||||
|
+ ** Or arguments of other window functions. But aggregate functions
|
||||||
|
+ ** may be arguments for window functions. */
|
||||||
|
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||||
|
- pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
|
||||||
|
+ pNC->ncFlags &= ~(NC_AllowWin | (!pExpr->y.pWin ? NC_AllowAgg : 0));
|
||||||
|
#else
|
||||||
|
pNC->ncFlags &= ~NC_AllowAgg;
|
||||||
|
#endif
|
||||||
|
@@ -850,7 +858,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||||
|
pExpr->y.pWin->pNextWin = pSel->pWin;
|
||||||
|
pSel->pWin = pExpr->y.pWin;
|
||||||
|
}
|
||||||
|
- pNC->ncFlags |= NC_AllowWin;
|
||||||
|
+ pNC->ncFlags |= NC_HasWin;
|
||||||
|
}else
|
||||||
|
#endif /* SQLITE_OMIT_WINDOWFUNC */
|
||||||
|
{
|
||||||
|
@@ -868,8 +876,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||||
|
pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
|
||||||
|
|
||||||
|
}
|
||||||
|
- pNC->ncFlags |= NC_AllowAgg;
|
||||||
|
}
|
||||||
|
+ pNC->ncFlags |= savedAllowFlags;
|
||||||
|
}
|
||||||
|
/* FIX ME: Compute pExpr->affinity based on the expected return
|
||||||
|
** type of the function
|
||||||
|
@@ -1573,8 +1581,8 @@ int sqlite3ResolveExprNames(
|
||||||
|
Walker w;
|
||||||
|
|
||||||
|
if( pExpr==0 ) return SQLITE_OK;
|
||||||
|
- savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg);
|
||||||
|
- pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg);
|
||||||
|
+ savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
|
||||||
|
+ pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
|
||||||
|
w.pParse = pNC->pParse;
|
||||||
|
w.xExprCallback = resolveExprStep;
|
||||||
|
w.xSelectCallback = resolveSelectStep;
|
||||||
|
@@ -1593,6 +1601,9 @@ int sqlite3ResolveExprNames(
|
||||||
|
if( pNC->ncFlags & NC_HasAgg ){
|
||||||
|
ExprSetProperty(pExpr, EP_Agg);
|
||||||
|
}
|
||||||
|
+ if( pNC->ncFlags & NC_HasWin ){
|
||||||
|
+ ExprSetProperty(pExpr, EP_Win);
|
||||||
|
+ }
|
||||||
|
pNC->ncFlags |= savedHasAgg;
|
||||||
|
return pNC->nErr>0 || w.pParse->nErr>0;
|
||||||
|
}
|
||||||
|
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
|
||||||
|
index 5f5f3cc..b7d3571 100644
|
||||||
|
--- a/src/sqliteInt.h
|
||||||
|
+++ b/src/sqliteInt.h
|
||||||
|
@@ -2517,6 +2517,7 @@ struct Expr {
|
||||||
|
#define EP_Alias 0x400000 /* Is an alias for a result set column */
|
||||||
|
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
|
||||||
|
#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
|
||||||
|
+#define EP_Win 0x8000000 /* Contains window functions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The EP_Propagate mask is a set of properties that automatically propagate
|
||||||
|
@@ -2773,6 +2774,7 @@ struct NameContext {
|
||||||
|
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
|
||||||
|
#define NC_Complex 0x2000 /* True if a function or subquery seen */
|
||||||
|
#define NC_AllowWin 0x4000 /* Window functions are allowed here */
|
||||||
|
+#define NC_HasWin 0x8000 /* One or more window functions seen */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** An instance of the following object describes a single ON CONFLICT
|
||||||
|
diff --git a/test/windowerr.tcl b/test/windowerr.tcl
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..80f464d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/windowerr.tcl
|
||||||
|
@@ -0,0 +1,59 @@
|
||||||
|
+# 2018 May 19
|
||||||
|
+#
|
||||||
|
+# The author disclaims copyright to this source code. In place of
|
||||||
|
+# a legal notice, here is a blessing:
|
||||||
|
+#
|
||||||
|
+# May you do good and not evil.
|
||||||
|
+# May you find forgiveness for yourself and forgive others.
|
||||||
|
+# May you share freely, never taking more than you give.
|
||||||
|
+#
|
||||||
|
+#***********************************************************************
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+source [file join [file dirname $argv0] pg_common.tcl]
|
||||||
|
+
|
||||||
|
+#=========================================================================
|
||||||
|
+
|
||||||
|
+start_test windowerr "2019 March 01"
|
||||||
|
+ifcapable !windowfunc
|
||||||
|
+
|
||||||
|
+execsql_test 1.0 {
|
||||||
|
+ DROP TABLE IF EXISTS t1;
|
||||||
|
+ CREATE TABLE t1(a INTEGER, b INTEGER);
|
||||||
|
+ INSERT INTO t1 VALUES(1, 1);
|
||||||
|
+ INSERT INTO t1 VALUES(2, 2);
|
||||||
|
+ INSERT INTO t1 VALUES(3, 3);
|
||||||
|
+ INSERT INTO t1 VALUES(4, 4);
|
||||||
|
+ INSERT INTO t1 VALUES(5, 5);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+foreach {tn frame} {
|
||||||
|
+ 1 "ORDER BY a ROWS BETWEEN -1 PRECEDING AND 1 FOLLOWING"
|
||||||
|
+ 2 "ORDER BY a ROWS BETWEEN 1 PRECEDING AND -1 FOLLOWING"
|
||||||
|
+
|
||||||
|
+ 3 "ORDER BY a RANGE BETWEEN -1 PRECEDING AND 1 FOLLOWING"
|
||||||
|
+ 4 "ORDER BY a RANGE BETWEEN 1 PRECEDING AND -1 FOLLOWING"
|
||||||
|
+
|
||||||
|
+ 5 "ORDER BY a GROUPS BETWEEN -1 PRECEDING AND 1 FOLLOWING"
|
||||||
|
+ 6 "ORDER BY a GROUPS BETWEEN 1 PRECEDING AND -1 FOLLOWING"
|
||||||
|
+
|
||||||
|
+ 7 "ORDER BY a,b RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING"
|
||||||
|
+
|
||||||
|
+ 8 "PARTITION BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING"
|
||||||
|
+} {
|
||||||
|
+ errorsql_test 1.$tn "
|
||||||
|
+ SELECT a, sum(b) OVER (
|
||||||
|
+ $frame
|
||||||
|
+ ) FROM t1 ORDER BY 1
|
||||||
|
+ "
|
||||||
|
+}
|
||||||
|
+errorsql_test 2.1 {
|
||||||
|
+ SELECT sum( sum(a) OVER () ) FROM t1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+errorsql_test 2.2 {
|
||||||
|
+ SELECT sum(a) OVER () AS xyz FROM t1 ORDER BY sum(xyz);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+finish_test
|
||||||
|
diff --git a/test/windowerr.test b/test/windowerr.test
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..97dae64
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/windowerr.test
|
||||||
|
@@ -0,0 +1,99 @@
|
||||||
|
+# 2019 March 01
|
||||||
|
+#
|
||||||
|
+# The author disclaims copyright to this source code. In place of
|
||||||
|
+# a legal notice, here is a blessing:
|
||||||
|
+#
|
||||||
|
+# May you do good and not evil.
|
||||||
|
+# May you find forgiveness for yourself and forgive others.
|
||||||
|
+# May you share freely, never taking more than you give.
|
||||||
|
+#
|
||||||
|
+#***********************************************************************
|
||||||
|
+# This file implements regression tests for SQLite library.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+####################################################
|
||||||
|
+# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
|
||||||
|
+####################################################
|
||||||
|
+
|
||||||
|
+set testdir [file dirname $argv0]
|
||||||
|
+source $testdir/tester.tcl
|
||||||
|
+set testprefix windowerr
|
||||||
|
+
|
||||||
|
+ifcapable !windowfunc { finish_test ; return }
|
||||||
|
+do_execsql_test 1.0 {
|
||||||
|
+ DROP TABLE IF EXISTS t1;
|
||||||
|
+ CREATE TABLE t1(a INTEGER, b INTEGER);
|
||||||
|
+ INSERT INTO t1 VALUES(1, 1);
|
||||||
|
+ INSERT INTO t1 VALUES(2, 2);
|
||||||
|
+ INSERT INTO t1 VALUES(3, 3);
|
||||||
|
+ INSERT INTO t1 VALUES(4, 4);
|
||||||
|
+ INSERT INTO t1 VALUES(5, 5);
|
||||||
|
+} {}
|
||||||
|
+
|
||||||
|
+# PG says ERROR: frame starting offset must not be negative
|
||||||
|
+do_test 1.1 { catch { execsql {
|
||||||
|
+ SELECT a, sum(b) OVER (
|
||||||
|
+ ORDER BY a ROWS BETWEEN -1 PRECEDING AND 1 FOLLOWING
|
||||||
|
+ ) FROM t1 ORDER BY 1
|
||||||
|
+} } } 1
|
||||||
|
+
|
||||||
|
+# PG says ERROR: frame ending offset must not be negative
|
||||||
|
+do_test 1.2 { catch { execsql {
|
||||||
|
+ SELECT a, sum(b) OVER (
|
||||||
|
+ ORDER BY a ROWS BETWEEN 1 PRECEDING AND -1 FOLLOWING
|
||||||
|
+ ) FROM t1 ORDER BY 1
|
||||||
|
+} } } 1
|
||||||
|
+
|
||||||
|
+# PG says ERROR: invalid preceding or following size in window function
|
||||||
|
+do_test 1.3 { catch { execsql {
|
||||||
|
+ SELECT a, sum(b) OVER (
|
||||||
|
+ ORDER BY a RANGE BETWEEN -1 PRECEDING AND 1 FOLLOWING
|
||||||
|
+ ) FROM t1 ORDER BY 1
|
||||||
|
+} } } 1
|
||||||
|
+
|
||||||
|
+# PG says ERROR: invalid preceding or following size in window function
|
||||||
|
+do_test 1.4 { catch { execsql {
|
||||||
|
+ SELECT a, sum(b) OVER (
|
||||||
|
+ ORDER BY a RANGE BETWEEN 1 PRECEDING AND -1 FOLLOWING
|
||||||
|
+ ) FROM t1 ORDER BY 1
|
||||||
|
+} } } 1
|
||||||
|
+
|
||||||
|
+# PG says ERROR: frame starting offset must not be negative
|
||||||
|
+do_test 1.5 { catch { execsql {
|
||||||
|
+ SELECT a, sum(b) OVER (
|
||||||
|
+ ORDER BY a GROUPS BETWEEN -1 PRECEDING AND 1 FOLLOWING
|
||||||
|
+ ) FROM t1 ORDER BY 1
|
||||||
|
+} } } 1
|
||||||
|
+
|
||||||
|
+# PG says ERROR: frame ending offset must not be negative
|
||||||
|
+do_test 1.6 { catch { execsql {
|
||||||
|
+ SELECT a, sum(b) OVER (
|
||||||
|
+ ORDER BY a GROUPS BETWEEN 1 PRECEDING AND -1 FOLLOWING
|
||||||
|
+ ) FROM t1 ORDER BY 1
|
||||||
|
+} } } 1
|
||||||
|
+
|
||||||
|
+# PG says ERROR: RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column
|
||||||
|
+do_test 1.7 { catch { execsql {
|
||||||
|
+ SELECT a, sum(b) OVER (
|
||||||
|
+ ORDER BY a,b RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
|
||||||
|
+ ) FROM t1 ORDER BY 1
|
||||||
|
+} } } 1
|
||||||
|
+
|
||||||
|
+# PG says ERROR: RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column
|
||||||
|
+do_test 1.8 { catch { execsql {
|
||||||
|
+ SELECT a, sum(b) OVER (
|
||||||
|
+ PARTITION BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
|
||||||
|
+ ) FROM t1 ORDER BY 1
|
||||||
|
+} } } 1
|
||||||
|
+
|
||||||
|
+# PG says ERROR: aggregate function calls cannot contain window function calls
|
||||||
|
+do_test 2.1 { catch { execsql {
|
||||||
|
+ SELECT sum( sum(a) OVER () ) FROM t1;
|
||||||
|
+} } } 1
|
||||||
|
+
|
||||||
|
+# PG says ERROR: column "xyz" does not exist
|
||||||
|
+do_test 2.2 { catch { execsql {
|
||||||
|
+ SELECT sum(a) OVER () AS xyz FROM t1 ORDER BY sum(xyz);
|
||||||
|
+} } } 1
|
||||||
|
+
|
||||||
|
+finish_test
|
||||||
|
--
|
||||||
|
2.24.1
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
Subject: [PATCH] Fix a use-after-free bug in the fts3 snippet() function.
|
||||||
|
|
||||||
|
---
|
||||||
|
ext/fts3/fts3.c | 1 +
|
||||||
|
test/fts3snippet2.test | 59 ++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 60 insertions(+)
|
||||||
|
create mode 100644 test/fts3snippet2.test
|
||||||
|
|
||||||
|
diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c
|
||||||
|
index 84fc8a5..9ddd201 100644
|
||||||
|
--- a/ext/fts3/fts3.c
|
||||||
|
+++ b/ext/fts3/fts3.c
|
||||||
|
@@ -5213,6 +5213,7 @@ static void fts3EvalNextRow(
|
||||||
|
fts3EvalNextRow(pCsr, pLeft, pRc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ pRight->bEof = pLeft->bEof = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
diff --git a/test/fts3snippet2.test b/test/fts3snippet2.test
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..607b01e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fts3snippet2.test
|
||||||
|
@@ -0,0 +1,59 @@
|
||||||
|
+# 2020-05-14
|
||||||
|
+#
|
||||||
|
+# The author disclaims copyright to this source code. In place of
|
||||||
|
+# a legal notice, here is a blessing:
|
||||||
|
+#
|
||||||
|
+# May you do good and not evil.
|
||||||
|
+# May you find forgiveness for yourself and forgive others.
|
||||||
|
+# May you share freely, never taking more than you give.
|
||||||
|
+#
|
||||||
|
+#*************************************************************************
|
||||||
|
+#
|
||||||
|
+# The tests in this file test the FTS3 auxillary functions offsets(),
|
||||||
|
+# snippet() and matchinfo() work. At time of writing, running this file
|
||||||
|
+# provides full coverage of fts3_snippet.c.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+set testdir [file dirname $argv0]
|
||||||
|
+source $testdir/tester.tcl
|
||||||
|
+set testprefix fts3snippet
|
||||||
|
+
|
||||||
|
+# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
|
||||||
|
+ifcapable !fts3 { finish_test ; return }
|
||||||
|
+source $testdir/fts3_common.tcl
|
||||||
|
+
|
||||||
|
+set sqlite_fts3_enable_parentheses 1
|
||||||
|
+#-------------------------------------------------------------------------
|
||||||
|
+# Request a snippet from a query with more than 64 phrases.
|
||||||
|
+#
|
||||||
|
+reset_db
|
||||||
|
+do_execsql_test 1.0 {
|
||||||
|
+ CREATE VIRTUAL TABLE f USING fts3(b);
|
||||||
|
+ INSERT INTO f VALUES ( x'746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218');
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+do_execsql_test 1.1 {
|
||||||
|
+ SELECT length(snippet(f))>0 FROM f WHERE b MATCH x'1065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a010f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c2a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e0f42';
|
||||||
|
+} {1}
|
||||||
|
+
|
||||||
|
+reset_db
|
||||||
|
+do_execsql_test 2.0 {
|
||||||
|
+ CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY);
|
||||||
|
+ INSERT INTO t0 VALUES (1, '1234','aaaa','bbbb');
|
||||||
|
+ SELECT snippet(t0) FROM t0 WHERE t0 MATCH x'0a4d4d4d4d320a4f52d70a310a310a4e4541520a0a31f6ce0a4f520a0a310a310a310a4f520a75fc2a242424' ;
|
||||||
|
+} {<b>1</b>}
|
||||||
|
+
|
||||||
|
+reset_db
|
||||||
|
+do_execsql_test 2.1 {
|
||||||
|
+ CREATE VIRTUAL TABLE t0 USING fts3(
|
||||||
|
+ col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY
|
||||||
|
+ );
|
||||||
|
+ INSERT INTO t0 VALUES ('one', '1234','aaaa','bbbb');
|
||||||
|
+}
|
||||||
|
+do_execsql_test 2.2 {
|
||||||
|
+ SELECT snippet(t0) FROM t0 WHERE t0 MATCH
|
||||||
|
+ '(def AND (one NEAR abc)) OR one'
|
||||||
|
+} {<b>one</b>}
|
||||||
|
+
|
||||||
|
+set sqlite_fts3_enable_parentheses 0
|
||||||
|
+finish_test
|
||||||
|
--
|
||||||
|
2.24.1
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
Subject: [PATCH] Do not allow a virtual table to be renamed into the name of
|
||||||
|
one of its shadows.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/alter.c | 5 ++++-
|
||||||
|
src/build.c | 28 ++++++++++++++++++++++------
|
||||||
|
src/sqliteInt.h | 5 +++++
|
||||||
|
3 files changed, 31 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/alter.c b/src/alter.c
|
||||||
|
index 1280e90..0fa24c0 100644
|
||||||
|
--- a/src/alter.c
|
||||||
|
+++ b/src/alter.c
|
||||||
|
@@ -117,7 +117,10 @@ void sqlite3AlterRenameTable(
|
||||||
|
/* Check that a table or index named 'zName' does not already exist
|
||||||
|
** in database iDb. If so, this is an error.
|
||||||
|
*/
|
||||||
|
- if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
|
||||||
|
+ if( sqlite3FindTable(db, zName, zDb)
|
||||||
|
+ || sqlite3FindIndex(db, zName, zDb)
|
||||||
|
+ || sqlite3IsShadowTableOf(db, pTab, zName)
|
||||||
|
+ ){
|
||||||
|
sqlite3ErrorMsg(pParse,
|
||||||
|
"there is already another table or index with this name: %s", zName);
|
||||||
|
goto exit_rename_table;
|
||||||
|
diff --git a/src/build.c b/src/build.c
|
||||||
|
index e0fed8a..426428b 100644
|
||||||
|
--- a/src/build.c
|
||||||
|
+++ b/src/build.c
|
||||||
|
@@ -1899,6 +1899,27 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||||
|
recomputeColumnsNotIndexed(pPk);
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
+#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
|
+/*
|
||||||
|
+** Return true if pTab is a virtual table and zName is a shadow table name
|
||||||
|
+** for that virtual table.
|
||||||
|
+*/
|
||||||
|
+int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){
|
||||||
|
+ int nName; /* Length of zName */
|
||||||
|
+
|
||||||
|
+ if( !IsVirtual(pTab) ) return 0;
|
||||||
|
+ nName = sqlite3Strlen30(pTab->zName);
|
||||||
|
+ if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0;
|
||||||
|
+ if( zName[nName]!='_' ) return 0;
|
||||||
|
+ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
|
||||||
|
+ if( pMod==0 ) return 0;
|
||||||
|
+ if( pMod->pModule->iVersion<3 ) return 0;
|
||||||
|
+ if( pMod->pModule->xShadowName==0 ) return 0;
|
||||||
|
+ return pMod->pModule->xShadowName(zName+nName+1);
|
||||||
|
+}
|
||||||
|
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
+
|
||||||
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
|
/*
|
||||||
|
** Return true if zName is a shadow table name in the current database
|
||||||
|
@@ -1910,7 +1931,6 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||||
|
static int isShadowTableName(sqlite3 *db, char *zName){
|
||||||
|
char *zTail; /* Pointer to the last "_" in zName */
|
||||||
|
Table *pTab; /* Table that zName is a shadow of */
|
||||||
|
- Module *pMod; /* Module for the virtual table */
|
||||||
|
|
||||||
|
zTail = strrchr(zName, '_');
|
||||||
|
if( zTail==0 ) return 0;
|
||||||
|
@@ -1919,11 +1939,7 @@ static int isShadowTableName(sqlite3 *db, char *zName){
|
||||||
|
*zTail = '_';
|
||||||
|
if( pTab==0 ) return 0;
|
||||||
|
if( !IsVirtual(pTab) ) return 0;
|
||||||
|
- pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
|
||||||
|
- if( pMod==0 ) return 0;
|
||||||
|
- if( pMod->pModule->iVersion<3 ) return 0;
|
||||||
|
- if( pMod->pModule->xShadowName==0 ) return 0;
|
||||||
|
- return pMod->pModule->xShadowName(zTail+1);
|
||||||
|
+ return sqlite3IsShadowTableOf(db, pTab, zName);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define isShadowTableName(x,y) 0
|
||||||
|
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
|
||||||
|
index b7d3571..76337f7 100644
|
||||||
|
--- a/src/sqliteInt.h
|
||||||
|
+++ b/src/sqliteInt.h
|
||||||
|
@@ -4407,6 +4407,11 @@ void sqlite3AutoLoadExtensions(sqlite3*);
|
||||||
|
);
|
||||||
|
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
|
||||||
|
#endif
|
||||||
|
+#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
|
+ int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
|
||||||
|
+#else
|
||||||
|
+# define sqlite3IsShadowTableOf(A,B,C) 0
|
||||||
|
+#endif
|
||||||
|
int sqlite3VtabEponymousTableInit(Parse*,Module*);
|
||||||
|
void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
|
||||||
|
void sqlite3VtabMakeWritable(Parse*,Table*);
|
||||||
|
--
|
||||||
|
2.24.1
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
Subject: [PATCH] Fix a null pointer deference that can occur on a strange
|
||||||
|
matchinfo() query.
|
||||||
|
|
||||||
|
---
|
||||||
|
ext/fts3/fts3_snippet.c | 2 +-
|
||||||
|
test/fts3matchinfo2.test | 35 +++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 36 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 test/fts3matchinfo2.test
|
||||||
|
|
||||||
|
diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c
|
||||||
|
index a0771c0..5778620 100644
|
||||||
|
--- a/ext/fts3/fts3_snippet.c
|
||||||
|
+++ b/ext/fts3/fts3_snippet.c
|
||||||
|
@@ -869,7 +869,7 @@ static void fts3ExprLHits(
|
||||||
|
iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
- while( 1 ){
|
||||||
|
+ if( pIter ) while( 1 ){
|
||||||
|
int nHit = fts3ColumnlistCount(&pIter);
|
||||||
|
if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
|
||||||
|
if( p->flag==FTS3_MATCHINFO_LHITS ){
|
||||||
|
diff --git a/test/fts3matchinfo2.test b/test/fts3matchinfo2.test
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..d6b3ad0
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fts3matchinfo2.test
|
||||||
|
@@ -0,0 +1,35 @@
|
||||||
|
+# 2020-05-14
|
||||||
|
+#
|
||||||
|
+# The author disclaims copyright to this source code. In place of
|
||||||
|
+# a legal notice, here is a blessing:
|
||||||
|
+#
|
||||||
|
+# May you do good and not evil.
|
||||||
|
+# May you find forgiveness for yourself and forgive others.
|
||||||
|
+# May you share freely, never taking more than you give.
|
||||||
|
+#
|
||||||
|
+#***********************************************************************
|
||||||
|
+# This file implements regression tests for the FTS3 module. The focus
|
||||||
|
+# of this file is tables created with the "matchinfo=fts3" option.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+set testdir [file dirname $argv0]
|
||||||
|
+source $testdir/tester.tcl
|
||||||
|
+
|
||||||
|
+# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
|
||||||
|
+ifcapable !fts3 { finish_test ; return }
|
||||||
|
+
|
||||||
|
+set sqlite_fts3_enable_parentheses 1
|
||||||
|
+
|
||||||
|
+# Crash case found by cyg0810 at gmail.com 2020-05-14. Reported to
|
||||||
|
+# chromium (which is not vulnerable) who kindly referred it to us.
|
||||||
|
+#
|
||||||
|
+do_execsql_test 1.0 {
|
||||||
|
+ CREATE TABLE t_content(col0 INTEGER);
|
||||||
|
+ CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY);
|
||||||
|
+ INSERT INTO t0 VALUES (1, '1234','aaaa','bbbb');
|
||||||
|
+ SELECT hex(matchinfo(t0,'yxy')) FROM t0 WHERE t0 MATCH x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d';
|
||||||
|
+} {/000000.*0000000/}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+set sqlite_fts3_enable_parentheses 0
|
||||||
|
+finish_test
|
||||||
|
\ No newline at end of file
|
||||||
|
--
|
||||||
|
2.24.1
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
From 1668926bc3c7da0b2870a60382b179a0e3edb5de Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Thu, 26 Mar 2020 08:14:29 +0100
|
||||||
|
Subject: [PATCH] Do not allow the constant-propagation optimization to apple
|
||||||
|
to ON/USING clause terms as it does not help and it might cause downstream
|
||||||
|
problems.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/select.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/select.c b/src/select.c
|
||||||
|
index bbd13a4..88a43df 100644
|
||||||
|
--- a/src/select.c
|
||||||
|
+++ b/src/select.c
|
||||||
|
@@ -4171,7 +4171,7 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
|
||||||
|
int i;
|
||||||
|
WhereConst *pConst;
|
||||||
|
if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
|
||||||
|
- if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue;
|
||||||
|
+ if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ) return WRC_Continue;
|
||||||
|
pConst = pWalker->u.pConst;
|
||||||
|
for(i=0; i<pConst->nConst; i++){
|
||||||
|
Expr *pColumn = pConst->apExpr[i*2];
|
||||||
|
--
|
||||||
|
2.24.1
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
From 2d788539b0018d34d3cabb328387ba6bec41ec42 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Thu, 26 Mar 2020 09:43:43 +0100
|
||||||
|
Subject: [PATCH] NULL pointer dereference and segmentation fault because of
|
||||||
|
generated column optimizations
|
||||||
|
|
||||||
|
Take care when checking the table of a TK_COLUMN expression node to
|
||||||
|
see if the table is a virtual table to first ensure that the
|
||||||
|
Expr.y.pTab pointer is not null due to generated column optimizations.
|
||||||
|
---
|
||||||
|
src/expr.c | 13 ++++++++++---
|
||||||
|
src/sqliteInt.h | 3 +++
|
||||||
|
src/whereexpr.c | 12 ++++++++----
|
||||||
|
3 files changed, 21 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/expr.c b/src/expr.c
|
||||||
|
index b081ca2..5f98f76 100644
|
||||||
|
--- a/src/expr.c
|
||||||
|
+++ b/src/expr.c
|
||||||
|
@@ -4901,18 +4901,25 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
|
||||||
|
case TK_LT:
|
||||||
|
case TK_LE:
|
||||||
|
case TK_GT:
|
||||||
|
- case TK_GE:
|
||||||
|
+ case TK_GE: {
|
||||||
|
+ Expr *pLeft = pExpr->pLeft;
|
||||||
|
+ Expr *pRight = pExpr->pRight;
|
||||||
|
testcase( pExpr->op==TK_EQ );
|
||||||
|
testcase( pExpr->op==TK_NE );
|
||||||
|
testcase( pExpr->op==TK_LT );
|
||||||
|
testcase( pExpr->op==TK_LE );
|
||||||
|
testcase( pExpr->op==TK_GT );
|
||||||
|
testcase( pExpr->op==TK_GE );
|
||||||
|
- if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
|
||||||
|
- || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
|
||||||
|
+ /* The y.pTab=0 assignment in wherecode.c always happens after the
|
||||||
|
+ ** impliesNotNullRow() test */
|
||||||
|
+ if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0)
|
||||||
|
+ && IsVirtual(pLeft->y.pTab))
|
||||||
|
+ || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0)
|
||||||
|
+ && IsVirtual(pRight->y.pTab))
|
||||||
|
){
|
||||||
|
return WRC_Prune;
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
default:
|
||||||
|
return WRC_Continue;
|
||||||
|
}
|
||||||
|
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
|
||||||
|
index 051aa40..5f5f3cc 100644
|
||||||
|
--- a/src/sqliteInt.h
|
||||||
|
+++ b/src/sqliteInt.h
|
||||||
|
@@ -2014,8 +2014,11 @@ struct Table {
|
||||||
|
*/
|
||||||
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
|
# define IsVirtual(X) ((X)->nModuleArg)
|
||||||
|
+# define ExprIsVtab(X) \
|
||||||
|
+ ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg)
|
||||||
|
#else
|
||||||
|
# define IsVirtual(X) 0
|
||||||
|
+# define ExprIsVtab(X) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/src/whereexpr.c b/src/whereexpr.c
|
||||||
|
index dbb7f0d..9d2813a 100644
|
||||||
|
--- a/src/whereexpr.c
|
||||||
|
+++ b/src/whereexpr.c
|
||||||
|
@@ -382,7 +382,8 @@ static int isAuxiliaryVtabOperator(
|
||||||
|
** MATCH(expression,vtab_column)
|
||||||
|
*/
|
||||||
|
pCol = pList->a[1].pExpr;
|
||||||
|
- if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
|
||||||
|
+ testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
|
||||||
|
+ if( ExprIsVtab(pCol) ){
|
||||||
|
for(i=0; i<ArraySize(aOp); i++){
|
||||||
|
if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
|
||||||
|
*peOp2 = aOp[i].eOp2;
|
||||||
|
@@ -404,7 +405,8 @@ static int isAuxiliaryVtabOperator(
|
||||||
|
** with function names in an arbitrary case.
|
||||||
|
*/
|
||||||
|
pCol = pList->a[0].pExpr;
|
||||||
|
- if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
|
||||||
|
+ testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
|
||||||
|
+ if( ExprIsVtab(pCol) ){
|
||||||
|
sqlite3_vtab *pVtab;
|
||||||
|
sqlite3_module *pMod;
|
||||||
|
void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
|
||||||
|
@@ -427,10 +429,12 @@ static int isAuxiliaryVtabOperator(
|
||||||
|
int res = 0;
|
||||||
|
Expr *pLeft = pExpr->pLeft;
|
||||||
|
Expr *pRight = pExpr->pRight;
|
||||||
|
- if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
|
||||||
|
+ testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 );
|
||||||
|
+ if( ExprIsVtab(pLeft) ){
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
- if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
|
||||||
|
+ testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 );
|
||||||
|
+ if( pRight && ExprIsVtab(pRight) ){
|
||||||
|
res++;
|
||||||
|
SWAP(Expr*, pLeft, pRight);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.24.1
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
From 75525dbdf9b7ed003e343c42710e8b13f73a7607 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Dubaj <odubaj@redhat.com>
|
||||||
|
Date: Thu, 23 Jan 2020 15:08:13 +0100
|
||||||
|
Subject: [PATCH] Fix buffer underflows in the zipfile extension associated
|
||||||
|
with zero-length or NULL filename in the ZIP archive. But report on the
|
||||||
|
mailing list by Yongheng and Rui.
|
||||||
|
|
||||||
|
---
|
||||||
|
ext/misc/zipfile.c | 14 +++++++++-----
|
||||||
|
test/zipfile.test | 13 +++++++++++++
|
||||||
|
2 files changed, 22 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c
|
||||||
|
index e6141ef..7fd4074 100644
|
||||||
|
--- a/ext/misc/zipfile.c
|
||||||
|
+++ b/ext/misc/zipfile.c
|
||||||
|
@@ -1433,8 +1433,8 @@ static int zipfileGetMode(
|
||||||
|
** identical, ignoring any trailing '/' character in either path. */
|
||||||
|
static int zipfileComparePath(const char *zA, const char *zB, int nB){
|
||||||
|
int nA = (int)strlen(zA);
|
||||||
|
- if( zA[nA-1]=='/' ) nA--;
|
||||||
|
- if( zB[nB-1]=='/' ) nB--;
|
||||||
|
+ if( nA>0 && zA[nA-1]=='/' ) nA--;
|
||||||
|
+ if( nB>0 && zB[nB-1]=='/' ) nB--;
|
||||||
|
if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -1628,11 +1628,15 @@ static int zipfileUpdate(
|
||||||
|
** '/'. This appears to be required for compatibility with info-zip
|
||||||
|
** (the unzip command on unix). It does not create directories
|
||||||
|
** otherwise. */
|
||||||
|
- if( zPath[nPath-1]!='/' ){
|
||||||
|
+ if( nPath<=0 || zPath[nPath-1]!='/' ){
|
||||||
|
zFree = sqlite3_mprintf("%s/", zPath);
|
||||||
|
- if( zFree==0 ){ rc = SQLITE_NOMEM; }
|
||||||
|
zPath = (const char*)zFree;
|
||||||
|
- nPath = (int)strlen(zPath);
|
||||||
|
+ if( zFree==0 ){
|
||||||
|
+ rc = SQLITE_NOMEM;
|
||||||
|
+ nPath = 0;
|
||||||
|
+ }else{
|
||||||
|
+ nPath = (int)strlen(zPath);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/test/zipfile.test b/test/zipfile.test
|
||||||
|
index e4b8088..9f07c0a 100644
|
||||||
|
--- a/test/zipfile.test
|
||||||
|
+++ b/test/zipfile.test
|
||||||
|
@@ -821,4 +821,17 @@ do_execsql_test 14.10 {
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
} {3 ok}
|
||||||
|
|
||||||
|
+# 2019-12-26 More problems in zipfile from the Yongheng and Rui fuzzer
|
||||||
|
+#
|
||||||
|
+do_execsql_test 15.10 {
|
||||||
|
+ DROP TABLE IF EXISTS t1;
|
||||||
|
+ CREATE VIRTUAL TABLE t1 USING zipfile(null);
|
||||||
|
+ REPLACE INTO t1 VALUES(null,null,0,null,null,null,null);
|
||||||
|
+} {}
|
||||||
|
+do_execsql_test 15.20 {
|
||||||
|
+ DROP TABLE IF EXISTS t2;
|
||||||
|
+ CREATE VIRTUAL TABLE t2 USING zipfile(null);
|
||||||
|
+ REPLACE INTO t2 values(null,null,null,null,null,10,null);
|
||||||
|
+} {}
|
||||||
|
+
|
||||||
|
finish_test
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
Summary: Library that implements an embeddable SQL database engine
|
Summary: Library that implements an embeddable SQL database engine
|
||||||
Name: sqlite
|
Name: sqlite
|
||||||
Version: %{rpmver}
|
Version: %{rpmver}
|
||||||
Release: 4%{?dist}
|
Release: 10%{?dist}
|
||||||
License: Public Domain
|
License: Public Domain
|
||||||
Group: Applications/Databases
|
Group: Applications/Databases
|
||||||
URL: http://www.sqlite.org/
|
URL: http://www.sqlite.org/
|
||||||
|
@ -37,6 +37,38 @@ Patch8: sqlite-3.18.0-sync2-dirsync.patch
|
||||||
# Fix for CVE-2019-8457 (rhbz#1723338)
|
# Fix for CVE-2019-8457 (rhbz#1723338)
|
||||||
# https://www.sqlite.org/src/info/90acdbfce9c08858
|
# https://www.sqlite.org/src/info/90acdbfce9c08858
|
||||||
Patch9: sqlite-3.26.0-out-of-bounds-read.patch
|
Patch9: sqlite-3.26.0-out-of-bounds-read.patch
|
||||||
|
# Fix for CVE-2019-13752
|
||||||
|
Patch10: sqlite-3.26-CVE-2019-13752.patch
|
||||||
|
# Fix for CVE-2019-13753
|
||||||
|
Patch11: sqlite-3.26-CVE-2019-13753.patch
|
||||||
|
# Fix for CVE-2019-13734
|
||||||
|
Patch12: sqlite-3.26.0-CVE-2019-13734.patch
|
||||||
|
# Fix for CVE-2019-19924
|
||||||
|
Patch13: sqlite-3.26.0-CVE-2019-19924.patch
|
||||||
|
# Fix for CVE-2019-19923
|
||||||
|
Patch14: sqlite-3.26.0-CVE-2019-19923.patch
|
||||||
|
# Fix for CVE-2019-19925
|
||||||
|
Patch15: sqlite-3.26.0-CVE-2019-19925.patch
|
||||||
|
# Fix for CVE-2019-19959
|
||||||
|
Patch16: sqlite-3.26.0-CVE-2019-19959.patch
|
||||||
|
# Fix for issues found by covscan
|
||||||
|
Patch17: sqlite-3.26.0-zPath-covscan.patch
|
||||||
|
# Fix for CVE-2019-20218
|
||||||
|
Patch18: sqlite-3.26.0-CVE-2019-20218.patch
|
||||||
|
# Fix for CVE-2020-6405
|
||||||
|
Patch19: sqlite-3.26.0-CVE-2020-6405.patch
|
||||||
|
# Fix for CVE-2020-9327
|
||||||
|
Patch20: sqlite-3.26.0-CVE-2020-9327.patch
|
||||||
|
# Fix for CVE-2019-16168
|
||||||
|
Patch21: sqlite-3.26.0-CVE-2019-16168.patch
|
||||||
|
# Fix for CVE-2019-5018
|
||||||
|
Patch22: sqlite-3.26.0-CVE-2019-5018.patch
|
||||||
|
# Fix for CVE-2020-13632
|
||||||
|
Patch23: sqlite-3.26.0-CVE-2020-13632.patch
|
||||||
|
# Fix for CVE-2020-13631
|
||||||
|
Patch24: sqlite-3.26.0-CVE-2020-13631.patch
|
||||||
|
# Fix for CVE-2020-13630
|
||||||
|
Patch25: sqlite-3.26.0-CVE-2020-13630.patch
|
||||||
|
|
||||||
BuildRequires: ncurses-devel readline-devel glibc-devel
|
BuildRequires: ncurses-devel readline-devel glibc-devel
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
|
@ -143,6 +175,22 @@ This package contains the analysis program for %{name}.
|
||||||
%endif
|
%endif
|
||||||
%patch8 -p1
|
%patch8 -p1
|
||||||
%patch9 -p1
|
%patch9 -p1
|
||||||
|
%patch10 -p1
|
||||||
|
%patch11 -p1
|
||||||
|
%patch12 -p1
|
||||||
|
%patch13 -p1
|
||||||
|
%patch14 -p1
|
||||||
|
%patch15 -p1
|
||||||
|
%patch16 -p1
|
||||||
|
%patch17 -p1
|
||||||
|
%patch18 -p1
|
||||||
|
%patch19 -p1
|
||||||
|
%patch20 -p1
|
||||||
|
%patch21 -p1
|
||||||
|
%patch22 -p1
|
||||||
|
%patch23 -p1
|
||||||
|
%patch24 -p1
|
||||||
|
%patch25 -p1
|
||||||
|
|
||||||
# Remove backup-file
|
# Remove backup-file
|
||||||
rm -f %{name}-doc-%{docver}/sqlite.css~ || :
|
rm -f %{name}-doc-%{docver}/sqlite.css~ || :
|
||||||
|
@ -247,6 +295,34 @@ make test
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Jun 10 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.26.0-10
|
||||||
|
- Fixed CVE-2020-13632 (#1845572)
|
||||||
|
- Fixed CVE-2020-13631 (#1845474)
|
||||||
|
- Fixed CVE-2020-13630 (#1845153)
|
||||||
|
|
||||||
|
* Tue Jun 02 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.26.0-9
|
||||||
|
- Fixed CVE-2019-5018 (#1721509)
|
||||||
|
|
||||||
|
* Thu Apr 23 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.26.0-8
|
||||||
|
- Fixed CVE-2019-16168 (#1826897)
|
||||||
|
|
||||||
|
* Tue Mar 24 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.26.0-7
|
||||||
|
- Fixed CVE-2019-20218 (#1791592)
|
||||||
|
- Fixed CVE-2020-6405 (#1804823)
|
||||||
|
- Fixed CVE-2020-0327 (#1816572)
|
||||||
|
|
||||||
|
* Thu Jan 23 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.26.0-6
|
||||||
|
- Fixed issues found by covscan
|
||||||
|
|
||||||
|
* Thu Jan 02 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.26.0-5
|
||||||
|
- Fixed CVE-2019-13752 (#1786529)
|
||||||
|
- Fixed CVE-2019-13753 (#1786535)
|
||||||
|
- Fixed CVE-2019-13734 (#1786509)
|
||||||
|
- Fixed CVE-2019-19924 (#1789776)
|
||||||
|
- Fixed CVE-2019-19923 (#1789812)
|
||||||
|
- Fixed CVE-2019-19925 (#1789808)
|
||||||
|
- Fixed CVE-2019-19959 (#1789823)
|
||||||
|
|
||||||
* Wed Jun 26 2019 Ondrej Dubaj <odubaj@redhat.com> - 3.26.0-4
|
* Wed Jun 26 2019 Ondrej Dubaj <odubaj@redhat.com> - 3.26.0-4
|
||||||
- Fixed CVE-2019-8457 (#1723338)
|
- Fixed CVE-2019-8457 (#1723338)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue