From a51297200ff4c6825e299fab8f9debf25c3e6207 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 3 May 2019 18:50:24 +0000 Subject: [PATCH] Fix a memory-leak/segfault caused by using OP_OpenDup and OP_OpenEphemeral on the same VM cursor. FossilOrigin-Name: a9b90aa12eecdd9f2a8b2d23da8b7cac43d8b1789f5cefa3f4e939d9f2b59269 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 7 +++++-- test/with3.test | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4adcf5eb1e..e6797fc705 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swhere\sself-joins\son\sviews\sthat\sare\saggregate\squeries\smay\sreturn\sthe\swrong\sresult. -D 2019-05-03T17:19:10.246 +C Fix\sa\smemory-leak/segfault\scaused\sby\susing\sOP_OpenDup\sand\sOP_OpenEphemeral\son\sthe\ssame\sVM\scursor. +D 2019-05-03T18:50:24.588 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,7 +591,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 36993059b87e7c2adf671aaa4ef5e0f826b6f4d95be15b019aee14308f0047b5 +F src/vdbe.c 81aa6fe0b7eb6ecd05b04f7a4097cc188ba3a6b4944e9ff418331d4f026cac69 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 F src/vdbeapi.c 5ef992332225d8b6151137fcaf33b4ba4d38db7e7c51f871d2e9ecb960f3709a @@ -1705,7 +1705,7 @@ F test/windowerr.test 675b5e6debfc9370bfacb0b91e2a93a8923512f92600b16f4ea70a1cd9 F test/windowfault.test 16e906a2c4110c88372ff4bd5de59ac7397ec2f025912eff8e5677eedd126898 F test/with1.test a07b5aad7f77acdf13e52e8814ea94606fcc72e9ea4c99baf293e9d7c63940be F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab -F test/with3.test 8d26920c88283e0a473ceebd3451554922108ce7b2a6a1157c47eb0a7011212c +F test/with3.test b5f1372097690c6ef84db2f13fc7e64a88c7263c3f88493605f90597e8a68d45 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 F test/without_rowid1.test 7ac016d20317e36a2f142e960679e558e74f6809ce5f27bde668af01782500df @@ -1822,7 +1822,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 9b5d943426c9273162ecb4c561eb3b25e843318dd438239c882c9db50f788454 -R 3a762b6259a99ea92c807013215a2169 +P 74ef97bf51dd531a277cf22fa4d42043d93799d5a5bd550812648834460fe0b7 +R 5407b1be905c1bcf46d2ef60d3252201 U dan -Z a881ecc4521ccc109413c9747ca34901 +Z efe7ecc358ec0708b5835450f237d48e diff --git a/manifest.uuid b/manifest.uuid index 10ef7c5bdf..99fae280f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74ef97bf51dd531a277cf22fa4d42043d93799d5a5bd550812648834460fe0b7 \ No newline at end of file +a9b90aa12eecdd9f2a8b2d23da8b7cac43d8b1789f5cefa3f4e939d9f2b59269 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 9bc5e4ee56..93297418b3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -256,7 +256,7 @@ static VdbeCursor *allocateCursor( ** is clear. Otherwise, if this is an ephemeral cursor created by ** OP_OpenDup, the cursor will not be closed and will still be part ** of a BtShared.pCursor list. */ - p->apCsr[iCur]->isEphemeral = 0; + if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0; sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } @@ -3710,7 +3710,10 @@ case OP_OpenEphemeral: { if( pCx ){ /* If the ephermeral table is already open, erase all existing content ** so that the table is empty again, rather than creating a new table. */ - rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); + assert( pCx->isEphemeral ); + if( pCx->pBtx ){ + rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); + } }else{ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; diff --git a/test/with3.test b/test/with3.test index 0f49f06859..360d37f9b9 100644 --- a/test/with3.test +++ b/test/with3.test @@ -130,4 +130,40 @@ do_eqp_test 3.2.2 { `--SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?) } +do_execsql_test 4.0 { + WITH t5(t5col1) AS ( + SELECT ( + WITH t3(t3col1) AS ( + WITH t2 AS ( + WITH t1 AS (SELECT 1 AS c1 GROUP BY 1) + SELECT a.c1 FROM t1 AS a, t1 AS b + WHERE anoncol1 = 1 + ) + SELECT (SELECT 1 FROM t2) FROM t2 + ) + SELECT t3col1 FROM t3 WHERE t3col1 + ) FROM (SELECT 1 AS anoncol1) + ) + SELECT t5col1, t5col1 FROM t5 +} {1 1} +do_execsql_test 4.1 { + SELECT EXISTS ( + WITH RECURSIVE Table0 AS ( + WITH RECURSIVE Table0(Col0) AS (SELECT ALL 1 ) + SELECT ALL ( + WITH RECURSIVE Table0 AS ( + WITH RECURSIVE Table0 AS ( + WITH RECURSIVE Table0 AS (SELECT DISTINCT 1 GROUP BY 1 ) + SELECT DISTINCT * FROM Table0 NATURAL INNER JOIN Table0 + WHERE Col0 = 1 + ) + SELECT ALL (SELECT DISTINCT * FROM Table0) FROM Table0 WHERE Col0 = 1 + ) + SELECT ALL * FROM Table0 NATURAL INNER JOIN Table0 + ) FROM Table0 ) + SELECT DISTINCT * FROM Table0 NATURAL INNER JOIN Table0 + ); +} {1} + + finish_test