SQLite

Check-in [8819617b7c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix enforcement of the LIKE_PATTERN limit. (CVS 3962)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8819617b7cf7ccd64bf6bb4ba208f37126964ec2
User & Date: danielk1977 2007-05-09 08:24:44.000
Context
2007-05-09
11:37
Add further test cases for compile time limits. (CVS 3963) (check-in: 9bf2c594a4 user: danielk1977 tags: trunk)
08:24
Fix enforcement of the LIKE_PATTERN limit. (CVS 3962) (check-in: 8819617b7c user: danielk1977 tags: trunk)
2007-05-08
21:56
Remove a keyword from the header comment in date.c (CVS 3961) (check-in: 03349ec0be user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/func.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** 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 $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.153 2007/05/09 08:24:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
  sqlite3_value **argv
){
  const unsigned char *zA, *zB;

  /* 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 ){
    sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
    return;
  }


  zA = sqlite3_value_text(argv[0]);
  zB = sqlite3_value_text(argv[1]);
  int escape = 0;
  if( argc==3 ){
    /* The escape character string must consist of a single UTF-8 character.
    ** Otherwise, return an error.
    */
    const unsigned char *zEsc = sqlite3_value_text(argv[2]);
    if( zEsc==0 ) return;
    if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
      sqlite3_result_error(context, 
          "ESCAPE expression must be a single character", -1);
      return;
    }
    escape = sqlite3ReadUtf8(zEsc);
  }
  if( zA && zB ){
    struct compareInfo *pInfo = sqlite3_user_data(context);
#ifdef SQLITE_TEST
    sqlite3_like_count++;
#endif
    
    sqlite3_result_int(context, patternCompare(zA, zB, pInfo, escape));
  }
}

/*
** Implementation of the NULLIF(x,y) function.  The result is the first
** argument if the arguments are different.  The result is NULL if the
** arguments are equal to each other.







|




<
|
|




















|







536
537
538
539
540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
  sqlite3_value **argv
){
  const unsigned char *zA, *zB;

  /* 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[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){
    sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
    return;
  }


  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.
    ** Otherwise, return an error.
    */
    const unsigned char *zEsc = sqlite3_value_text(argv[2]);
    if( zEsc==0 ) return;
    if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
      sqlite3_result_error(context, 
          "ESCAPE expression must be a single character", -1);
      return;
    }
    escape = sqlite3ReadUtf8(zEsc);
  }
  if( zA && zB ){
    struct compareInfo *pInfo = sqlite3_user_data(context);
#ifdef SQLITE_TEST
    sqlite3_like_count++;
#endif
    
    sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
  }
}

/*
** Implementation of the NULLIF(x,y) function.  The result is the first
** argument if the arguments are different.  The result is NULL if the
** arguments are equal to each other.
Changes to src/test_config.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** 
** This file contains code used for testing the SQLite system.
** None of the code in this file goes into a deliverable build.
** 
** 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 $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>








|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** 
** This file contains code used for testing the SQLite system.
** None of the code in this file goes into a deliverable build.
** 
** The focus of this file is providing the TCL testing layer
** access to compile-time constants.
**
** $Id: test_config.c,v 1.2 2007/05/09 08:24:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

372
373
374
375
376
377
378





379
380
381
382
383
384
385
           (char*)&sqlite_max_length, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  }
  {
    static int sqlite_max_column = SQLITE_MAX_COLUMN;
    Tcl_LinkVar(interp, "SQLITE_MAX_COLUMN",
           (char*)&sqlite_max_column, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  }





  {
    static int sqlite_max_expr_length = SQLITE_MAX_EXPR_LENGTH;
    Tcl_LinkVar(interp, "SQLITE_MAX_EXPR_LENGTH",
           (char*)&sqlite_max_expr_length, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  }
  {
    static int sqlite_max_vdbe_op = SQLITE_MAX_VDBE_OP;







>
>
>
>
>







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
           (char*)&sqlite_max_length, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  }
  {
    static int sqlite_max_column = SQLITE_MAX_COLUMN;
    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",
           (char*)&sqlite_max_expr_length, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  }
  {
    static int sqlite_max_vdbe_op = SQLITE_MAX_VDBE_OP;
428
429
430
431
432
433
434





435
436
437
438
439
440
441
442
443
444
           (char*)&temp_store, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  }
  {
    static int sqlite_default_file_format = SQLITE_DEFAULT_FILE_FORMAT;
    Tcl_LinkVar(interp, "SQLITE_DEFAULT_FILE_FORMAT",
           (char*)&sqlite_default_file_format, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  }





}


/*
** Register commands with the TCL interpreter.
*/
int Sqliteconfig_Init(Tcl_Interp *interp){
  set_options(interp);
  return TCL_OK;
}







>
>
>
>
>










