From: drh Date: Sat, 14 Dec 2019 19:55:31 +0000 (+0000) Subject: When a generated column expression is initially parsed, if it contains errors X-Git-Tag: version-3.31.0~220 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7e3f135c62422bb3e2ad0df53541c09449065099;p=thirdparty%2Fsqlite.git When a generated column expression is initially parsed, if it contains errors convert the expression to a simple NULL. This prevents additional pieces of the expression tree that are allocated from lookaside from leaking into the schema, where lookaside allocations are not allowed. FossilOrigin-Name: a89b38605661e36d192df1d074383b704b34a959fcbc169837c0d4f6848f3208 --- diff --git a/manifest b/manifest index d4736b0b01..07e3258efd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Due\sto\sthe\sprevious\schange,\sthe\sp5\sparameter\sto\sOP_VColumn\sno\slonger\sever\ncontains\sextraneous\sbits,\sso\schange\sa\stestcase()\sinto\san\sassert()\sto\sshow\nas\smuch. -D 2019-12-14T18:08:22.047 +C When\sa\sgenerated\scolumn\sexpression\sis\sinitially\sparsed,\sif\sit\scontains\serrors\nconvert\sthe\sexpression\sto\sa\ssimple\sNULL.\s\sThis\sprevents\sadditional\spieces\sof\nthe\sexpression\stree\sthat\sare\sallocated\sfrom\slookaside\sfrom\sleaking\sinto\sthe\nschema,\swhere\slookaside\sallocations\sare\snot\sallowed. +D 2019-12-14T19:55:31.349 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -471,7 +471,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c d22498af716953400e314d2d98d1dac3ea5c3b01e0fd243ef9e9b132c74114ec F src/btree.h f27a33c49280209a93385e218306c4ee5f46ba8d7649d2f81a7166b282232484 F src/btreeInt.h 91806f01fd1145a9a86ba3042f25c38d8faf6002701bf5e780742cf88bcff437 -F src/build.c 7c277ccc24c249b84f29ba829b0ed377e78487c93d17d999798641be0c20fad5 +F src/build.c 9a08209f438b5cbc9795ed34430553288944593aa1221325529e67e3c3449143 F src/callback.c 88615dfc0a82167b65b452b4b305dbf86be77200b3343c6ffc6d03e92a01d181 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251 @@ -1022,7 +1022,7 @@ F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c -F test/gencol1.test 1cd2b6cfd3ba0a9fe12569db5bcd8972cb83f81586121e8d769905f3b3612879 +F test/gencol1.test 38d90883d0b22ffe8690ecbccf8e6227ece3e380fbbeb4aaed7015a1bd1d9fa4 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/having.test e4098a4b8962f9596035c3b87a8928a10648acc509f1bb8d6f96413bbf79a1b3 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 @@ -1852,7 +1852,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 2401e04730a156aa48787b91af4e516406cb7635145e430be62fd16481816237 -R 6e927ffe1bc60c5e48f827a09022214f +P 5b4a88cd3b3a32b1242e0eb733cc0bc4becb830a887b8e6604a4c7452050e163 +R 2ce3068a1d1623c8a21d7c464aff2e08 U drh -Z e4acfaf148e07535ac807ca90a087964 +Z ed637028b5830da71aa8a6716a5eba7f diff --git a/manifest.uuid b/manifest.uuid index 6cda219371..b8e530c15c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b4a88cd3b3a32b1242e0eb733cc0bc4becb830a887b8e6604a4c7452050e163 \ No newline at end of file +a89b38605661e36d192df1d074383b704b34a959fcbc169837c0d4f6848f3208 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 171cc68cf4..f84eda2a82 100644 --- a/src/build.c +++ b/src/build.c @@ -2252,10 +2252,19 @@ void sqlite3EndTable( for(ii=0; iinCol; ii++){ u32 colFlags = p->aCol[ii].colFlags; if( (colFlags & COLFLAG_GENERATED)!=0 ){ + Expr *pX = p->aCol[ii].pDflt; testcase( colFlags & COLFLAG_VIRTUAL ); testcase( colFlags & COLFLAG_STORED ); - sqlite3ResolveSelfReference(pParse, p, NC_GenCol, - p->aCol[ii].pDflt, 0); + if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){ + /* If there are errors in resolving the expression, change the + ** expression to a NULL. This prevents code generators that operate + ** on the expression from inserting extra parts into the expression + ** tree that have been allocated from lookaside memory, which is + ** illegal in a schema and will lead to errors heap corruption when + ** the database connection closes. */ + sqlite3ExprDelete(db, pX); + p->aCol[ii].pDflt = sqlite3ExprAlloc(db, TK_NULL, 0, 0); + } }else{ nNG++; } diff --git a/test/gencol1.test b/test/gencol1.test index 8d3ba648d0..0867844798 100644 --- a/test/gencol1.test +++ b/test/gencol1.test @@ -382,6 +382,41 @@ do_catchsql_test gencol1-14.10 { INSERT INTO t0 VALUES(2); } {1 {UNIQUE constraint failed: t0.c1}} - +# 2019-12-14 gramfuzz1 find +# The schema is malformed in that it has a subquery on a generated +# column expression. This will be loaded if writable_schema=ON. SQLite +# must not use such an expression during code generation as the code generator +# will add bits of content to the expression tree that might be allocated +# from lookaside. But the schema is not tied to a particular database +# connection, so the use of lookaside memory is prohibited. The fix +# is to change the generated column expression to NULL before adding it +# to the schema. +# +reset_db +do_test gencol1-15.10 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 8192 pagesize 4096 filename c27.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................ +| 96: 00 2e 3f d8 0d 00 00 00 01 0f ba 00 0f ba 00 00 ..?............. +| 4016: 00 00 00 00 00 00 00 00 00 00 44 01 06 17 11 11 ..........D..... +| 4032: 01 75 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 .utablet1t1.CREA +| 4048: 54 45 20 54 41 42 4c 45 20 74 31 28 61 20 49 4e TE TABLE t1(a IN +| 4064: 54 2c 20 62 20 41 53 28 28 56 41 4c 55 45 53 28 T, b AS((VALUES( +| 4080: 31 29 29 20 49 53 20 75 6e 6b 6e 6f 77 6e 29 29 1)) IS unknown)) +| page 2 offset 4096 +| 0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 ................ +| end c27.db +}]} {} +do_execsql_test gencol1-15.20 { + PRAGMA writable_schema=ON; + REPLACE INTO t1 VALUES(9); + SELECT a, quote(b) FROM t1 +} {9 NULL} finish_test