/ Check-in [e14374e4]
Login

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

Overview
Comment:Be careful not to use the result of sqlite3_value_blob() after changing the representation of an object. Ticket #2290. (CVS 3834)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:e14374e4e6f14a90ecb53c2e7c86908a220c6d68
User & Date: drh 2007-04-10 13:51:18
Context
2007-04-10
18:17
Preliminary fix for ticket #2291. This fixes the immediate problem. But we really need to write more tests for the xfer optimization in order to look for other related problems before closing this ticket. (CVS 3835) check-in: 34fec312 user: drh tags: trunk
13:51
Be careful not to use the result of sqlite3_value_blob() after changing the representation of an object. Ticket #2290. (CVS 3834) check-in: e14374e4 user: drh tags: trunk
2007-04-09
20:45
Fix crash in delete when existing row has null fields. Previous code assumed that the row had values in all columns, sigh. Fixes bug http://www.sqlite.org/cvstrac/tktview?tn=2289 . (CVS 3833) check-in: 81be7290 user: shess 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
...
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
** 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.138 2007/03/17 17:52:42 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
................................................................................
  int argc,
  sqlite3_value **argv
){
  int i, n;
  const unsigned char *pBlob;
  char *zHex, *z;
  assert( argc==1 );
  pBlob = sqlite3_value_blob(argv[0]);
  n = sqlite3_value_bytes(argv[0]);
  z = zHex = sqlite3_malloc(n*2 + 1);
  if( zHex==0 ) return;
  for(i=0; i<n; i++, pBlob++){
    unsigned char c = *pBlob;
    *(z++) = hexdigits[(c>>4)&0xf];
    *(z++) = hexdigits[c&0xf];
  }







|







 







|
|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
** 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.139 2007/04/10 13:51:18 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
................................................................................
  int argc,
  sqlite3_value **argv
){
  int i, n;
  const unsigned char *pBlob;
  char *zHex, *z;
  assert( argc==1 );
  n = sqlite3_value_bytes(argv[0]);
  pBlob = sqlite3_value_blob(argv[0]);
  z = zHex = sqlite3_malloc(n*2 + 1);
  if( zHex==0 ) return;
  for(i=0; i<n; i++, pBlob++){
    unsigned char c = *pBlob;
    *(z++) = hexdigits[(c>>4)&0xf];
    *(z++) = hexdigits[c&0xf];
  }

Changes to test/func.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
321
322
323
324
325
326
327



328
329
330
331
332
333
334
#    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 built-in functions.
#
# $Id: func.test,v 1.59 2007/03/17 17:52:42 drh Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
# The "hex()" function was added in order to be able to render blobs
# generated by randomblob().  So this seems like a good place to test
# hex().
#
do_test func-9.10 {
  execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')}
} {00112233445566778899AABBCCDDEEFF}




# Use the "sqlite_register_test_function" TCL command which is part of
# the text fixture in order to verify correct operation of some of
# the user-defined SQL function APIs that are not used by the built-in
# functions.
#
set ::DB [sqlite3_connection_pointer db]







|







 







>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
#    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 built-in functions.
#
# $Id: func.test,v 1.60 2007/04/10 13:51:19 drh Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
# The "hex()" function was added in order to be able to render blobs
# generated by randomblob().  So this seems like a good place to test
# hex().
#
do_test func-9.10 {
  execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')}
} {00112233445566778899AABBCCDDEEFF}
do_test func-9.11 {
  execsql {SELECT hex(replace('abcdefg','ef','12'))}
} {61626364313267}

# Use the "sqlite_register_test_function" TCL command which is part of
# the text fixture in order to verify correct operation of some of
# the user-defined SQL function APIs that are not used by the built-in
# functions.
#
set ::DB [sqlite3_connection_pointer db]

Changes to www/capi3ref.tcl.

1
2
3
4
5
6
7
8
...
425
426
427
428
429
430
431












432
433
434
435
436
437
438
set rcsid {$Id: capi3ref.tcl,v 1.53 2007/03/17 10:26:59 danielk1977 Exp $}
source common.tcl
header {C/C++ Interface For SQLite Version 3}
puts {
<h2 class=pdf_section>C/C++ Interface For SQLite Version 3</h2>
}

proc api {name prototype desc {notused x}} {
................................................................................
<tr><td> TEXT </td><td>    FLOAT </td><td> Use atof()</td></tr>
<tr><td> TEXT </td><td>    BLOB </td><td>  No change</td></tr>
<tr><td> BLOB </td><td>    INTEGER</td><td>Convert to TEXT then use atoi()</td></tr>
<tr><td> BLOB </td><td>    FLOAT </td><td> Convert to TEXT then use atof()</td></tr>
<tr><td> BLOB </td><td>    TEXT </td><td>  Add a \\000 terminator if needed</td></tr>
</table>
</blockquote>












}

api {} {
int sqlite3_column_count(sqlite3_stmt *pStmt);
} {
 Return the number of columns in the result set returned by the prepared
 SQL statement. This routine returns 0 if pStmt is an SQL statement
|







 







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







1
2
3
4
5
6
7
8
...
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
set rcsid {$Id: capi3ref.tcl,v 1.54 2007/04/10 13:51:19 drh Exp $}
source common.tcl
header {C/C++ Interface For SQLite Version 3}
puts {
<h2 class=pdf_section>C/C++ Interface For SQLite Version 3</h2>
}

proc api {name prototype desc {notused x}} {
................................................................................
<tr><td> TEXT </td><td>    FLOAT </td><td> Use atof()</td></tr>
<tr><td> TEXT </td><td>    BLOB </td><td>  No change</td></tr>
<tr><td> BLOB </td><td>    INTEGER</td><td>Convert to TEXT then use atoi()</td></tr>
<tr><td> BLOB </td><td>    FLOAT </td><td> Convert to TEXT then use atof()</td></tr>
<tr><td> BLOB </td><td>    TEXT </td><td>  Add a \\000 terminator if needed</td></tr>
</table>
</blockquote>

  Note that when type conversions occur, pointers returned by prior
  calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
  sqlite3_column_text16() may be invalidated.  So, for example, if
  you initially call sqlite3_column_text() and get back a pointer to
  a UTF-8 string, then you call sqlite3_column_text16(), after the
  call to sqlite3_column_text16() the pointer returned by the prior
  call to sqlite3_column_text() will likely point to deallocated memory.
  Attempting to use the original pointer might lead to heap corruption
  or a segfault.  Note also that calls  to sqlite3_column_bytes()
  and sqlite3_column_bytes16() can also cause type conversion that
  and deallocate prior buffers.  Use these routines carefully.
}

api {} {
int sqlite3_column_count(sqlite3_stmt *pStmt);
} {
 Return the number of columns in the result set returned by the prepared
 SQL statement. This routine returns 0 if pStmt is an SQL statement