433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
           (char*)&temp_store, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  }
  {
    static int sqlite_default_file_format = SQLITE_DEFAULT_FILE_FORMAT;
    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);
  }
}


/*
** Register commands with the TCL interpreter.
*/
int Sqliteconfig_Init(Tcl_Interp *interp){
  set_options(interp);
  return TCL_OK;
}
Changes to test/sqllimits1.test.
8
9
10
11
12
13
14
15
16
17
18



















19
20
21
22
23
24
25
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# 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 $

set testdir [file dirname $argv0]
source $testdir/tester.tcl




















#--------------------------------------------------------------------
# Test cases sqllimits-1.* test that the SQLITE_MAX_LENGTH limit
# is enforced.
#
do_test sqllimits-1.1 {
  catchsql { SELECT randomblob(2147483647) }







|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests to verify that the limits defined in
# sqlite source file limits.h are enforced.
#
# $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.
#
do_test sqllimits-1.1 {
  catchsql { SELECT randomblob(2147483647) }
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
do_test sqllimits-1.4 {
  set ::str [string repeat A 65537]
  set ::rep [string repeat B 65537]
  catchsql { SELECT replace($::str, 'A', $::rep) }
} {1 {string or blob too big}}

#--------------------------------------------------------------------
# Test cases sqllimits-2.* test that the SQLITE_MAX_SQL limit
# is enforced.
#
do_test sqllimits-2.1 {
  set    sql "SELECT 1 WHERE 1==1"

  append sql [string repeat " AND 1==1" 200000]
  catchsql $sql
} {1 {String or BLOB exceeded size limit}}

#--------------------------------------------------------------------
# Test cases sqllimits-3.* test that the limit set using the
# max_page_count pragma.
#







|




>
|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
do_test sqllimits-1.4 {
  set ::str [string repeat A 65537]
  set ::rep [string repeat B 65537]
  catchsql { SELECT replace($::str, 'A', $::rep) }
} {1 {string or blob too big}}

#--------------------------------------------------------------------
# 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"
  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}}

#--------------------------------------------------------------------
# Test cases sqllimits-3.* test that the limit set using the
# max_page_count pragma.
#
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176
177

178
179
180
181

182
183
184
185

186
187
188
189
190
191
192





















































193
194
195
} {0 7}


#--------------------------------------------------------------------
# Test cases sqllimits1-4.* test the SQLITE_MAX_COLUMN limit.
#
do_test sqllimits-1.4.1 {

  set cols [list]
  for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} {
    lappend cols "c$i"
  }
  catchsql "CREATE TABLE t([join $cols ,])" 
} {1 {too many columns on t}}

do_test sqllimits-1.4.2 {

  set cols [list]
  for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} {
    lappend cols "sql AS sql$i"
  }
  catchsql "SELECT [join $cols ,] FROM sqlite_master"
} {1 {too many columns in result set}}

do_test sqllimits-1.4.3 {

  set cols [list]
  for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} {
    lappend cols "sql AS sql$i"
  }
  catchsql "SELECT sql4 FROM (SELECT [join $cols ,] FROM sqlite_master)"
} {1 {too many columns in result set}}

do_test sqllimits-1.4.4 {

  set cols [list]
  for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} {
    lappend cols c
  }
  set sql1 "CREATE TABLE t1(c);"
  set sql2 "CREATE INDEX i1 ON t1([join $cols ,]);"
  catchsql "$sql1 ; $sql2"
} {1 {too many columns in index}}

do_test sqllimits-1.4.5 {

  catchsql "SELECT * FROM t1 GROUP BY [join $cols ,]"
} {1 {too many terms in GROUP BY clause}}

do_test sqllimits-1.4.6 {

  catchsql "SELECT * FROM t1 ORDER BY [join $cols ,]"
} {1 {too many terms in ORDER BY clause}}

do_test sqllimits-1.4.7 {

  set cols [list]
  for {set i 0} {$i <= $SQLITE_MAX_COLUMN} {incr i} {
    lappend cols "c = 1"
  }
  catchsql "UPDATE t1 SET [join $cols ,];"
} {1 {too many columns in set list}}






















































finish_test









>








>








>








>










>




>




>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
} {0 7}


#--------------------------------------------------------------------
# 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"
  }
  catchsql "CREATE TABLE t([join $cols ,])" 
} {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"
  }
  catchsql "SELECT [join $cols ,] FROM sqlite_master"
} {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"
  }
  catchsql "SELECT sql4 FROM (SELECT [join $cols ,] FROM sqlite_master)"
} {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
  }
  set sql1 "CREATE TABLE t1(c);"
  set sql2 "CREATE INDEX i1 ON t1([join $cols ,]);"
  catchsql "$sql1 ; $sql2"
} {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"
  }
  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