diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e47291 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/sqlite-src-3260000.zip diff --git a/.mingw-sqlite.metadata b/.mingw-sqlite.metadata new file mode 100644 index 0000000..b010288 --- /dev/null +++ b/.mingw-sqlite.metadata @@ -0,0 +1 @@ +a05429d6a8337d60ddc7c6381b49941059a55f68 SOURCES/sqlite-src-3260000.zip diff --git a/SOURCES/sqlite-3.12.2-no-malloc-usable-size.patch b/SOURCES/sqlite-3.12.2-no-malloc-usable-size.patch new file mode 100644 index 0000000..b983bd3 --- /dev/null +++ b/SOURCES/sqlite-3.12.2-no-malloc-usable-size.patch @@ -0,0 +1,24 @@ +diff -up sqlite-src-3120200/configure.ac.malloc_usable_size sqlite-src-3120200/configure.ac +--- sqlite-src-3120200/configure.ac.malloc_usable_size 2016-04-25 09:46:48.134690570 +0200 ++++ sqlite-src-3120200/configure.ac 2016-04-25 09:48:41.622637181 +0200 +@@ -108,7 +108,7 @@ AC_CHECK_HEADERS([sys/types.h stdlib.h s + ######### + # Figure out whether or not we have these functions + # +-AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64]) ++AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s strchrnul usleep utime pread pread64 pwrite pwrite64]) + + ######### + # By default, we use the amalgamation (this may be changed below...) +diff -up sqlite-src-3120200/configure.malloc_usable_size sqlite-src-3120200/configure +--- sqlite-src-3120200/configure.malloc_usable_size 2016-04-25 09:47:12.594679063 +0200 ++++ sqlite-src-3120200/configure 2016-04-25 09:49:28.684615042 +0200 +@@ -10275,7 +10275,7 @@ done + ######### + # Figure out whether or not we have these functions + # +-for ac_func in fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 ++for ac_func in fdatasync gmtime_r isnan localtime_r localtime_s strchrnul usleep utime pread pread64 pwrite pwrite64 + do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` + ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/SOURCES/sqlite-3.16-datetest-2.2c.patch b/SOURCES/sqlite-3.16-datetest-2.2c.patch new file mode 100644 index 0000000..63857db --- /dev/null +++ b/SOURCES/sqlite-3.16-datetest-2.2c.patch @@ -0,0 +1,14 @@ +--- sqlite-src-3160100/test/date.test.orig 2017-01-04 14:48:46.113737093 +0100 ++++ sqlite-src-3160100/test/date.test 2017-01-04 14:49:11.144833563 +0100 +@@ -76,11 +76,6 @@ datetest 2.1c datetime(0,'unixepochx') N + datetest 2.1d datetime('2003-10-22','unixepoch') NULL + datetest 2.2 datetime(946684800,'unixepoch') {2000-01-01 00:00:00} + datetest 2.2b datetime('946684800','unixepoch') {2000-01-01 00:00:00} +-for {set i 0} {$i<1000} {incr i} { +- set sql [format {strftime('%%H:%%M:%%f',1237962480.%03d,'unixepoch')} $i] +- set res [format {06:28:00.%03d} $i] +- datetest 2.2c-$i $sql $res +-} + datetest 2.3 {date('2003-10-22','weekday 0')} 2003-10-26 + datetest 2.4 {date('2003-10-22','weekday 1')} 2003-10-27 + datetest 2.4a {date('2003-10-22','weekday 1')} 2003-10-27 diff --git a/SOURCES/sqlite-3.18.0-sync2-dirsync.patch b/SOURCES/sqlite-3.18.0-sync2-dirsync.patch new file mode 100644 index 0000000..0c7d0a5 --- /dev/null +++ b/SOURCES/sqlite-3.18.0-sync2-dirsync.patch @@ -0,0 +1,90 @@ +--- sqlite-src-3180000/test/sync2.test.sync2-dirsync 2017-03-30 21:26:42.000000000 +0200 ++++ sqlite-src-3180000/test/sync2.test 2017-04-03 13:16:14.422329691 +0200 +@@ -44,6 +44,15 @@ + uplevel [list do_test $tn [list execsql_sync $sql] [list {*}$res]] + } + ++# Wrapper over the expected sync count, takes DIRSYNC into consideration ++proc expected_sync_count {sync_count} { ++ ifcapable dirsync { ++ return $sync_count ++ } else { ++ return [ incr sync_count -1 ] ++ } ++} ++ + #----------------------------------------------------------------------- + # Tests for journal mode. + # +@@ -53,13 +62,13 @@ + INSERT INTO t1 VALUES(1, 2); + } + +-do_execsql_sync_test 1.1 { INSERT INTO t1 VALUES(3, 4) } 4 ++do_execsql_sync_test 1.1 { INSERT INTO t1 VALUES(3, 4) } [ expected_sync_count 4 ] + + # synchronous=normal. So, 1 sync on the directory, 1 on the journal, 1 + # on the db file. 3 in total. + do_execsql_test 1.2.1 { PRAGMA main.synchronous = NORMAL } + do_execsql_test 1.2.2 { PRAGMA main.synchronous } 1 +-do_execsql_sync_test 1.2.3 { INSERT INTO t1 VALUES(5, 6) } 3 ++do_execsql_sync_test 1.2.3 { INSERT INTO t1 VALUES(5, 6) } [ expected_sync_count 3 ] + + # synchronous=off. No syncs. + do_execsql_test 1.3.1 { PRAGMA main.synchronous = OFF } +@@ -70,7 +79,7 @@ + # 2 on the journal, 1 on the db file. 4 in total. + do_execsql_test 1.4.1 { PRAGMA main.synchronous = FULL } + do_execsql_test 1.4.2 { PRAGMA main.synchronous } 2 +-do_execsql_sync_test 1.4.3 { INSERT INTO t1 VALUES(9, 10) } 4 ++do_execsql_sync_test 1.4.3 { INSERT INTO t1 VALUES(9, 10) } [ expected_sync_count 4 ] + + #----------------------------------------------------------------------- + # Tests for wal mode. +@@ -79,7 +88,7 @@ + + # sync=full, journal_mode=wal. One sync on the directory, two on the + # wal file. +-do_execsql_sync_test 1.6 { INSERT INTO t1 VALUES(11, 12) } 3 ++do_execsql_sync_test 1.6 { INSERT INTO t1 VALUES(11, 12) } [ expected_sync_count 3 ] + + # One sync on the wal file. + do_execsql_sync_test 1.7 { INSERT INTO t1 VALUES(13, 14) } 1 +@@ -112,7 +121,7 @@ + + # Wal mode, sync=normal. The first transaction does one sync on directory, + # one on the wal file. The second does no syncs. +- do_execsql_sync_test 1.11.1 { INSERT INTO t1 VALUES(19, 20) } 2 ++ do_execsql_sync_test 1.11.1 { INSERT INTO t1 VALUES(19, 20) } [ expected_sync_count 2 ] + do_execsql_sync_test 1.11.2 { INSERT INTO t1 VALUES(21, 22) } 0 + do_execsql_test 1.11.3 { PRAGMA main.synchronous } 1 + +@@ -129,14 +138,14 @@ + # Delete mode, sync=full. The first transaction does one sync on + # directory, two on the journal file, one on the db. The second does + # the same. +- do_execsql_sync_test 1.15.1 { INSERT INTO t1 VALUES(26, 27) } 4 +- do_execsql_sync_test 1.15.2 { INSERT INTO t1 VALUES(28, 29) } 4 ++ do_execsql_sync_test 1.15.1 { INSERT INTO t1 VALUES(26, 27) } [ expected_sync_count 4 ] ++ do_execsql_sync_test 1.15.2 { INSERT INTO t1 VALUES(28, 29) } [ expected_sync_count 4 ] + do_execsql_test 1.15.3 { PRAGMA main.synchronous } 2 + + # Switch back to wal mode. + do_execsql_test 1.16 { PRAGMA journal_mode = wal } {wal} + +- do_execsql_sync_test 1.17.1 { INSERT INTO t1 VALUES(30, 31) } 2 ++ do_execsql_sync_test 1.17.1 { INSERT INTO t1 VALUES(30, 31) } [ expected_sync_count 2 ] + do_execsql_sync_test 1.17.2 { INSERT INTO t1 VALUES(32, 33) } 0 + do_execsql_test 1.17.3 { PRAGMA main.synchronous } 1 + +@@ -152,8 +161,8 @@ + # Close and reopen the db. Back to synchronous=normal. + db close + sqlite3 db test.db +- do_execsql_sync_test 1.20.1 { INSERT INTO t1 VALUES(38, 39) } 4 +- do_execsql_sync_test 1.20.2 { INSERT INTO t1 VALUES(40, 41) } 4 ++ do_execsql_sync_test 1.20.1 { INSERT INTO t1 VALUES(38, 39) } [ expected_sync_count 4 ] ++ do_execsql_sync_test 1.20.2 { INSERT INTO t1 VALUES(40, 41) } [ expected_sync_count 4 ] + do_execsql_test 1.20.3 { PRAGMA main.synchronous } 2 + } + diff --git a/SOURCES/sqlite-3.26-CVE-2019-13752.patch b/SOURCES/sqlite-3.26-CVE-2019-13752.patch new file mode 100644 index 0000000..b298a21 --- /dev/null +++ b/SOURCES/sqlite-3.26-CVE-2019-13752.patch @@ -0,0 +1,149 @@ +From 92b243715eea17997ed9707540757d0667ad9eb2 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +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 + #include + #include +- ++#include + + #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 + diff --git a/SOURCES/sqlite-3.26-CVE-2019-13753.patch b/SOURCES/sqlite-3.26-CVE-2019-13753.patch new file mode 100644 index 0000000..cc21b6d --- /dev/null +++ b/SOURCES/sqlite-3.26-CVE-2019-13753.patch @@ -0,0 +1,25 @@ +From 0b3ba64a9c7f785f6b3f1c1c15c5b0f1e41e0461 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +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 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-13734.patch b/SOURCES/sqlite-3.26.0-CVE-2019-13734.patch new file mode 100644 index 0000000..9cb8e4c --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-13734.patch @@ -0,0 +1,107 @@ +From 5f4ce30babee8085fc36680c6103d9a06be49ef7 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +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 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-16168.patch b/SOURCES/sqlite-3.26.0-CVE-2019-16168.patch new file mode 100644 index 0000000..d968605 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-16168.patch @@ -0,0 +1,65 @@ +From ab17169870e985b062e520ecf95e6c79ad784f38 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +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 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-19923.patch b/SOURCES/sqlite-3.26.0-CVE-2019-19923.patch new file mode 100644 index 0000000..ea95b19 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-19923.patch @@ -0,0 +1,67 @@ +From 7d47517d579601bb6e59e33bf0896f0ed36aa0aa Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +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 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-19924.patch b/SOURCES/sqlite-3.26.0-CVE-2019-19924.patch new file mode 100644 index 0000000..df29238 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-19924.patch @@ -0,0 +1,60 @@ +From 6b06304c2a46e17a6dc4402eadc75ccac24da893 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +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 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-19925.patch b/SOURCES/sqlite-3.26.0-CVE-2019-19925.patch new file mode 100644 index 0000000..bed5060 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-19925.patch @@ -0,0 +1,50 @@ +From 1986c6384122947b10804cbc5c4d7af85e097404 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +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 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-19959.patch b/SOURCES/sqlite-3.26.0-CVE-2019-19959.patch new file mode 100644 index 0000000..ec1965c --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-19959.patch @@ -0,0 +1,63 @@ +From 16c5290d72cb8059e9dfe545613183b850fc44e4 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +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 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-20218.patch b/SOURCES/sqlite-3.26.0-CVE-2019-20218.patch new file mode 100644 index 0000000..befc39b --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-20218.patch @@ -0,0 +1,102 @@ +From ff5f246e41239cc4dd33ffa73883fa07f78674e1 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Fri, 7 Aug 2020 07:00:29 +0200 +Subject: [PATCH] Do not attempt to unwind the WITH stack in the Parse object + following an error. + +--- + src/select.c | 5 ++++- + src/util.c | 1 + + test/altertab2.test | 20 ++++++++++++++++++++ + test/with3.test | 10 +++++++++- + 4 files changed, 34 insertions(+), 2 deletions(-) + +diff --git a/src/select.c b/src/select.c +index c46f177..a6d1757 100644 +--- a/src/select.c ++++ b/src/select.c +@@ -4639,6 +4639,9 @@ static int withExpand( + With *pWith; /* WITH clause that pCte belongs to */ + + assert( pFrom->pTab==0 ); ++ if( pParse->nErr ){ ++ return SQLITE_ERROR; ++ } + + pCte = searchWith(pParse->pWith, pFrom, &pWith); + if( pCte ){ +@@ -4908,7 +4911,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; + } + +diff --git a/src/util.c b/src/util.c +index 54f9b93..96b0b14 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -222,6 +222,7 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ + sqlite3DbFree(db, pParse->zErrMsg); + pParse->zErrMsg = zMsg; + pParse->rc = SQLITE_ERROR; ++ pParse->pWith = 0; + } + } + +diff --git a/test/altertab2.test b/test/altertab2.test +index 2e4212c..2102e02 100644 +--- a/test/altertab2.test ++++ b/test/altertab2.test +@@ -85,5 +85,25 @@ do_execsql_test 2.3 { + {CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES "p3"(a))} + } + ++#------------------------------------------------------------------------ ++# ++reset_db ++do_execsql_test 3.0 { ++ CREATE TABLE v0 (a); ++ CREATE VIEW v2 (v3) AS ++ WITH x1 AS (SELECT * FROM v2) ++ SELECT v3 AS x, v3 AS y FROM v2; ++} ++ ++do_catchsql_test 3.1 { ++ SELECT * FROM v2 ++} {1 {view v2 is circularly defined}} ++ ++db close ++sqlite3 db test.db ++ ++do_catchsql_test 3.2 { ++ ALTER TABLE v0 RENAME TO t3 ; ++} {1 {error in view v2: view v2 is circularly defined}} + + finish_test +diff --git a/test/with3.test b/test/with3.test +index de150b1..4a3a5a7 100644 +--- a/test/with3.test ++++ b/test/with3.test +@@ -30,7 +30,15 @@ do_catchsql_test 1.0 { + SELECT 5 FROM t0 UNION SELECT 8 FROM m + ) + SELECT * FROM i; +-} {1 {no such table: m}} ++} {1 {no such table: t0}} ++ ++# 2019-11-09 dbfuzzcheck find ++do_catchsql_test 1.1 { ++ CREATE VIEW v1(x,y) AS ++ WITH t1(a,b) AS (VALUES(1,2)) ++ SELECT * FROM nosuchtable JOIN t1; ++ SELECT * FROM v1; ++} {1 {no such table: main.nosuchtable}} + + # Additional test cases that came out of the work to + # fix for Kostya's problem. +-- +2.26.0 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2019-5018.patch b/SOURCES/sqlite-3.26.0-CVE-2019-5018.patch new file mode 100644 index 0000000..fde7e0a --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2019-5018.patch @@ -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 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-13434.patch b/SOURCES/sqlite-3.26.0-CVE-2020-13434.patch new file mode 100644 index 0000000..ec015ab --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-13434.patch @@ -0,0 +1,73 @@ +Subject: [PATCH] Limit the "precision" of floating-point to text conversions + in the printf() function to 100,000,000. + +--- + src/printf.c | 12 ++++++++++++ + test/printf.test | 16 +++++++++++++--- + 2 files changed, 25 insertions(+), 3 deletions(-) + +diff --git a/src/printf.c b/src/printf.c +index 7bce83f..260bf79 100644 +--- a/src/printf.c ++++ b/src/printf.c +@@ -165,6 +165,13 @@ static char *getTextArg(PrintfArguments *p){ + #endif + #define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ + ++/* ++** Hard limit on the precision of floating-point conversions. ++*/ ++#ifndef SQLITE_PRINTF_PRECISION_LIMIT ++# define SQLITE_FP_PRECISION_LIMIT 100000000 ++#endif ++ + /* + ** Render a string given by "fmt" into the StrAccum object. + */ +@@ -471,6 +478,11 @@ void sqlite3_str_vappendf( + length = 0; + #else + if( precision<0 ) precision = 6; /* Set default precision */ ++#ifdef SQLITE_FP_PRECISION_LIMIT ++ if( precision>SQLITE_FP_PRECISION_LIMIT ){ ++ precision = SQLITE_FP_PRECISION_LIMIT; ++ } ++#endif + if( realvalue<0.0 ){ + realvalue = -realvalue; + prefix = '-'; +diff --git a/test/printf.test b/test/printf.test +index d768898..a2b5e2a 100644 +--- a/test/printf.test ++++ b/test/printf.test +@@ -538,9 +538,11 @@ do_test printf-2.1.2.8 { + do_test printf-2.1.2.9 { + sqlite3_mprintf_double {abc: %d %d (%1.1g) :xyz} 1 1 1.0e-20 + } {abc: 1 1 (1e-20) :xyz} +-do_test printf-2.1.2.10 { +- sqlite3_mprintf_double {abc: %*.*f} 2000000000 1000000000 1.0e-20 +-} {abc: } ++if {$SQLITE_MAX_LENGTH<=[expr 1000*1000*1000]} { ++ do_test printf-2.1.2.10 { ++ sqlite3_mprintf_double {abc: %*.*f} 2000000000 1000000000 1.0e-20 ++ } {} ++} + do_test printf-2.1.3.1 { + sqlite3_mprintf_double {abc: (%*.*f) :xyz} 1 1 1.0 + } {abc: (1.0) :xyz} +@@ -3777,4 +3779,12 @@ foreach ::iRepeat {0 1} { + } + } + ++# 2020-05-23 ++# ticket 23439ea582241138 ++# ++do_execsql_test printf-16.1 { ++ SELECT printf('%.*g',2147483647,0.01); ++} {0.01} ++ ++ + finish_test +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-13630.patch b/SOURCES/sqlite-3.26.0-CVE-2020-13630.patch new file mode 100644 index 0000000..17525f6 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-13630.patch @@ -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' ; ++} {1} ++ ++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' ++} {one} ++ ++set sqlite_fts3_enable_parentheses 0 ++finish_test +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-13631.patch b/SOURCES/sqlite-3.26.0-CVE-2020-13631.patch new file mode 100644 index 0000000..0813c9a --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-13631.patch @@ -0,0 +1,98 @@ +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 | 29 +++++++++++++++++++++++------ + src/sqliteInt.h | 5 +++++ + 3 files changed, 32 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..afe4171 100644 +--- a/src/build.c ++++ b/src/build.c +@@ -1899,6 +1899,28 @@ 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 */ ++ Module *pMod; /* Module for the virtual table */ ++ ++ if( !IsVirtual(pTab) ) return 0; ++ nName = sqlite3Strlen30(pTab->zName); ++ if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0; ++ if( zName[nName]!='_' ) 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(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 +1932,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 +1940,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 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-13632.patch b/SOURCES/sqlite-3.26.0-CVE-2020-13632.patch new file mode 100644 index 0000000..f72b8d9 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-13632.patch @@ -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 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-15358.patch b/SOURCES/sqlite-3.26.0-CVE-2020-15358.patch new file mode 100644 index 0000000..2cff0ad --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-15358.patch @@ -0,0 +1,88 @@ +Subject: [PATCH] Fix a defect in the query-flattener optimization + +--- + src/select.c | 8 ++++---- + src/sqliteInt.h | 1 + + test/selectA.test | 22 ++++++++++++++++++++++ + 3 files changed, 27 insertions(+), 4 deletions(-) + +diff --git a/src/select.c b/src/select.c +index 88a43df..a513d36 100644 +--- a/src/select.c ++++ b/src/select.c +@@ -2686,9 +2686,7 @@ static int multiSelect( + selectOpName(p->op))); + rc = sqlite3Select(pParse, p, &uniondest); + testcase( rc!=SQLITE_OK ); +- /* Query flattening in sqlite3Select() might refill p->pOrderBy. +- ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ +- sqlite3ExprListDelete(db, p->pOrderBy); ++ assert( p->pOrderBy==0 ); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->pOrderBy = 0; +@@ -4010,7 +4008,7 @@ static int flattenSubquery( + ** We look at every expression in the outer query and every place we see + ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". + */ +- if( pSub->pOrderBy ){ ++ if( pSub->pOrderBy && (pParent->selFlags & SF_NoopOrderBy)==0 ){ + /* At this point, any non-zero iOrderByCol values indicate that the + ** ORDER BY column expression is identical to the iOrderByCol'th + ** expression returned by SELECT statement pSub. Since these values +@@ -5633,6 +5631,8 @@ int sqlite3Select( + sqlite3ExprListDelete(db, p->pOrderBy); + p->pOrderBy = 0; + p->selFlags &= ~SF_Distinct; ++ p->selFlags |= SF_NoopOrderBy; ++ + } + sqlite3SelectPrep(pParse, p, 0); + if( pParse->nErr || db->mallocFailed ){ +diff --git a/src/sqliteInt.h b/src/sqliteInt.h +index 76337f7..60b2ebd 100644 +--- a/src/sqliteInt.h ++++ b/src/sqliteInt.h +@@ -2874,6 +2874,7 @@ struct Select { + #define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */ + #define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ + #define SF_ComplexResult 0x40000 /* Result contains subquery or function */ ++#define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ + + /* + ** The results of a SELECT can be distributed in several ways, as defined +diff --git a/test/selectA.test b/test/selectA.test +index 838e5f4..2626008 100644 +--- a/test/selectA.test ++++ b/test/selectA.test +@@ -1446,5 +1446,27 @@ do_execsql_test 6.1 { + SELECT * FROM (SELECT a FROM t1 UNION SELECT b FROM t2) WHERE a=a; + } {12345} + ++# 2020-06-15 ticket 8f157e8010b22af0 ++# ++reset_db ++do_execsql_test 7.1 { ++ CREATE TABLE t1(c1); INSERT INTO t1 VALUES(12),(123),(1234),(NULL),('abc'); ++ CREATE TABLE t2(c2); INSERT INTO t2 VALUES(44),(55),(123); ++ CREATE TABLE t3(c3,c4); INSERT INTO t3 VALUES(66,1),(123,2),(77,3); ++ CREATE VIEW t4 AS SELECT c3 FROM t3; ++ CREATE VIEW t5 AS SELECT c3 FROM t3 ORDER BY c4; ++} ++do_execsql_test 7.2 { ++ SELECT * FROM t1, t2 WHERE c1=(SELECT 123 INTERSECT SELECT c2 FROM t4) AND c1=123; ++} {123 123} ++do_execsql_test 7.3 { ++ SELECT * FROM t1, t2 WHERE c1=(SELECT 123 INTERSECT SELECT c2 FROM t5) AND c1=123; ++} {123 123} ++do_execsql_test 7.4 { ++ CREATE TABLE a(b); ++ CREATE VIEW c(d) AS SELECT b FROM a ORDER BY b; ++ SELECT sum(d) OVER( PARTITION BY(SELECT 0 FROM c JOIN a WHERE b =(SELECT b INTERSECT SELECT d FROM c) AND b = 123)) FROM c; ++} {} ++ + + finish_test +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-6405.patch b/SOURCES/sqlite-3.26.0-CVE-2020-6405.patch new file mode 100644 index 0000000..cf1fff5 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-6405.patch @@ -0,0 +1,27 @@ +From 1668926bc3c7da0b2870a60382b179a0e3edb5de Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +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; inConst; i++){ + Expr *pColumn = pConst->apExpr[i*2]; +-- +2.24.1 + diff --git a/SOURCES/sqlite-3.26.0-CVE-2020-9327.patch b/SOURCES/sqlite-3.26.0-CVE-2020-9327.patch new file mode 100644 index 0000000..24b1eb9 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-CVE-2020-9327.patch @@ -0,0 +1,106 @@ +From 2d788539b0018d34d3cabb328387ba6bec41ec42 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +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; iu.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 + diff --git a/SOURCES/sqlite-3.26.0-out-of-bounds-read.patch b/SOURCES/sqlite-3.26.0-out-of-bounds-read.patch new file mode 100644 index 0000000..1edc762 --- /dev/null +++ b/SOURCES/sqlite-3.26.0-out-of-bounds-read.patch @@ -0,0 +1,89 @@ +From eca47c8481b0c2f09a7818ed2bce0ad27b1dae27 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Wed, 26 Jun 2019 12:25:10 +0200 +Subject: [PATCH] Fixed out of bounds heap read in function rtreenode() + + Enhance the rtreenode() function of rtree (used for + testing) so that it uses the newer sqlite3_str object + for better performance and improved error reporting. + Test cases added to TH3. + + Resolves: #1723338 + Version: 3.26.0-4 +--- + ext/rtree/rtree.c | 35 ++++++++++++++++------------------- + 1 file changed, 16 insertions(+), 19 deletions(-) + +diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c +index 4b044cb..87d0de0 100644 +--- a/ext/rtree/rtree.c ++++ b/ext/rtree/rtree.c +@@ -3711,49 +3711,46 @@ rtreeInit_fail: + ** *2 coordinates. + */ + static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ +- char *zText = 0; + RtreeNode node; + Rtree tree; + int ii; ++ int nData; ++ int errCode; ++ sqlite3_str *pOut; + + UNUSED_PARAMETER(nArg); + memset(&node, 0, sizeof(RtreeNode)); + memset(&tree, 0, sizeof(Rtree)); + tree.nDim = (u8)sqlite3_value_int(apArg[0]); ++ if( tree.nDim<1 || tree.nDim>5 ) return; + tree.nDim2 = tree.nDim*2; + tree.nBytesPerCell = 8 + 8 * tree.nDim; + node.zData = (u8 *)sqlite3_value_blob(apArg[1]); ++ nData = sqlite3_value_bytes(apArg[1]); ++ if( nData<4 ) return; ++ if( nData0 ) sqlite3_str_append(pOut, " ", 1); ++ sqlite3_str_appendf(pOut, "{%lld", cell.iRowid); + for(jj=0; jj +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 + diff --git a/SOURCES/sqlite-3.6.23-lemon-system-template.patch b/SOURCES/sqlite-3.6.23-lemon-system-template.patch new file mode 100644 index 0000000..3d3b0aa --- /dev/null +++ b/SOURCES/sqlite-3.6.23-lemon-system-template.patch @@ -0,0 +1,21 @@ +diff -up sqlite-3.6.23/tool/lemon.c.system-template sqlite-3.6.23/tool/lemon.c +--- sqlite-3.6.23/tool/lemon.c.system-template 2010-03-10 16:40:35.000000000 +0200 ++++ sqlite-3.6.23/tool/lemon.c 2010-03-10 16:40:39.000000000 +0200 +@@ -3363,6 +3363,8 @@ PRIVATE FILE *tplt_open(struct lemon *le + tpltname = buf; + }else if( access(templatename,004)==0 ){ + tpltname = templatename; ++ }else if( access("/usr/share/lemon/lempar.c", R_OK)==0){ ++ tpltname = "/usr/share/lemon/lempar.c"; + }else{ + tpltname = pathsearch(lemp->argv0,templatename,0); + } +@@ -3374,7 +3376,7 @@ PRIVATE FILE *tplt_open(struct lemon *le + } + in = fopen(tpltname,"rb"); + if( in==0 ){ +- fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); ++ fprintf(stderr,"Can't open the template file \"%s\".\n",tpltname); + lemp->errorcnt++; + return 0; + } diff --git a/SOURCES/sqlite-3.7.7.1-stupid-openfiles-test.patch b/SOURCES/sqlite-3.7.7.1-stupid-openfiles-test.patch new file mode 100644 index 0000000..101f0d4 --- /dev/null +++ b/SOURCES/sqlite-3.7.7.1-stupid-openfiles-test.patch @@ -0,0 +1,37 @@ +--- sqlite-src-3240000/test/oserror.test.old 2018-06-05 08:40:35.656122573 +0200 ++++ sqlite-src-3240000/test/oserror.test 2018-06-05 08:40:45.614935197 +0200 +@@ -51,20 +51,20 @@ + # a call to getcwd() may fail if there are no free file descriptors. So + # an error may be reported for either open() or getcwd() here. + # +-if {![clang_sanitize_address]} { +- do_test 1.1.1 { +- set ::log [list] +- list [catch { +- for {set i 0} {$i < 20000} {incr i} { sqlite3 dbh_$i test.db -readonly 1 } +- } msg] $msg +- } {1 {unable to open database file}} +- do_test 1.1.2 { +- catch { for {set i 0} {$i < 20000} {incr i} { dbh_$i close } } +- } {1} +- do_re_test 1.1.3 { +- lindex $::log 0 +- } {^os_unix.c:\d+: \(\d+\) (open|getcwd)\(.*test.db\) - } +-} ++#if {![clang_sanitize_address]} { ++# do_test 1.1.1 { ++# set ::log [list] ++# list [catch { ++# for {set i 0} {$i < 20000} {incr i} { sqlite3 dbh_$i test.db -readonly 1 } ++# } msg] $msg ++# } {1 {unable to open database file}} ++# do_test 1.1.2 { ++# catch { for {set i 0} {$i < 20000} {incr i} { dbh_$i close } } ++# } {1} ++# do_re_test 1.1.3 { ++# lindex $::log 0 ++# } {^os_unix.c:\d+: \(\d+\) (open|getcwd)\(.*test.db\) - } ++#} + + + # Test a failure in open() due to the path being a directory. diff --git a/SOURCES/sqlite-3.8.0-percentile-test.patch b/SOURCES/sqlite-3.8.0-percentile-test.patch new file mode 100644 index 0000000..f828fa5 --- /dev/null +++ b/SOURCES/sqlite-3.8.0-percentile-test.patch @@ -0,0 +1,15 @@ +# On i686 arch the removed test fails with result 2749999.50004681 instead of expected +# 2749999.5. This patch is temporary workaround and should be dropped as soon as a valid +# fix is found. + +diff -up sqlite-src-3080002/test/percentile.test.broken sqlite-src-3080002/test/percentile.test +--- sqlite-src-3080002/test/percentile.test.broken 2013-09-16 13:19:53.406004041 +0200 ++++ sqlite-src-3080002/test/percentile.test 2013-09-16 13:20:00.079024945 +0200 +@@ -195,7 +195,6 @@ ifcapable vtab { + foreach {in out} { + 0 0.0 + 100 9999990.0 +- 50 2749999.5 + 10 99999.9 + } { + do_test percentile-2.1.$in { diff --git a/SOURCES/sqlite-3.8.10.1-tcl-regress-tests.patch b/SOURCES/sqlite-3.8.10.1-tcl-regress-tests.patch new file mode 100644 index 0000000..bdeb6da --- /dev/null +++ b/SOURCES/sqlite-3.8.10.1-tcl-regress-tests.patch @@ -0,0 +1,137 @@ +This patch disables a test which caused failed assertion in tcl 8.6.3. +According to sqlite upstream[1], this should be fixed in tcl 8.6.5. + +[1] http://mailinglists.sqlite.org/cgi-bin/mailman/private/sqlite-users/2015-May/059518.html + +diff -up sqlite-src-3130000/test/shell1.test.orig sqlite-src-3130000/test/shell1.test +--- sqlite-src-3140100/test/shell1.test.orig 2016-08-12 02:17:02.000000000 +0200 ++++ sqlite-src-3140100/test/shell1.test 2016-08-15 15:00:59.869664051 +0200 +@@ -855,67 +855,67 @@ do_test shell1-4.6 { + + # Test using arbitrary byte data with the shell via standard input/output. + # +-do_test shell1-5.0 { +- # +- # NOTE: Skip NUL byte because it appears to be incompatible with command +- # shell argument parsing. +- # +- for {set i 1} {$i < 256} {incr i} { +- # +- # NOTE: Due to how the Tcl [exec] command works (i.e. where it treats +- # command channels opened for it as textual ones), the carriage +- # return character (and on Windows, the end-of-file character) +- # cannot be used here. +- # +- if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} { +- continue +- } +- if {$i>=0xE0 && $tcl_platform(os)=="OpenBSD"} continue +- if {$i>=0xE0 && $i<=0xEF && $tcl_platform(os)=="Linux"} continue +- set hex [format %02X $i] +- set char [subst \\x$hex]; set oldChar $char +- set escapes [list] +- if {$tcl_platform(platform)=="windows"} { +- # +- # NOTE: On Windows, we need to escape all the whitespace characters, +- # the alarm (\a) character, and those with special meaning to +- # the SQLite shell itself. +- # +- set escapes [list \ +- \a \\a \b \\b \t \\t \n \\n \v \\v \f \\f \r \\r \ +- " " "\" \"" \" \\\" ' \"'\" \\ \\\\] +- } else { +- # +- # NOTE: On Unix, we need to escape most of the whitespace characters +- # and those with special meaning to the SQLite shell itself. +- # The alarm (\a), backspace (\b), and carriage-return (\r) +- # characters do not appear to require escaping on Unix. For +- # the alarm and backspace characters, this is probably due to +- # differences in the command shell. For the carriage-return, +- # it is probably due to differences in how Tcl handles command +- # channel end-of-line translations. +- # +- set escapes [list \ +- \t \\t \n \\n \v \\v \f \\f \ +- " " "\" \"" \" \\\" ' \"'\" \\ \\\\] +- } +- set char [string map $escapes $char] +- set x [catchcmdex test.db ".print $char\n"] +- set code [lindex $x 0] +- set res [lindex $x 1] +- if {$code ne "0"} { +- error "failed with error: $res" +- } +- if {$res ne "$oldChar\n"} { +- if {[llength $res] > 0} { +- set got [format %02X [scan $res %c]] +- } else { +- set got +- } +- error "failed with byte $hex mismatch, got $got" +- } +- } +-} {} ++#do_test shell1-5.0 { ++# # ++# # NOTE: Skip NUL byte because it appears to be incompatible with command ++# # shell argument parsing. ++# # ++# for {set i 1} {$i < 256} {incr i} { ++# # ++# # NOTE: Due to how the Tcl [exec] command works (i.e. where it treats ++# # command channels opened for it as textual ones), the carriage ++# # return character (and on Windows, the end-of-file character) ++# # cannot be used here. ++# # ++# if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} { ++# continue ++# } ++# if {$i>=0xE0 && $tcl_platform(os)=="OpenBSD"} continue ++# if {$i>=0xE0 && $i<=0xEF && $tcl_platform(os)=="Linux"} continue ++# set hex [format %02X $i] ++# set char [subst \\x$hex]; set oldChar $char ++# set escapes [list] ++# if {$tcl_platform(platform)=="windows"} { ++# # ++# # NOTE: On Windows, we need to escape all the whitespace characters, ++# # the alarm (\a) character, and those with special meaning to ++# # the SQLite shell itself. ++# # ++# set escapes [list \ ++# \a \\a \b \\b \t \\t \n \\n \v \\v \f \\f \r \\r \ ++# " " "\" \"" \" \\\" ' \"'\" \\ \\\\] ++# } else { ++# # ++# # NOTE: On Unix, we need to escape most of the whitespace characters ++# # and those with special meaning to the SQLite shell itself. ++# # The alarm (\a), backspace (\b), and carriage-return (\r) ++# # characters do not appear to require escaping on Unix. For ++# # the alarm and backspace characters, this is probably due to ++# # differences in the command shell. For the carriage-return, ++# # it is probably due to differences in how Tcl handles command ++# # channel end-of-line translations. ++# # ++# set escapes [list \ ++# \t \\t \n \\n \v \\v \f \\f \ ++# " " "\" \"" \" \\\" ' \"'\" \\ \\\\] ++# } ++# set char [string map $escapes $char] ++# set x [catchcmdex test.db ".print $char\n"] ++# set code [lindex $x 0] ++# set res [lindex $x 1] ++# if {$code ne "0"} { ++# error "failed with error: $res" ++# } ++# if {$res ne "$oldChar\n"} { ++# if {[llength $res] > 0} { ++# set got [format %02X [scan $res %c]] ++# } else { ++# set got ++# } ++# error "failed with byte $hex mismatch, got $got" ++# } ++# } ++#} {} + + # These test cases do not work on MinGW + if 0 { diff --git a/SOURCES/sqlite-dont-search-for-pthreads-on-non-unix.patch b/SOURCES/sqlite-dont-search-for-pthreads-on-non-unix.patch new file mode 100644 index 0000000..9cbf776 --- /dev/null +++ b/SOURCES/sqlite-dont-search-for-pthreads-on-non-unix.patch @@ -0,0 +1,11 @@ +--- configure.ac.pthread 2016-02-18 11:40:40.177797402 +0100 ++++ configure.ac 2016-02-18 11:41:34.232609836 +0100 +@@ -193,7 +193,7 @@ + fi + AC_SUBST(SQLITE_THREADSAFE) + +-if test "$SQLITE_THREADSAFE" = "1"; then ++if test "$SQLITE_THREADSAFE" = "1" -a "$SQLITE_OS_UNIX" = "1" ; then + AC_SEARCH_LIBS(pthread_create, pthread) + AC_SEARCH_LIBS(pthread_mutexattr_init, pthread) + fi diff --git a/SOURCES/sqlite-mingw-crosscompile.patch b/SOURCES/sqlite-mingw-crosscompile.patch new file mode 100644 index 0000000..e3f2f49 --- /dev/null +++ b/SOURCES/sqlite-mingw-crosscompile.patch @@ -0,0 +1,20 @@ +--- configure.ac.cc 2016-02-18 11:42:35.868255721 +0100 ++++ configure.ac 2016-02-18 11:42:35.889255260 +0100 +@@ -259,16 +259,7 @@ + if test "$CYGWIN" != "yes"; then + AC_CYGWIN + fi +-if test "$CYGWIN" = "yes"; then +- BUILD_EXEEXT=.exe +-else +- BUILD_EXEEXT=$EXEEXT +-fi +-if test x"$cross_compiling" = xno; then +- TARGET_EXEEXT=$BUILD_EXEEXT +-else +- TARGET_EXEEXT=$config_TARGET_EXEEXT +-fi ++TARGET_EXEEXT=$EXEEXT + if test "$TARGET_EXEEXT" = ".exe"; then + SQLITE_OS_UNIX=0 + SQLITE_OS_WIN=1 diff --git a/SPECS/mingw-sqlite.spec b/SPECS/mingw-sqlite.spec new file mode 100644 index 0000000..0e4d9ad --- /dev/null +++ b/SPECS/mingw-sqlite.spec @@ -0,0 +1,556 @@ +%?mingw_package_header + +%global name1 sqlite + +%global realver 3260000 +%global rpmver 3.26.0.0 + +# bcond default logic is nicely backwards... +%bcond_with tcl +%global tclversion 8.6 + +Name: mingw-%{name1} +Version: %{rpmver} +Release: 1%{?dist} +Summary: MinGW Windows port of sqlite embeddable SQL database engine + +License: Public Domain +Group: Applications/Databases +URL: http://www.sqlite.org/ +Source0: http://www.sqlite.org/2018/%{name1}-src-%{realver}.zip + +BuildArch: noarch +ExclusiveArch: %{ix86} x86_64 + +### Patches are copied from RHEL-8 spec-file ### +# Support a system-wide lemon template +Patch1: sqlite-3.6.23-lemon-system-template.patch +# Shut up stupid tests depending on system settings of allowed open fd's +Patch2: sqlite-3.7.7.1-stupid-openfiles-test.patch +# sqlite >= 3.7.10 is buggy if malloc_usable_size() is detected, disable it: +# https://bugzilla.redhat.com/show_bug.cgi?id=801981 +# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=665363 +Patch3: sqlite-3.12.2-no-malloc-usable-size.patch +# Temporary workaround for failed percentile test, see patch for details +Patch4: sqlite-3.8.0-percentile-test.patch +# Disable test failing due to tcl regression. Details in patch file. +Patch6: sqlite-3.8.10.1-tcl-regress-tests.patch +# Disable test date-2.2c on i686 +Patch7: sqlite-3.16-datetest-2.2c.patch +# Modify sync2.test to pass with DIRSYNC turned off +Patch8: sqlite-3.18.0-sync2-dirsync.patch +# Fix for CVE-2019-8457 (rhbz#1723338) +# https://www.sqlite.org/src/info/90acdbfce9c08858 +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 +# Fix for CVE-2020-13434 +# upstream commit: https://www.sqlite.org/src/info/d08d3405878d394e +Patch26: sqlite-3.26.0-CVE-2020-13434.patch +# Fix for CVE-2020-15358 +# upstream commit: https://www.sqlite.org/src/info/10fa79d00f8091e5 +Patch27: sqlite-3.26.0-CVE-2020-15358.patch + +#end-of-patches-from-RHEL +###################### + + +# mingw specific patches +# Don't try to link against pthreads even if it is available +Patch1001: sqlite-dont-search-for-pthreads-on-non-unix.patch + +# Don't force build exe extension same as target exe extension +Patch1002: sqlite-mingw-crosscompile.patch + +BuildRequires: mingw32-filesystem >= 95 +BuildRequires: mingw32-gcc +BuildRequires: mingw32-binutils +BuildRequires: mingw32-pdcurses +BuildRequires: mingw32-readline +BuildRequires: mingw32-termcap + +BuildRequires: mingw64-filesystem >= 95 +BuildRequires: mingw64-gcc +BuildRequires: mingw64-binutils +BuildRequires: mingw64-pdcurses +BuildRequires: mingw64-readline +BuildRequires: mingw64-termcap + +# For the pthread patch +BuildRequires: autoconf automake libtool + +BuildRequires: /usr/bin/tclsh + +%if %{with tcl} +BuildRequires: /usr/bin/tclsh +BuildRequires: mingw32-tcl +%endif + + +%description +SQLite is a C library that implements an SQL database engine. A large +subset of SQL92 is supported. A complete database is stored in a +single disk file. The API is designed for convenience and ease of use. +Applications that link against SQLite can enjoy the power and +flexibility of an SQL database without the administrative hassles of +supporting a separate database server. Version 2 and version 3 binaries +are named to permit each to be installed on a single host + +This package contains cross-compiled libraries and development tools +for Windows. + + +# Win32 +%package -n mingw32-%{name1} +Summary: MinGW Windows port of sqlite embeddable SQL database engine +Requires: pkgconfig + +%description -n mingw32-%{name1} +SQLite is a C library that implements an SQL database engine. A large +subset of SQL92 is supported. A complete database is stored in a +single disk file. The API is designed for convenience and ease of use. +Applications that link against SQLite can enjoy the power and +flexibility of an SQL database without the administrative hassles of +supporting a separate database server. Version 2 and version 3 binaries +are named to permit each to be installed on a single host + +This package contains cross-compiled libraries and development tools +for Windows. + +%package -n mingw32-%{name1}-static +Summary: Static version of MinGW Windows port of sqlite library +Requires: mingw32-%{name1} = %{version}-%{release} +Group: Development/Libraries + +%description -n mingw32-%{name1}-static +SQLite is a C library that implements an SQL database engine. A large +subset of SQL92 is supported. A complete database is stored in a +single disk file. The API is designed for convenience and ease of use. +Applications that link against SQLite can enjoy the power and +flexibility of an SQL database without the administrative hassles of +supporting a separate database server. Version 2 and version 3 binaries +are named to permit each to be installed on a single host + +This package contains static cross-compiled library + +# Win64 +%package -n mingw64-%{name1} +Summary: MinGW Windows port of sqlite embeddable SQL database engine +Requires: pkgconfig + +%description -n mingw64-%{name1} +SQLite is a C library that implements an SQL database engine. A large +subset of SQL92 is supported. A complete database is stored in a +single disk file. The API is designed for convenience and ease of use. +Applications that link against SQLite can enjoy the power and +flexibility of an SQL database without the administrative hassles of +supporting a separate database server. Version 2 and version 3 binaries +are named to permit each to be installed on a single host + +This package contains cross-compiled libraries and development tools +for Windows. + +%package -n mingw64-%{name1}-static +Summary: Static version of MinGW Windows port of sqlite library +Requires: mingw64-%{name1} = %{version}-%{release} +Group: Development/Libraries + +%description -n mingw64-%{name1}-static +SQLite is a C library that implements an SQL database engine. A large +subset of SQL92 is supported. A complete database is stored in a +single disk file. The API is designed for convenience and ease of use. +Applications that link against SQLite can enjoy the power and +flexibility of an SQL database without the administrative hassles of +supporting a separate database server. Version 2 and version 3 binaries +are named to permit each to be installed on a single host + +This package contains static cross-compiled library + + +%?mingw_debug_package + + +%prep +%setup -q -n %{name1}-src-%{realver} + +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch6 -p1 +%ifarch %{ix86} +%patch7 -p1 +%endif +%patch8 -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 +%patch26 -p1 +%patch27 -p1 + +%patch1001 -p0 -b .pthread +%patch1002 -p0 -b .cc +autoreconf -i --force + + +%build +# I think there's a bug in the configure script where, if +# cross-compiling, it cannot correctly determine the target executable +# extension (ie. .exe). As a result it doesn't correctly detect that +# the target is Windows and so tries to use Unix-specific functions +# which don't exist. In any case we can work around this by forcing +# the extension via this export. +# - RWMJ 2008-09-30 +export config_TARGET_EXEEXT=.exe +# add compile flags to enable rtree, fts3 +export MINGW32_CFLAGS="%{mingw32_cflags} -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_DISABLE_DIRSYNC=1 -DSQLITE_ENABLE_FTS3=3 -DSQLITE_ENABLE_RTREE=1 -fno-strict-aliasing" +export MINGW64_CFLAGS="%{mingw64_cflags} -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_DISABLE_DIRSYNC=1 -DSQLITE_ENABLE_FTS3=3 -DSQLITE_ENABLE_RTREE=1 -fno-strict-aliasing" + +%mingw_configure %{!?with_tcl:--disable-tcl} --enable-load-extension + +# -lc hack +for i in build_win32 build_win64 ; do + pushd $i + sed -e s,build_libtool_need_lc=yes,build_libtool_need_lc=no, < libtool > libtool.x + mv libtool.x libtool + chmod a+x libtool + popd +done + +%mingw_make %{?_smp_mflags} + + +%install +%mingw_make_install DESTDIR=$RPM_BUILD_ROOT + +chmod 0644 $RPM_BUILD_ROOT%{mingw32_libdir}/libsqlite3.dll.a +chmod 0644 $RPM_BUILD_ROOT%{mingw64_libdir}/libsqlite3.dll.a + +%if %{with tcl} +install -d -m755 $RPM_BUILD_ROOT%{mingw32_datadir}/tcl%{tclversion}/sqlite3/ +mv $RPM_BUILD_ROOT%{_datadir}/tcl%{tclversion}/sqlite3/pkgIndex.tcl $RPM_BUILD_ROOT%{mingw32_datadir}/tcl%{tclversion}/sqlite3/ + +install -d -m755 $RPM_BUILD_ROOT%{mingw64_datadir}/tcl%{tclversion}/sqlite3/ +mv $RPM_BUILD_ROOT%{_datadir}/tcl%{tclversion}/sqlite3/pkgIndex.tcl $RPM_BUILD_ROOT%{mingw64_datadir}/tcl%{tclversion}/sqlite3/ +%endif + +# Drop all .la files +find $RPM_BUILD_ROOT -name "*.la" -delete + +# Win32 +%files -n mingw32-%{name1} +%doc README.md VERSION +%{mingw32_bindir}/sqlite3.exe +%{mingw32_bindir}/libsqlite3-0.dll +%{mingw32_libdir}/libsqlite3.dll.a +%{mingw32_includedir}/sqlite3.h +%{mingw32_includedir}/sqlite3ext.h +%{mingw32_libdir}/pkgconfig/sqlite3.pc +%if %{with tcl} +%{mingw32_datadir}/tcl%{tclversion}/sqlite3/ +%{mingw32_datadir}/tcl%{tclversion}/sqlite3/pkgIndex.tcl +%endif + +%files -n mingw32-%{name1}-static +%{mingw32_libdir}/libsqlite3.a + +# Win64 +%files -n mingw64-%{name1} +%doc README.md VERSION +%{mingw64_bindir}/sqlite3.exe +%{mingw64_bindir}/libsqlite3-0.dll +%{mingw64_libdir}/libsqlite3.dll.a +%{mingw64_includedir}/sqlite3.h +%{mingw64_includedir}/sqlite3ext.h +%{mingw64_libdir}/pkgconfig/sqlite3.pc +%if %{with tcl} +%{mingw64_datadir}/tcl%{tclversion}/sqlite3/ +%{mingw64_datadir}/tcl%{tclversion}/sqlite3/pkgIndex.tcl +%endif + +%files -n mingw64-%{name1}-static +%{mingw64_libdir}/libsqlite3.a + + +%changelog + +* Mon Nov 30 2020 Uri Lublin - 3.26.0.0-1 +- Rebase to sqlite 3.26.0 +- Fix CVE-2019-8457 CVE-2019-13752 CVE-2019-13753 CVE-2019-13734 +- Fix CVE-2019-19924 CVE-2019-19923 CVE-2019-19925 CVE-2019-19959 +- Fix CVE-2019-20218 CVE-2020-6405 CVE-2020-9327 CVE-2019-5018 +- Fix CVE-2019-16168 + Resolves: rhbz#1826898 +- Fix CVE-2020-13632 + Resolves: rhbz#1845615 +- Fix CVE-2020-13631 + Resolves: rhbz#1845475 +- Fix CVE-2020-13630 + Resolves: rhbz#1845212 +- Fix CVE-2020-13434 + Resolves: rhbz#1845851 +- Fix CVE-2020-15358 + +* Tue Aug 14 2018 Victor Toso - 3.22.0.0-3 +- ExclusiveArch: i686, x86_64 +- Related: rhbz#1615874 + +* Thu Feb 08 2018 Fedora Release Engineering - 3.22.0.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Jan 23 2018 Thomas Sailer - 3.22.0.0-1 +- update to 3.22.0.0 + +* Thu Aug 24 2017 Thomas Sailer - 3.20.1.0-1 +- update to 3.20.1.0 + +* Wed Aug 02 2017 Thomas Sailer - 3.20.0.0-1 +- update to 3.20.0.0 + +* Wed Jul 26 2017 Fedora Release Engineering - 3.19.3.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Jun 09 2017 Thomas Sailer - 3.19.3.0-1 +- update to 3.19.3.0 + +* Thu May 25 2017 Thomas Sailer - 3.19.1.0-1 +- update to 3.19.1.0 + +* Tue May 23 2017 Thomas Sailer - 3.19.0.0-1 +- update to 3.19.0.0 + +* Fri Mar 31 2017 Thomas Sailer - 3.18.0.0-1 +- update to 3.18.0.0 + +* Tue Feb 14 2017 Thomas Sailer - 3.17.0.0-1 +- update to 3.17.0.0 + +* Fri Feb 10 2017 Fedora Release Engineering - 3.16.2.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Sat Jan 07 2017 Thomas Sailer - 3.16.2.0-1 +- update to 3.16.2.0 + +* Wed Jan 04 2017 Thomas Sailer - 3.16.1.0-1 +- update to 3.16.1.0 + +* Tue Jan 03 2017 Thomas Sailer - 3.16.0.0-1 +- update to 3.16.0.0 + +* Thu Dec 01 2016 Thomas Sailer - 3.15.2.0-1 +- update to 3.15.2.0 + +* Tue Nov 08 2016 Thomas Sailer - 3.15.1.0-1 +- update to 3.15.1.0 + +* Sun Oct 16 2016 Thomas Sailer - 3.15.0.0-1 +- update to 3.15.0.0 + +* Fri Aug 12 2016 Thomas Sailer - 3.14.1.0-1 +- update to 3.14.1.0 + +* Tue Apr 19 2016 Thomas Sailer - 3.12.2.0-1 +- update to 3.12.2.0 + +* Sun Apr 10 2016 Thomas Sailer - 3.12.1.0-1 +- update to 3.12.1.0 + +* Wed Mar 30 2016 Thomas Sailer - 3.12.0.0-1 +- update to 3.12.0.0 + +* Fri Mar 04 2016 Thomas Sailer - 3.11.1.0-1 +- update to 3.11.1.0 + +* Thu Feb 18 2016 Thomas Sailer - 3.11.0.0-1 +- update to 3.11.0.0 + +* Thu Feb 04 2016 Fedora Release Engineering - 3.10.2.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Jan 21 2016 Thomas Sailer - 3.10.2.0-1 +- update to 3.10.2.0 + +* Thu Jan 14 2016 Thomas Sailer - 3.10.1.0-1 +- update to 3.10.1.0 + +* Wed Jun 17 2015 Fedora Release Engineering - 3.8.4.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 3.8.4.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu May 29 2014 Erik van Pienbroek - 3.8.4.3-1 +- Update to 3.8.4.3 + +* Sat Jan 25 2014 Erik van Pienbroek - 3.8.2-1 +- Update to 3.8.2 + +* Wed Nov 20 2013 Erik van Pienbroek - 3.8.1-1 +- Update to 3.8.1 + +* Sat Aug 03 2013 Fedora Release Engineering - 3.7.17-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Sat Jun 15 2013 Erik van Pienbroek - 3.7.17-2 +- Rebuild to resolve InterlockedCompareExchange regression in mingw32 libraries + +* Sun Jun 2 2013 Thomas Sailer - 3.7.17-1 +- update to 3.7.17 + +* Sun May 12 2013 Erik van Pienbroek - 3.7.16.2-2 +- Don't try to link against pthreads even if it is available on win32 + (sqlite uses the native win32 threading API already) + +* Mon May 6 2013 Thomas Sailer - 3.7.16.2-1 +- update to 3.7.16.2 + +* Sun Mar 24 2013 Erik van Pienbroek - 3.7.16-1 +- Update to 3.7.16 + +* Sun Mar 3 2013 Thomas Sailer - 3.7.15.2-1 +- Update to 3.7.15.2 + +* Thu Feb 14 2013 Fedora Release Engineering - 3.7.14.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Thu Dec 6 2012 Erik van Pienbroek - 3.7.14.1-1 +- Update to 3.7.14.1 +- Dropped all patches which are not needed for the mingw target +- There's no need to re-run the autotools any more + +* Tue Dec 4 2012 Thomas Sailer - 3.7.13-1 +- update to 3.7.13 + +* Fri Jul 20 2012 Fedora Release Engineering - 3.7.9-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sun Apr 22 2012 Erik van Pienbroek - 3.7.9-6 +- Add BR: mingw64-pdcurses + +* Sat Mar 10 2012 Erik van Pienbroek - 3.7.9-5 +- Added win64 support + +* Fri Mar 09 2012 Erik van Pienbroek - 3.7.9-4 +- Dropped .la files + +* Tue Mar 06 2012 Kalev Lember - 3.7.9-3 +- Renamed the source package to mingw-sqlite (#800450) +- Modernize the spec file +- Use mingw macros without leading underscore + +* Mon Feb 27 2012 Erik van Pienbroek - 3.7.9-2 +- Rebuild against the mingw-w64 toolchain + +* Mon Jan 16 2012 Thomas Sailer - 3.7.9-1 +- update to 3.7.9 + +* Fri Jan 13 2012 Fedora Release Engineering - 3.7.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Sat Dec 24 2011 Ivan Romanov - 3.7.5-2 +- static subpackage + +* Sun Feb 13 2011 Thomas Sailer - 3.7.5-1 +- update to 3.7.5 + +* Tue Feb 08 2011 Fedora Release Engineering - 3.7.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Dec 6 2010 Thomas Sailer - 3.7.3-1 +- update to 3.7.3 + +* Sun Jan 31 2010 Thomas Sailer - 3.6.22-1 +- update to 3.6.22 + +* Sun Dec 6 2009 Thomas Sailer - 3.6.20-1 +- update to 3.6.20 + +* Sun Sep 20 2009 Thomas Sailer - 3.6.17-1 +- update to 3.6.17 + +* Sat Jul 25 2009 Fedora Release Engineering - 3.6.14.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Jun 23 2009 Thomas Sailer - 3.6.14.2-1 +- update to 3.6.14.2 +- add debuginfo packages + +* Thu Apr 23 2009 Thomas Sailer - 3.6.12-4 +- fix CFLAGS setting + +* Thu Apr 23 2009 Thomas Sailer - 3.6.12-3 +- use Erik van Pienbroek way to add to CFLAGS + +* Thu Apr 23 2009 Thomas Sailer - 3.6.12-2 +- BR tclsh; the build process without tclsh and with extensions + enabled is broken + +* Thu Apr 23 2009 Thomas Sailer - 3.6.12-1 +- update to 3.6.12 to match native +- enable rtree, fts3 + +* Wed Feb 25 2009 Fedora Release Engineering - 3.6.6.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Feb 20 2009 Richard W.M. Jones - 3.6.6.2-2 +- Rebuild for mingw32-gcc 4.4 + +* Tue Dec 16 2008 Richard Jones - 3.6.6.2-1 +- New upstream release (to match Fedora native), 3.6.6.2. +- Replace patches with ones from native. +- Rebase -no-undefined patch. +- Remove spurious +x permissions on libsqlite3.dll.a. +- Requires pkgconfig. + +* Sat Nov 22 2008 Richard Jones - 3.5.9-3 +- Rebuild against new readline. + +* Fri Oct 31 2008 Richard Jones - 3.5.9-2 +- Rebuild against latest termcap. + +* Thu Sep 25 2008 Richard Jones - 3.5.9-1 +- Initial RPM release.