/ Check-in [f4021843]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Make sure zeroblob does reasonable things with a negative argument or an argument that is larger than the maximum blob size. (CVS 4048)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f40218434e549144ddb48303df30e5191d44d3fc
User & Date: drh 2007-06-07 19:08:33
Context
2007-06-08
00:20
Fix the query optimizer so that it correctly handles constant expressions in the ON clause of a LEFT JOIN. Ticket #2403. (CVS 4049) check-in: 46fdd195 user: drh tags: trunk
2007-06-07
19:08
Make sure zeroblob does reasonable things with a negative argument or an argument that is larger than the maximum blob size. (CVS 4048) check-in: f4021843 user: drh tags: trunk
15:45
Fix an error in test file sqllimits1.test that was causing a test to fail when SQLITE_MAX_EXPR_DEPTH was defined. (CVS 4047) check-in: e66aa2c3 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
752
753
754
755
756
757
758
759
760
761



762
763

764
765
766
767
768
769
770
** 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.159 2007/05/15 14:40:11 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
................................................................................
** The zeroblob(N) function returns a zero-filled blob of size N bytes.
*/
static void zeroblobFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int n;
  assert( argc==1 );
  n = sqlite3_value_int(argv[0]);



  sqlite3_result_zeroblob(context, n);
}


/*
** The replace() function.  Three arguments are all strings: call
** them A, B, and C. The result is also a string which is derived
** from A by replacing every occurance of B with C.  The match
** must be exact.  Collating sequences are not used.
*/







|







 







|

|
>
>
>
|
|
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
** 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.160 2007/06/07 19:08:33 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
................................................................................
** The zeroblob(N) function returns a zero-filled blob of size N bytes.
*/
static void zeroblobFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  i64 n;
  assert( argc==1 );
  n = sqlite3_value_int64(argv[0]);
  if( n>SQLITE_MAX_LENGTH ){
    sqlite3_result_error_toobig(context);
  }else{
    sqlite3_result_zeroblob(context, n);
  }
}

/*
** The replace() function.  Three arguments are all strings: call
** them A, B, and C. The result is also a string which is derived
** from A by replacing every occurance of B with C.  The match
** must be exact.  Collating sequences are not used.
*/

Changes to src/limits.h.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
76
77
78
79
80
81
82

83
84
85
86
87
88
89
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** 
** This file defines various limits of what SQLite can process.
**
** @(#) $Id: limits.h,v 1.7 2007/06/07 10:55:36 drh Exp $
*/

/*
** The maximum length of a TEXT or BLOB in bytes.   This also
** limits the size of a row in a table or index.
**
** The hard limit is the ability of a 32-bit signed integer
................................................................................
*/
#ifndef SQLITE_MAX_COMPOUND_SELECT
# define SQLITE_MAX_COMPOUND_SELECT 100
#endif

/*
** The maximum number of opcodes in a VDBE program.

*/
#ifndef SQLITE_MAX_VDBE_OP
# define SQLITE_MAX_VDBE_OP 25000
#endif

/*
** The maximum number of arguments to an SQL function.







|







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** 
** This file defines various limits of what SQLite can process.
**
** @(#) $Id: limits.h,v 1.8 2007/06/07 19:08:34 drh Exp $
*/

/*
** The maximum length of a TEXT or BLOB in bytes.   This also
** limits the size of a row in a table or index.
**
** The hard limit is the ability of a 32-bit signed integer
................................................................................
*/
#ifndef SQLITE_MAX_COMPOUND_SELECT
# define SQLITE_MAX_COMPOUND_SELECT 100
#endif

/*
** The maximum number of opcodes in a VDBE program.
** Not currently enforced.
*/
#ifndef SQLITE_MAX_VDBE_OP
# define SQLITE_MAX_VDBE_OP 25000
#endif

/*
** The maximum number of arguments to an SQL function.

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.623 2007/05/23 06:31:39 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <math.h>
#include "vdbeInt.h"

................................................................................
  ** is encountered.
  */
too_big:
  sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0);
  rc = SQLITE_TOOBIG;
  goto vdbe_halt;

  /* Jump to here if a malloc() fails.  It's hard to get a malloc()
  ** to fail on a modern VM computer, so this code is untested.
  */
