From b56fe1ff27e97c0f6d8e8c7552be8c73e2862df4 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Wed, 9 May 2007 08:24:44 +0000 Subject: [PATCH] Fix enforcement of the LIKE_PATTERN limit. (CVS 3962) FossilOrigin-Name: 8819617b7cf7ccd64bf6bb4ba208f37126964ec2 --- manifest | 18 +++++----- manifest.uuid | 2 +- src/func.c | 11 +++--- src/test_config.c | 12 ++++++- test/sqllimits1.test | 86 ++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 109 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 3ec63a3646..1f641933b1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\skeyword\sfrom\sthe\sheader\scomment\sin\sdate.c\s(CVS\s3961) -D 2007-05-08T21:56:00 +C Fix\senforcement\sof\sthe\sLIKE_PATTERN\slimit.\s(CVS\s3962) +D 2007-05-09T08:24:44 F Makefile.in 87b200ad9970907f76df734d29dff3d294c10935 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -71,7 +71,7 @@ F src/date.c 6049db7d5a8fdf2c677ff7d58fa31d4f6593c988 F src/delete.c 5c0d89b3ef7d48fe1f5124bfe8341f982747fe29 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b F src/expr.c eb91a54d0c2a3bebfcf91deda95508a188c2ed63 -F src/func.c 1fccb0372041188f4240350553164704e8aebeb4 +F src/func.c 6282d2025d8e0db80b43783a4778cbb04e98f2f6 F src/hash.c 67b23e14f0257b69a3e8aa663e4eeadc1a2b6fd5 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564 F src/insert.c e595ca26805dfb3a9ebaabc28e7947c479f3b14d @@ -119,7 +119,7 @@ F src/test9.c c0f38f7795cc51d37db6c63874d90f40f10d0f0e F src/test_async.c 9d326ceda4306bcab252b8f7e8e480ed45d7ccb6 F src/test_autoext.c 855157d97aa28cf84233847548bfacda21807436 F src/test_btree.c 882d59acad48bab3b1fe3daf3645059b590cfc79 -F src/test_config.c 8a66329b3f2fbb17d8ce00716eb611fa49f0887e +F src/test_config.c c267103cac3733a0d14a0b8d3fa8c22b22fb468a F src/test_hexio.c 32204b5ce281ebc85f789c69c4ec725129e7e7f5 F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8 F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3 @@ -340,7 +340,7 @@ F test/shared_err.test cc528f6e78665787e93d9ce3a782a2ce5179d821 F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5 F test/speed1.test 22e1b27af0683ed44dcd2f93ed817a9c3e65084a F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded -F test/sqllimits1.test 02a33a7f6c0064be4e5133327975ce5e69342a4f +F test/sqllimits1.test 7fff0aaf860bdd65ba9c45969f1d17ca4f6c9a8c F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797 F test/subselect.test 974e87f8fc91c5f00dd565316d396a5a6c3106c4 F test/sync.test d05397b8f89f423dd6dba528692019ab036bc1c3 @@ -486,7 +486,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P c5754530c6b1a8151c558f33d27fed70c95a988b -R b5f8e28bbaf447fb3e0fb1a48ce02db9 -U drh -Z 0e6336c72c0c38d732834ceb058795ef +P 03349ec0be208fd8701d94515a2ed13129cb8422 +R f2e9dd7272549bf53a2372232b2e3902 +U danielk1977 +Z ddbbd47818532a8c09b0749d1c22ef8a diff --git a/manifest.uuid b/manifest.uuid index a46769e233..b563aab038 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03349ec0be208fd8701d94515a2ed13129cb8422 \ No newline at end of file +8819617b7cf7ccd64bf6bb4ba208f37126964ec2 \ No newline at end of file diff --git a/src/func.c b/src/func.c index c9a035a427..a8fbe104e1 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.152 2007/05/08 20:37:39 drh Exp $ +** $Id: func.c,v 1.153 2007/05/09 08:24:44 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -540,14 +540,13 @@ static void likeFunc( /* Limit the length of the LIKE or GLOB pattern to avoid problems ** of deep recursion and N*N behavior in patternCompare(). */ - if( sqlite3_value_bytes(argv[1])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ + if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); return; } - - zA = sqlite3_value_text(argv[0]); - zB = sqlite3_value_text(argv[1]); + zB = sqlite3_value_text(argv[0]); + zA = sqlite3_value_text(argv[1]); int escape = 0; if( argc==3 ){ /* The escape character string must consist of a single UTF-8 character. @@ -568,7 +567,7 @@ static void likeFunc( sqlite3_like_count++; #endif - sqlite3_result_int(context, patternCompare(zA, zB, pInfo, escape)); + sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)); } } diff --git a/src/test_config.c b/src/test_config.c index ff500e302d..f7373ee191 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.1 2007/05/08 01:08:49 drh Exp $ +** $Id: test_config.c,v 1.2 2007/05/09 08:24:44 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -376,6 +376,11 @@ static void set_options(Tcl_Interp *interp){ Tcl_LinkVar(interp, "SQLITE_MAX_COLUMN", (char*)&sqlite_max_column, TCL_LINK_INT|TCL_LINK_READ_ONLY); } + { + static int sqlite_max_sql_length = SQLITE_MAX_SQL_LENGTH; + Tcl_LinkVar(interp, "SQLITE_MAX_SQL_LENGTH", + (char*)&sqlite_max_sql_length, TCL_LINK_INT|TCL_LINK_READ_ONLY); + } { static int sqlite_max_expr_length = SQLITE_MAX_EXPR_LENGTH; Tcl_LinkVar(interp, "SQLITE_MAX_EXPR_LENGTH", @@ -432,6 +437,11 @@ static void set_options(Tcl_Interp *interp){ Tcl_LinkVar(interp, "SQLITE_DEFAULT_FILE_FORMAT", (char*)&sqlite_default_file_format, TCL_LINK_INT|TCL_LINK_READ_ONLY); } + { + static int sqlite_max_like_pattern = SQLITE_MAX_LIKE_PATTERN_LENGTH; + Tcl_LinkVar(interp, "SQLITE_MAX_LIKE_PATTERN_LENGTH", + (char*)&sqlite_max_like_pattern, TCL_LINK_INT|TCL_LINK_READ_ONLY); + } } diff --git a/test/sqllimits1.test b/test/sqllimits1.test index 812b3763f2..17a0edb074 100644 --- a/test/sqllimits1.test +++ b/test/sqllimits1.test @@ -12,11 +12,30 @@ # This file contains tests to verify that the limits defined in # sqlite source file limits.h are enforced. # -# $Id: sqllimits1.test,v 1.3 2007/05/08 17:54:44 danielk1977 Exp $ +# $Id: sqllimits1.test,v 1.4 2007/05/09 08:24:44 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl +# Test organization: +# +# sqllimits-1.*: SQLITE_MAX_LENGTH +# sqllimits-2.*: SQLITE_MAX_SQL_LENGTH +# sqllimits-3.*: SQLITE_MAX_PAGE_COUNT +# sqllimits-4.*: SQLITE_MAX_COLUMN +# +# Todo: +# +# sqllimits-5.*: SQLITE_MAX_EXPR_LENGTH (sqlite todo) +# sqllimits-6.*: SQLITE_MAX_VDBE_OP (sqlite todo) +# sqllimits-7.*: SQLITE_MAX_FUNCTION_ARG +# sqllimits-8.*: SQLITE_MAX_ATTACHED +# sqllimits-9.*: SQLITE_MAX_VARIABLE_NUMBER +# sqllimits-10.*: SQLITE_MAX_PAGE_SIZE +# sqllimits-11.*: SQLITE_MAX_PAGE_COUNT +# sqllimits-12.*: SQLITE_MAX_LIKE_PATTERN_LENGTH +# + #-------------------------------------------------------------------- # Test cases sqllimits-1.* test that the SQLITE_MAX_LENGTH limit # is enforced. @@ -44,12 +63,13 @@ do_test sqllimits-1.4 { } {1 {string or blob too big}} #-------------------------------------------------------------------- -# Test cases sqllimits-2.* test that the SQLITE_MAX_SQL limit +# Test cases sqllimits-2.* test that the SQLITE_MAX_SQL_LENGTH limit # is enforced. # do_test sqllimits-2.1 { set sql "SELECT 1 WHERE 1==1" - append sql [string repeat " AND 1==1" 200000] + set N [expr {$::SQLITE_MAX_SQL_LENGTH / [string length " AND 1==1"]}] + append sql [string repeat " AND 1==1" $N] catchsql $sql } {1 {String or BLOB exceeded size limit}} @@ -141,6 +161,7 @@ do_test sqllimits1-3.6 { # Test cases sqllimits1-4.* test the SQLITE_MAX_COLUMN limit. # do_test sqllimits-1.4.1 { + # Columns in a table. set cols [list] for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} { lappend cols "c$i" @@ -149,6 +170,7 @@ do_test sqllimits-1.4.1 { } {1 {too many columns on t}} do_test sqllimits-1.4.2 { + # Columns in the result-set of a SELECT. set cols [list] for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} { lappend cols "sql AS sql$i" @@ -157,6 +179,7 @@ do_test sqllimits-1.4.2 { } {1 {too many columns in result set}} do_test sqllimits-1.4.3 { + # Columns in the result-set of a sub-SELECT. set cols [list] for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} { lappend cols "sql AS sql$i" @@ -165,6 +188,7 @@ do_test sqllimits-1.4.3 { } {1 {too many columns in result set}} do_test sqllimits-1.4.4 { + # Columns in an index. set cols [list] for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} { lappend cols c @@ -175,14 +199,17 @@ do_test sqllimits-1.4.4 { } {1 {too many columns in index}} do_test sqllimits-1.4.5 { + # Columns in a GROUP BY clause. catchsql "SELECT * FROM t1 GROUP BY [join $cols ,]" } {1 {too many terms in GROUP BY clause}} do_test sqllimits-1.4.6 { + # Columns in an ORDER BY clause. catchsql "SELECT * FROM t1 ORDER BY [join $cols ,]" } {1 {too many terms in ORDER BY clause}} do_test sqllimits-1.4.7 { + # Assignments in an UPDATE statement. set cols [list] for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} { lappend cols "c = 1" @@ -190,6 +217,59 @@ do_test sqllimits-1.4.7 { catchsql "UPDATE t1 SET [join $cols ,];" } {1 {too many columns in set list}} +do_test sqllimits-1.4.8 { + # Columns in a view definition: + set cols [list] + for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} { + lappend cols "c$i" + } + catchsql "CREATE VIEW v1 AS SELECT [join $cols ,] FROM t1;" +} {1 {too many columns in result set}} + +do_test sqllimits-1.4.9 { + # Columns in a view definition (testing * expansion): + set cols [list] + for {set i 0} {$i < $SQLITE_MAX_COLUMN} {incr i} { + lappend cols "c$i" + } + catchsql "CREATE TABLE t2([join $cols ,])" + catchsql "CREATE VIEW v1 AS SELECT *, c1 AS o FROM t2;" +} {1 {too many columns in result set}} + +#-------------------------------------------------------------------- +# These tests - sqllimits-5.* - test that the SQLITE_MAX_EXPR_LENGTH +# limit is enforced. The limit refers to the number of terms in +# the expression. +# + +#-------------------------------------------------------------------- +# Test cases sqllimits-12.* verify that the +# SQLITE_MAX_LIKE_PATTERN_LENGTH limit is enforced. This limit only +# applies to the built-in LIKE operator, supplying an external +# implementation by overriding the like() scalar function bypasses +# this limitation. +# +# These tests check that the limit is not incorrectly applied to +# the left-hand-side of the LIKE operator (the string being tested +# against the pattern). +# +do_test sqllimits-1.12.1 { + set max $::SQLITE_MAX_LIKE_PATTERN_LENGTH + set ::pattern [string repeat "A%" [expr $max/2]] + set ::string [string repeat "A" [expr {$max*2}]] + execsql { + SELECT $::string LIKE $::pattern; + } +} {1} +do_test sqllimits-1.12.2 { + set max $::SQLITE_MAX_LIKE_PATTERN_LENGTH + set ::pattern [string repeat "A%" [expr {($max/2) + 1}]] + set ::string [string repeat "A" [expr {$max*2}]] + catchsql { + SELECT $::string LIKE $::pattern; + } +} {1 {LIKE or GLOB pattern too complex}} + finish_test