From 3043b53222c647a5d971f6fce5df980aa71b637d Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Dec 2016 17:40:14 +0000 Subject: [PATCH] Fix a crash that could occur following an OOM in the group_concat() function if the second argument is an SQLITE_BLOB value. FossilOrigin-Name: 14d855d2b2b5b3485e0673d11405db7266b34c6d --- manifest | 19 ++++++++------- manifest.uuid | 2 +- src/func.c | 2 +- test/gcfault.test | 56 ++++++++++++++++++++++++++++++++++++++++++++ test/instr.test | 9 +++++++ test/instrfault.test | 24 +++++++++++++++++++ 6 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 test/gcfault.test diff --git a/manifest b/manifest index cb748fb07e..0b232f2882 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Strengthen\sthe\sdefense\sagainst\sOOM\sin\sthe\sinstr()\sSQL\sfunction. -D 2016-12-30T15:16:20.650 +C Fix\sa\scrash\sthat\scould\soccur\sfollowing\san\sOOM\sin\sthe\sgroup_concat()\sfunction\nif\sthe\ssecond\sargument\sis\san\sSQLITE_BLOB\svalue. +D 2016-12-30T17:40:14.373 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -344,7 +344,7 @@ F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 F src/expr.c a90e37bc542abe33890cafccacbf8a7db9cb5401 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae -F src/func.c 00cd42119843ab0730fac5ae35fc09f344b08259 +F src/func.c d8582ee91975975645f206db332c38f534b783ad F src/global.c dcdb89f30b7aa531c5660030af106bc5bc48ef2e F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -825,6 +825,7 @@ F test/fuzzdata5.db 9f0cdcc5c6e83b90cf9ae343bd07f684d2da2de7 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 +F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 @@ -865,8 +866,8 @@ F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 F test/insert4.test a20432f1c0fbbcff8f11d0e6ab4acb8c9db58023 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 -F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 -F test/instrfault.test aa90b7c3486a069151b28384ae525644a1f79d51 +F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba +F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a F test/intarray.test 46d95b457916638c5d8b1af21fb174804b3acf8b F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054 F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d @@ -1540,7 +1541,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 0bdbe49c6d392c4c86a6c01219c9d91d150dea7d -R 08bfc0b07daab66cd8d9a28810d0ff87 -U drh -Z 6b0be7f43941c0b0506a1dbb2af0a32d +P a0971e713682a73d8c7c20511db256c20d2f6388 +R b2119513a85656f5ab1ba46bed3bca22 +U dan +Z b8d94ab9819b45ed8f5f9b27f33e84f7 diff --git a/manifest.uuid b/manifest.uuid index 674c29ed2a..c1f02179dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a0971e713682a73d8c7c20511db256c20d2f6388 \ No newline at end of file +14d855d2b2b5b3485e0673d11405db7266b34c6d \ No newline at end of file diff --git a/src/func.c b/src/func.c index 1f80392ba9..4afb25ad6f 100644 --- a/src/func.c +++ b/src/func.c @@ -1634,7 +1634,7 @@ static void groupConcatStep( zSep = ","; nSep = 1; } - if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); + if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); } zVal = (char*)sqlite3_value_text(argv[0]); nVal = sqlite3_value_bytes(argv[0]); diff --git a/test/gcfault.test b/test/gcfault.test new file mode 100644 index 0000000000..d54b78fafc --- /dev/null +++ b/test/gcfault.test @@ -0,0 +1,56 @@ +# 2016 December 30 +# +# 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. The +# focus of this file is testing OOM error handling within the built-in +# group_concat() function. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix gcfault + + +foreach {enc} { + utf16 + utf8 +} { + reset_db + sqlite3_db_config_lookaside db 0 0 0 + execsql "PRAGMA encoding = $enc" + + do_execsql_test 1.$enc.1 { + CREATE TABLE s(i, s); + INSERT INTO s VALUES(1, ',0123456789,'); + INSERT INTO s VALUES(2, X'2c303132333435363738392c'); + + CREATE TABLE e(e); + INSERT INTO e VALUES('v1'), ('v2'); + } {} + + do_faultsim_test 1.$enc.1 -faults oom* -body { + execsql { SELECT group_concat(e, (SELECT s FROM s WHERE i=1)) FROM e } + } + + do_faultsim_test 1.$enc.2 -faults oom-t* -body { + execsql { SELECT group_concat(e, (SELECT s FROM s WHERE i=2)) FROM e } + } + + do_faultsim_test 1.$enc.3 -faults oom-t* -prep { + set ::STMT [sqlite3_prepare db {SELECT group_concat(e, ?) FROM e} -1 dummy] + sqlite3_bind_text $::STMT 1 ",0123456789," 12 + } -body { + while { "SQLITE_ROW"==[sqlite3_step $::STMT] } { } + } -test { + sqlite3_finalize $::STMT + } +} + +finish_test diff --git a/test/instr.test b/test/instr.test index c8be4862b9..2caf3bce3b 100644 --- a/test/instr.test +++ b/test/instr.test @@ -248,4 +248,13 @@ do_execsql_test instr-1.62 { SELECT coalesce(instr(NULL,NULL), 999); } {999} +do_execsql_test instr-1.63 { + SELECT instr(X'', 'abc') +} 0 +do_execsql_test instr-1.64 { + CREATE TABLE x1(a, b); + INSERT INTO x1 VALUES(X'', 'abc'); + SELECT instr(a, b) FROM x1; +} 0 + finish_test diff --git a/test/instrfault.test b/test/instrfault.test index e2d93e742d..0ddb12c84b 100644 --- a/test/instrfault.test +++ b/test/instrfault.test @@ -29,6 +29,8 @@ foreach {enc} { utf16 } { reset_db + sqlite3_db_config_lookaside db 0 0 0 + execsql "PRAGMA encoding = $enc" do_execsql_test 1.$enc.1 { CREATE TABLE t1(n, h); @@ -63,6 +65,28 @@ foreach {enc} { faultsim_test_result {0 31} sqlite3_finalize $::stmt } + + do_faultsim_test 1.$enc.4 -faults oom-t* -prep { + set ::stmt [sqlite3_prepare_v2 db "SELECT instr(?, ?)" -1 dummy] + sqlite3_bind_blob $::stmt 1 $::HAYSTACK [string length $::HAYSTACK] + sqlite3_bind_text $::stmt 2 $::NEEDLE [string length $::NEEDLE] + } -body { + set rc [sqlite3_step $::stmt] + if {$rc=="SQLITE_NOMEM"} { error "out of memory" } + sqlite3_column_int $::stmt 0 + } -test { + faultsim_test_result {0 31} + sqlite3_finalize $::stmt + } + + do_execsql_test 1.$enc.5.0 { + CREATE TABLE h1(a, b); + INSERT INTO h1 VALUES('abcdefg%200hijkl', randomblob(200)); + INSERT INTO h1 SELECT b, a FROM h1; + } + do_faultsim_test 1.$enc.5 -faults oom-t* -body { + execsql { SELECT rowid FROM h1 WHERE instr(a,b) } + } -test {} } finish_test