no_mem:
  sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);
  rc = SQLITE_NOMEM;
  goto vdbe_halt;

  /* Jump to here for an SQLITE_MISUSE error.







|







 







|
<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
5135
5136
5137
5138
5139
5140
5141
5142

5143
5144
5145
5146
5147
5148
5149
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.624 2007/06/07 19:08:34 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <math.h>
#include "vdbeInt.h"

................................................................................
  ** is encountered.
  */
too_big:
  sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0);
  rc = SQLITE_TOOBIG;
  goto vdbe_halt;

  /* Jump to here if a malloc() fails.

  */
no_mem:
  sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);
  rc = SQLITE_NOMEM;
  goto vdbe_halt;

  /* Jump to here for an SQLITE_MISUSE error.

Changes to src/vdbemem.c.

94
95
96
97
98
99
100

101


102
103
104
105
106
107
108
109
...
407
408
409
410
411
412
413

414
415
416
417
418
419
420
** If the given Mem* has a zero-filled tail, turn it into an ordinary
** blob stored in dynamically allocated space.
*/
#ifndef SQLITE_OMIT_INCRBLOB
int sqlite3VdbeMemExpandBlob(Mem *pMem){
  if( pMem->flags & MEM_Zero ){
    char *pNew;

    assert( (pMem->flags & MEM_Blob)!=0 );


    pNew = sqliteMalloc(pMem->n+pMem->u.i);
    if( pNew==0 ){ 
      return SQLITE_NOMEM;
    }
    memcpy(pNew, pMem->z, pMem->n);
    memset(&pNew[pMem->n], 0, pMem->u.i);
    sqlite3VdbeMemRelease(pMem);
    pMem->z = pNew;
................................................................................
** n containing all zeros.
*/
void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Blob|MEM_Zero|MEM_Short;
  pMem->type = SQLITE_BLOB;
  pMem->n = 0;

  pMem->u.i = n;
  pMem->z = pMem->zShort;
  pMem->enc = SQLITE_UTF8;
}

/*
** Delete any previous value and set the value stored in *pMem to val,







>

>
>
|







 







>







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
** If the given Mem* has a zero-filled tail, turn it into an ordinary
** blob stored in dynamically allocated space.
*/
#ifndef SQLITE_OMIT_INCRBLOB
int sqlite3VdbeMemExpandBlob(Mem *pMem){
  if( pMem->flags & MEM_Zero ){
    char *pNew;
    int nByte;
    assert( (pMem->flags & MEM_Blob)!=0 );
    nByte = pMem->n + pMem->u.i;
    if( nByte<=0 ) nByte = 1;
    pNew = sqliteMalloc(nByte);
    if( pNew==0 ){ 
      return SQLITE_NOMEM;
    }
    memcpy(pNew, pMem->z, pMem->n);
    memset(&pNew[pMem->n], 0, pMem->u.i);
    sqlite3VdbeMemRelease(pMem);
    pMem->z = pNew;
................................................................................
** n containing all zeros.
*/
void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Blob|MEM_Zero|MEM_Short;
  pMem->type = SQLITE_BLOB;
  pMem->n = 0;
  if( n<0 ) n = 0;
  pMem->u.i = n;
  pMem->z = pMem->zShort;
  pMem->enc = SQLITE_UTF8;
}

/*
** Delete any previous value and set the value stored in *pMem to val,

Changes to test/sqllimits1.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
37
38
39
40
41
42
43
44
45
46



47
48
49
50
51
52
53
..
54
55
56
57
58
59
60












61
62
63
64
65
66
67
...
433
434
435
436
437
438
439
440
441
#    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.9 2007/06/07 15:45:35 danielk1977 Exp $

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

# Test organization:
#
#     sqllimits-1.*:  SQLITE_MAX_LENGTH
................................................................................
#     sqllimits-6.*:   SQLITE_MAX_VDBE_OP               (sqlite todo)
#

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




# Large, but allowable, blob-size.
#
set ::LARGESIZE [expr $SQLITE_MAX_LENGTH - 1] 

do_test sqllimits-1.2 {
  catchsql { SELECT LENGTH(randomblob($::LARGESIZE)) }
................................................................................
} "0 $::LARGESIZE"

do_test sqllimits-1.3 {
  catchsql { SELECT quote(randomblob($::LARGESIZE)) }
} {1 {string or blob too big}}

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
................................................................................
  set ::format "[string repeat A 60][string repeat "%J" $::N]"
  catchsql {
    SELECT strftime($::format, 1);
  }
} {1 {string or blob too big}}

finish_test









|







 







|


>
>
>







 







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







 







<
<
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
..
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
...
448
449
450
451
452
453
454


#    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.10 2007/06/07 19:08:34 drh Exp $

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

# Test organization:
#
#     sqllimits-1.*:  SQLITE_MAX_LENGTH
................................................................................
#     sqllimits-6.*:   SQLITE_MAX_VDBE_OP               (sqlite todo)
#

#--------------------------------------------------------------------
# Test cases sqllimits-1.* test that the SQLITE_MAX_LENGTH limit
# is enforced.
#
do_test sqllimits-1.1.1 {
  catchsql { SELECT randomblob(2147483647) }
} {1 {string or blob too big}}
do_test sqllimits-1.1.2 {
  catchsql { SELECT zeroblob(2147483647) }
} {1 {string or blob too big}}

# Large, but allowable, blob-size.
#
set ::LARGESIZE [expr $SQLITE_MAX_LENGTH - 1] 

do_test sqllimits-1.2 {
  catchsql { SELECT LENGTH(randomblob($::LARGESIZE)) }
................................................................................
} "0 $::LARGESIZE"

do_test sqllimits-1.3 {
  catchsql { SELECT quote(randomblob($::LARGESIZE)) }
} {1 {string or blob too big}}

do_test sqllimits-1.4 {
  catchsql { SELECT LENGTH(zeroblob($::LARGESIZE)) }
} "0 $::LARGESIZE"

do_test sqllimits-1.5 {
  catchsql { SELECT quote(zeroblob($::LARGESIZE)) }
} {1 {string or blob too big}}

do_test sqllimits-1.6 {
  catchsql { SELECT zeroblob(-1) }
} {0 {}}

do_test sqllimits-1.9 {
  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
................................................................................
  set ::format "[string repeat A 60][string repeat "%J" $::N]"
  catchsql {
    SELECT strftime($::format, 1);
  }
} {1 {string or blob too big}}

finish_test


Changes to test/zeroblob.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
147
148
149
150
151
152
153
154
























155
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing of the zero-filled blob functionality
# including the sqlite3_bind_zeroblob(), sqlite3_result_zeroblob(),
# and the built-in zeroblob() SQL function.
#
# $Id: zeroblob.test,v 1.5 2007/05/30 06:19:33 danielk1977 Exp $

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

ifcapable !incrblob {
  finish_test
  return
................................................................................
} {{}}
do_test zeroblob-5.4 {
  execsql {
    SELECT CAST(zeroblob(100) AS BLOB);
  }
} [execsql {SELECT zeroblob(100)}]
  

























finish_test







|







 








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

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
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
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing of the zero-filled blob functionality
# including the sqlite3_bind_zeroblob(), sqlite3_result_zeroblob(),
# and the built-in zeroblob() SQL function.
#
# $Id: zeroblob.test,v 1.6 2007/06/07 19:08:34 drh Exp $

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

ifcapable !incrblob {
  finish_test
  return
................................................................................
} {{}}
do_test zeroblob-5.4 {
  execsql {
    SELECT CAST(zeroblob(100) AS BLOB);
  }
} [execsql {SELECT zeroblob(100)}]
  

# Check for malicious use of zeroblob.  Make sure nothing crashes.
#
do_test zeroblob-6.1.1 { 
  execsql {select zeroblob(-1)} 
} {{}} 
do_test zeroblob-6.1.2 { 
  execsql {select zeroblob(-10)} 
} {{}} 
do_test zeroblob-6.1.3 { 
  execsql {select zeroblob(-100)} 
} {{}} 
do_test zeroblob-6.2 { 
  execsql {select length(zeroblob(-1))} 
} {0} 
do_test zeroblob-6.3 { 
  execsql {select zeroblob(-1)|1} 
} {1} 
do_test zeroblob-6.4 { 
  catchsql {select length(zeroblob(2147483648))} 
} {1 {string or blob too big}} 
do_test zeroblob-6.5 { 
  catchsql {select zeroblob(2147483648)} 
} {1 {string or blob too big}} 

finish_test