]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make window range queries more robust against corrupt database files.
authordrh <>
Sat, 24 Apr 2021 23:40:05 +0000 (23:40 +0000)
committerdrh <>
Sat, 24 Apr 2021 23:40:05 +0000 (23:40 +0000)
dbsqlfuzz f22df3a7b2aab0937a415484514fc2f68a293c99.

FossilOrigin-Name: 506333742103c1f440db5da819a36f3b518f7b49e94a7b74419b02bbcadc5a78

manifest
manifest.uuid
src/window.c
test/fuzzdata8.db

index dda2d26af2ec462f89a3ad24e7c81cd794a715e5..9c94a08655c542df4ff2f57cf310283077b11b5f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Treat\sbyte-order\smarks\s(BOMs)\sat\sthe\sstart\sof\sa\stoken\sas\swhitespace.\nThis\senhancement\sis\sinspired\sby\n[forum:/forumpost/ed8f696a20|forum\spost\sed8f696a20].
-D 2021-04-24T12:24:08.900
+C Make\swindow\srange\squeries\smore\srobust\sagainst\scorrupt\sdatabase\sfiles.\ndbsqlfuzz\sf22df3a7b2aab0937a415484514fc2f68a293c99.
+D 2021-04-24T23:40:05.083
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -634,7 +634,7 @@ F src/where.c cb76c17d0bded653040cb16e2f4532fa7b20f5f8c205f4078d346562821107a2
 F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4
 F src/wherecode.c 992bf0d7520bffd345472fb9bc83a1ca0134e46d9e904879bb21e1e77957fcc3
 F src/whereexpr.c d8cafcf6781cf871082f04d7540862cf0fe30cb381dd1b2145a380376364fe8e
-F src/window.c ae9fbd0cbaa39e1b384c13289ed769f9981383bde7b2f262c70ad6c42e5ab226
+F src/window.c 35b14e7a53fe0472b42679919c474de3a5b5c1615fe90a2c41431f37e4ede1be
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
 F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7
@@ -1057,7 +1057,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2
-F test/fuzzdata8.db eb5547e7aa31b689ede8d23c038e5150d319ae80deb2bdf596afe1cc1be5fb3d
+F test/fuzzdata8.db cb843f55a3ab450c0ae82cb86731019f8180a0bd59de9f3656cfff5d6ba7a0a7
 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
@@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 32255e39cbde65492d88177464cee9e10cb20cf3105208416be131e2c89b63e1
-R 1d0e571ef291122bdf317bcd3d07015b
+P 3d55c21c167631f42d155aadec544e629bd078de9992aa5a74694d08bc52052b
+R 046b16c6ecc6c0794b90790e7eea9c3c
 U drh
-Z 9d760c4ee05493d61d6146a0ceb36fa0
+Z e9d04fc2504496c7597cf6435acf852a
index 5733a0c5918f5003527b601d67890814ded07281..320919c0647f37daec26feb1c14b30322308ae24 100644 (file)
@@ -1 +1 @@
-3d55c21c167631f42d155aadec544e629bd078de9992aa5a74694d08bc52052b
\ No newline at end of file
+506333742103c1f440db5da819a36f3b518f7b49e94a7b74419b02bbcadc5a78
\ No newline at end of file
index ad3b47dad4b332c7c0e8d37ec8516402ba859176..61e57cf374859e692d7df450220ac462b7c151c5 100644 (file)
@@ -1570,6 +1570,7 @@ struct WindowCodeArg {
   int regGosub;              /* Register used with OP_Gosub(addrGosub) */
   int regArg;                /* First in array of accumulator registers */
   int eDelete;               /* See above */
+  int regRowid;
 
   WindowCsrAndReg start;
   WindowCsrAndReg current;
@@ -2246,16 +2247,24 @@ static int windowCodeOp(
   /* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or
   ** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the 
   ** start cursor does not advance past the end cursor within the 
-  ** temporary table. It otherwise might, if (a>b).  */
+  ** temporary table. It otherwise might, if (a>b). Also ensure that,
+  ** if the input cursor is still finding new rows, that the end
+  ** cursor does not go past it to EOF. */
   if( pMWin->eStart==pMWin->eEnd && regCountdown
-   && pMWin->eFrmType==TK_RANGE && op==WINDOW_AGGINVERSE
+   && pMWin->eFrmType==TK_RANGE
   ){
     int regRowid1 = sqlite3GetTempReg(pParse);
     int regRowid2 = sqlite3GetTempReg(pParse);
-    sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1);
-    sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2);
-    sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1);
-    VdbeCoverage(v);
+    if( op==WINDOW_AGGINVERSE ){
+      sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1);
+      sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2);
+      sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1);
+      VdbeCoverage(v);
+    }else if( p->regRowid ){
+      sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid1);
+      sqlite3VdbeAddOp3(v, OP_Ge, p->regRowid, lblDone, regRowid1);
+      VdbeCoverage(v);
+    }
     sqlite3ReleaseTempReg(pParse, regRowid1);
     sqlite3ReleaseTempReg(pParse, regRowid2);
     assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING );
@@ -2752,7 +2761,6 @@ void sqlite3WindowCodeStep(
   int addrEmpty;                  /* Address of OP_Rewind in flush: */
   int regNew;                     /* Array of registers holding new input row */
   int regRecord;                  /* regNew array in record form */
-  int regRowid;                   /* Rowid for regRecord in eph table */
   int regNewPeer = 0;             /* Peer values for new row (part of regNew) */
   int regPeer = 0;                /* Peer values for current row */
   int regFlushPart = 0;           /* Register for "Gosub flush_partition" */
@@ -2824,7 +2832,7 @@ void sqlite3WindowCodeStep(
   regNew = pParse->nMem+1;
   pParse->nMem += nInput;
   regRecord = ++pParse->nMem;
-  regRowid = ++pParse->nMem;
+  s.regRowid = ++pParse->nMem;
 
   /* If the window frame contains an "<expr> PRECEDING" or "<expr> FOLLOWING"
   ** clause, allocate registers to store the results of evaluating each
@@ -2880,9 +2888,9 @@ void sqlite3WindowCodeStep(
   }
 
   /* Insert the new row into the ephemeral table */
-  sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid);
-  sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid);
-  addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid);
+  sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, s.regRowid);
+  sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, s.regRowid);
+  addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, s.regRowid);
   VdbeCoverageNeverNull(v);
 
   /* This block is run for the first row of each partition */
@@ -3000,6 +3008,7 @@ void sqlite3WindowCodeStep(
     sqlite3VdbeJumpHere(v, addrGosubFlush);
   }
 
+  s.regRowid = 0;
   addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
   VdbeCoverage(v);
   if( pMWin->eEnd==TK_PRECEDING ){
index 92bd92d253e90652ee64b48380eda5111135a3e1..6f9754a2ec655467e30ee2b6b0bdf700cda2a3ad 100644 (file)
Binary files a/test/fuzzdata8.db and b/test/fuzzdata8.db differ