From 4b2f9368cbbc9a26e8dcbcb87791267c10d14f50 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Jan 2008 23:37:09 +0000 Subject: [PATCH] Improved test coverage for the tokenizer and sqlite3_complete() interface. Fix bugs in parsing blob literals and SQL variables beginning with $. (CVS 4743) FossilOrigin-Name: c82033faf8bdb83ce43f0dd1611408e7796d53de --- manifest | 22 ++++---- manifest.uuid | 2 +- src/parse.y | 10 ++-- src/test_config.c | 4 +- src/tokenize.c | 17 ++---- test/blob.test | 8 +-- test/main.test | 141 +++++++++++++++++++++++++++++++++++++++++++--- tool/lempar.c | 3 +- 8 files changed, 165 insertions(+), 42 deletions(-) diff --git a/manifest b/manifest index 93b350a257..54b3b13c8b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sfault\sinjector\smodule\sin\sfault.c.\s\sUse\sit\sas\sa\sbasis\sfor\smemory\nallocation\sfailure\stesting.\s(CVS\s4742) -D 2008-01-22T21:30:53 +C Improved\stest\scoverage\sfor\sthe\stokenizer\sand\ssqlite3_complete()\sinterface.\nFix\sbugs\sin\sparsing\sblob\sliterals\sand\sSQL\svariables\sbeginning\swith\s$.\s(CVS\s4743) +D 2008-01-22T23:37:10 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in bc2b5df3e3d0d4b801b824b7ef6dec43812b049b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -127,7 +127,7 @@ F src/os_win.c c832d528ea774c7094d887749d71884984c9034c F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c d8c2f06c3ce225dd14816cd02f07d7c65aff1f53 F src/pager.h f504f7ae84060fee0416a853e368d3d113c3d6fa -F src/parse.y bcc6092d2577f4b525e09928b3ed164965e35c54 +F src/parse.y 00f2698c8ae84f315be5e3f10b63c94f531fdd6d F src/pragma.c 2bb8d6882b9a330e041acd05fb6aff5a01bf0a08 F src/prepare.c 05433874e7f161124d29877f83d246efb3a10dd7 F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910 @@ -153,7 +153,7 @@ F src/test9.c b46c8fe02ac7cca1a7316436d8d38d50c66f4b2f F src/test_async.c 5f21392d66869a4c87dc9153e40d0dc0e085261f F src/test_autoext.c 855157d97aa28cf84233847548bfacda21807436 F src/test_btree.c c1308ba0b88ab577fa56c9e493a09829dfcded9c -F src/test_config.c c0917656ada90c4aa23c52d1ade39815a930ee18 +F src/test_config.c a3ac9faf2e3c032bb0bdb9e3f2fd36a1e17a6cce F src/test_devsym.c 6341971bf1c7769c740501b36bc6192cd975c335 F src/test_hexio.c 1a1cd8324d57585ea86b922f609fa1fbaaf9662d F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8 @@ -164,7 +164,7 @@ F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f F src/test_server.c a6ece6c835e7eae835054124e09e947e422b1ac5 F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59 F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730 -F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48 +F src/tokenize.c c4b79fd48ddb709b2b8522b7d93a5a3d98168ca4 F src/trigger.c 9bd3b6fa0beff4a02d262c96466f752ec15a7fc3 F src/update.c 31edd9c9764e80753930bd5f9b43e0edb404636f F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736 @@ -209,7 +209,7 @@ F test/bigfile.test 9a6a8346e4042d9c781ed6cb6553ac871ae30618 F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 F test/bind.test 261fd1603613e7f877a516d29f281c9d8c2ecf52 F test/bindxfer.test b9a57f66dbd317feeefa28bd65b6576f1592ee98 -F test/blob.test 28c3b25150684ee3d108bb78cfb67a472deef2f0 +F test/blob.test f2dbdbf1159674283645c2636436839313ee7131 F test/btree.test 41c328449887a4a532650db28cf346556ff70d4e F test/btree2.test 4b56a2a4a4f84d68c77aef271223a713bf5ebafc F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4 @@ -366,7 +366,7 @@ F test/lock.test 6825aea0b5885578b1b63a3b178803842c4ee9f1 F test/lock2.test 018b846f6f3b3b695fad07e317b7988442b556f4 F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9 F test/lock4.test f358fa835dff485d462072eee991111f09e87441 -F test/main.test 05f585bb70c05caac3e047903b517cbb319ed204 +F test/main.test 82c222989e02ea09abd58d453828ffd71806b6bf F test/malloc.test 010b60540ce24d90c00bcd46762f06beb80f165d F test/malloc2.test bacb55551f6f4dc58c538589a8d3e29b127ef8d0 F test/malloc3.test 5d3839afd98bff92b82d13405f41c96e77ac2a6b @@ -538,7 +538,7 @@ F test/zeroblob.test 7d1854ea79d048e023e5f2e38106a7e99a17435c F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/lemon.c 5d1731de7eb31238e42ff424c0c78efb4a7be635 -F tool/lempar.c feab108e39e9bd65e3cadb18e5c1d6e857075b28 +F tool/lempar.c 2dafd3da7fba7ccecc3af58fb512f0cbfb8058a4 F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133 F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8 F tool/memleak3.tcl 7707006ee908cffff210c98158788d85bb3fcdbf @@ -614,7 +614,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P c8394ac24b87707fa7f2e3cb43ad8efb65d2595e -R 21d4a739d8a6a8ab5aa325f6376c5db5 +P 1a335e180183b414fcc3510ce28b98b21cd134a6 +R 1823b998eac2ea2abc6d95d39900dbcf U drh -Z 7682f023570ed6783cc7782294e94c3e +Z 8b71aeae0977a8f741811bf53f9ebac4 diff --git a/manifest.uuid b/manifest.uuid index 2d0a28a5bb..5f6f743136 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1a335e180183b414fcc3510ce28b98b21cd134a6 \ No newline at end of file +c82033faf8bdb83ce43f0dd1611408e7796d53de \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 0e7aaf397d..7766341958 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.239 2008/01/22 14:50:17 drh Exp $ +** @(#) $Id: parse.y,v 1.240 2008/01/22 23:37:10 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -32,11 +32,9 @@ // This code runs whenever there is a syntax error // %syntax_error { - if( !pParse->parseError ){ - assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); - pParse->parseError = 1; - } + assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); + pParse->parseError = 1; } %stack_overflow { sqlite3ErrorMsg(pParse, "parser stack overflow"); diff --git a/src/test_config.c b/src/test_config.c index 4f44281224..dcbd8ed958 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -16,7 +16,7 @@ ** The focus of this file is providing the TCL testing layer ** access to compile-time constants. ** -** $Id: test_config.c,v 1.17 2008/01/22 21:30:53 drh Exp $ +** $Id: test_config.c,v 1.18 2008/01/22 23:37:10 drh Exp $ */ #include "sqliteLimit.h" @@ -368,8 +368,10 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double", #if SQLITE_THREADSAFE Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY); + assert( sqlite3_threadsafe() ); #else Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY); + assert( !sqlite3_threadsafe() ); #endif #ifdef SQLITE_OMIT_TRACE diff --git a/src/tokenize.c b/src/tokenize.c index b736f5f5ee..a029c4eeff 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.137 2007/12/17 16:20:07 drh Exp $ +** $Id: tokenize.c,v 1.138 2008/01/22 23:37:10 drh Exp $ */ #include "sqliteInt.h" #include @@ -292,7 +292,7 @@ static int getToken(const unsigned char *z, int *tokenType){ } case '[': { for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){} - *tokenType = TK_ID; + *tokenType = c==']' ? TK_ID : TK_ILLEGAL; return i; } case '?': { @@ -344,19 +344,14 @@ static int getToken(const unsigned char *z, int *tokenType){ } #ifndef SQLITE_OMIT_BLOB_LITERAL case 'x': case 'X': { - if( (c=z[1])=='\'' || c=='"' ){ - int delim = c; + if( z[1]=='\'' ){ *tokenType = TK_BLOB; - for(i=2; (c=z[i])!=0; i++){ - if( c==delim ){ - if( i%2 ) *tokenType = TK_ILLEGAL; - break; - } + for(i=2; (c=z[i])!=0 && c!='\''; i++){ if( !isxdigit(c) ){ *tokenType = TK_ILLEGAL; - return i; } } + if( i%2 || !c ) *tokenType = TK_ILLEGAL; if( c ) i++; return i; } @@ -477,7 +472,7 @@ abort_parse: sqlite3_free(pParse->zErrMsg); } pParse->zErrMsg = 0; - if( !nErr ) nErr++; + nErr++; } if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ sqlite3VdbeDelete(pParse->pVdbe); diff --git a/test/blob.test b/test/blob.test index b3c22b487c..7840cfef7c 100644 --- a/test/blob.test +++ b/test/blob.test @@ -10,7 +10,7 @@ #*********************************************************************** # This file implements regression tests for SQLite library. # -# $Id: blob.test,v 1.5 2006/01/03 00:33:50 drh Exp $ +# $Id: blob.test,v 1.6 2008/01/22 23:37:10 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -49,13 +49,13 @@ do_test blob-1.3 { # Try some syntax errors in blob literals. do_test blob-1.4 { catchsql {SELECT X'01020k304', 100} -} {1 {unrecognized token: "X'01020"}} +} {1 {unrecognized token: "X'01020k304'"}} do_test blob-1.5 { catchsql {SELECT X'01020, 100} -} {1 {unrecognized token: "X'01020"}} +} {1 {unrecognized token: "X'01020, 100"}} do_test blob-1.6 { catchsql {SELECT X'01020 100'} -} {1 {unrecognized token: "X'01020"}} +} {1 {unrecognized token: "X'01020 100'"}} do_test blob-1.7 { catchsql {SELECT X'01001'} } {1 {unrecognized token: "X'01001'"}} diff --git a/test/main.test b/test/main.test index 00aa96af0b..6abfc84857 100644 --- a/test/main.test +++ b/test/main.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is exercising the code in main.c. # -# $Id: main.test,v 1.27 2007/09/03 15:42:48 drh Exp $ +# $Id: main.test,v 1.28 2008/01/22 23:37:10 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -133,26 +133,26 @@ ifcapable {trigger} { do_test main-1.25 { db complete { CREATE TRIGGER xyz AFTER DELETE backend BEGIN - UPDATE pqr SET a=[;end;];;; + UPDATE cantor SET a=[;end;];;; } } {0} do_test main-1.26 { db complete { CREATE -- a comment - TRIGGER xyz AFTER DELETE backend BEGIN + TRIGGER exy AFTER DELETE backend BEGIN UPDATE pqr SET a=5; } } {0} do_test main-1.27.1 { db complete { CREATE -- a comment - TRIGGERX xyz AFTER DELETE backend BEGIN + TRIGGERX tangentxx AFTER DELETE backend BEGIN UPDATE pqr SET a=5; } } {1} do_test main-1.27.2 { db complete { - CREATE/**/TRIGGER xyz AFTER DELETE backend BEGIN + CREATE/**/TRIGGER tiger00 AFTER DELETE backend BEGIN UPDATE pqr SET a=5; } } {0} @@ -160,7 +160,7 @@ ifcapable {trigger} { do_test main-1.27.3 { db complete { /* */ EXPLAIN -- A comment - CREATE/**/TRIGGER xyz AFTER DELETE backend BEGIN + CREATE/**/TRIGGER ezxyz12 AFTER DELETE backend BEGIN UPDATE pqr SET a=5; } } {0} @@ -194,6 +194,9 @@ ifcapable {trigger} { EXPLAIN select * from xyz; } } {0} + +} ;# end ifcapable {complete} + } do_test main-1.30 { db complete { @@ -242,8 +245,26 @@ do_test main-1.35 { do_test main-1.36 { db complete {hi there/***/;} } {1} +do_test main-1.37 { + db complete {hi there/**} +} {0} +do_test main-1.38 { + db complete {hi [there} +} {0} -} ;# end ifcapable {complete} +ifcapable {trigger} { + # Characters less than \040 can never be part of an identifier. + # Characters greater than \u177 are always identifier characters. + do_test main-1.100 { + db complete "create \037\036\035\034trigger\001\002;" + } {1} + do_test main-1.101 { + db complete "create trigger\200;" + } {1} + do_test main-1.102 { + db complete "create \200trigger;" + } {1} +} # Try to open a database with a corrupt database file. @@ -282,6 +303,112 @@ do_test main-3.2.2 { do_test main-3.2.3 { catchsql {select "abc} } {1 {unrecognized token: ""abc"}} +do_test main-3.2.4 { + catchsql {select [abc} +} {1 {unrecognized token: "[abc"}} +do_test main-3.2.5 { + catchsql {select x'4869} +} {1 {unrecognized token: "x'4869"}} +do_test main-3.2.6 { + catchsql {select x'4869'} +} {0 Hi} +do_test main-3.2.7 { + catchsql {select x'48695'} +} {1 {unrecognized token: "x'48695'"}} +do_test main-3.2.8 { + catchsql {select x'486x'} +} {1 {unrecognized token: "x'486x'"}} +do_test main-3.2.9 { + catchsql {select $abc(} +} {1 {unrecognized token: "$abc("}} +do_test main-3.2.10 { + catchsql {select $abc(x} +} {1 {unrecognized token: "$abc(x"}} +set xyz 123 +do_test main-3.2.11 { + catchsql {select $::xyz} +} {0 123} +namespace eval ::testnamespace { + variable xyz 321 +} +do_test main-3.2.12 { + catchsql {select $testnamespace::xyz} +} {0 321} +do_test main-3.2.13 { + catchsql {select $(abc)} +} {1 {unrecognized token: "$"}} +breakpoint +do_test main-3.2.14 { + set hi\u1234x 987 + db eval "select \$hi\u1234x" +} {987} +do_test main-3.2.15 { + catchsql "select 456\u1234" +} [list 1 "unrecognized token: \"456\u1234\""] +do_test main-3.2.16 { + catchsql {select cast(3.14e+4 AS integer)} +} {0 31400} +do_test main-3.2.17 { + catchsql {select cast(3.14e+04 AS integer)} +} {0 31400} +do_test main-3.2.18 { + catchsql {select cast(3.14e+004 AS integer)} +} {0 31400} +do_test main-3.2.19 { + catchsql {select cast(3.14e4 AS integer)} +} {0 31400} +do_test main-3.2.20 { + catchsql {select cast(3.14e04 AS integer)} +} {0 31400} +do_test main-3.2.21 { + catchsql {select cast(3.14e004 AS integer)} +} {0 31400} +do_test main-3.2.16 { + catchsql {select cast(3.14E+4 AS integer)} +} {0 31400} +do_test main-3.2.17 { + catchsql {select cast(3.14E+04 AS integer)} +} {0 31400} +do_test main-3.2.18 { + catchsql {select cast(3.14E+004 AS integer)} +} {0 31400} +do_test main-3.2.19 { + catchsql {select cast(3.14E4 AS integer)} +} {0 31400} +do_test main-3.2.20 { + catchsql {select cast(3.14E04 AS integer)} +} {0 31400} +do_test main-3.2.21 { + catchsql {select cast(3.14E004 AS integer)} +} {0 31400} +do_test main-3.2.22 { + catchsql {select cast(3.14e-4 * 1e8 AS integer)} +} {0 31400} +do_test main-3.2.23 { + catchsql {select cast(3.14E-04 * 1E08 AS integer)} +} {0 31400} +do_test main-3.2.24 { + catchsql {select cast(3.14e-004 * 01.0E+8 AS integer)} +} {0 31400} +do_test main-3.2.25 { + catchsql {select 123/*abc} +} {0 123} +do_test main-3.2.26 { + catchsql {select 123/***abc} +} {0 123} +do_test main-3.2.27 { + catchsql {select 123/*/*2} +} {0 123} +do_test main-3.2.28 { + catchsql {select 123/**/*2} +} {0 246} +do_test main-3.2.29 { + catchsql {select 123/} +} {1 {near "/": syntax error}} +do_test main-3.2.30 { + catchsql {select 123--5} +} {0 123} + do_test main-3.3 { catch {db close} diff --git a/tool/lempar.c b/tool/lempar.c index f061961b77..68a998ac51 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -562,7 +562,8 @@ static void yy_reduce( { yy_shift(yypParser,yyact,yygoto,&yygotominor); } - }else if( yyact == YYNSTATE + YYNRULE + 1 ){ + }else{ + assert( yyact == YYNSTATE + YYNRULE + 1 ); yy_accept(yypParser); } }