Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Make sure strings returned by sqlite3_value_text() and sqlite3_value_text16() are always '\000'-terminated. (CVS 3391) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2c63588b45f4e1ab9b9f1b72c901f380 |
User & Date: | drh 2006-09-04 15:53:53.000 |
Context
2006-09-04
| ||
18:54 | Fix a bug in the new misc6.test script. Fix error messages when not compiled with memory debugging enabled. Ticket #1957. (CVS 3392) (check-in: 9fb92024bf user: drh tags: trunk) | |
15:53 | Make sure strings returned by sqlite3_value_text() and sqlite3_value_text16() are always '\000'-terminated. (CVS 3391) (check-in: 2c63588b45 user: drh tags: trunk) | |
2006-09-02
| ||
22:14 | Fix bugs in test scripts so that fulltest will pass. (CVS 3390) (check-in: 367bd8376f user: drh tags: trunk) | |
Changes
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.219 2006/09/04 15:53:53 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
437 438 439 440 441 442 443 444 445 446 447 448 449 450 | if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){ sqlite3_result_text(context, (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]), SQLITE_TRANSIENT); break; } } } /* ** A structure into which to accumulate text. */ struct dstr { int nAlloc; /* Space allocated */ int nUsed; /* Space used */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){ sqlite3_result_text(context, (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]), SQLITE_TRANSIENT); break; } } } /* ** These are test functions. hex8() interprets its argument as ** UTF8 and returns a hex encoding. hex16le() interprets its argument ** as UTF16le and returns a hex encoding. */ static void hex8Func(sqlite3_context *p, int argc, sqlite3_value **argv){ const unsigned char *z; int i; char zBuf[200]; z = sqlite3_value_text(argv[0]); for(i=0; i<sizeof(zBuf)/2 - 2 && z[i]; i++){ sprintf(&zBuf[i*2], "%02x", z[i]&0xff); } zBuf[i*2] = 0; sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT); } static void hex16Func(sqlite3_context *p, int argc, sqlite3_value **argv){ const unsigned short int *z; int i; char zBuf[400]; z = sqlite3_value_text16(argv[0]); for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){ sprintf(&zBuf[i*4], "%04x", z[i]&0xff); } zBuf[i*4] = 0; sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT); } /* ** A structure into which to accumulate text. */ struct dstr { int nAlloc; /* Space allocated */ int nUsed; /* Space used */ |
︙ | ︙ | |||
544 545 546 547 548 549 550 551 552 553 554 555 556 557 | Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, ifnullFunc, 0, 0); #ifndef SQLITE_OMIT_UTF16 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also ** because it is not tested anywhere else. */ if( rc==SQLITE_OK ){ sqlite3_value *pVal; #ifdef SQLITE_MEMDEBUG | > > > > | 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 | Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, ifnullFunc, 0, 0); rc = sqlite3_create_function(db, "hex8", 1, SQLITE_ANY, 0, hex8Func, 0, 0); rc = sqlite3_create_function(db, "hex16", 1, SQLITE_ANY, 0, hex16Func, 0, 0); #ifndef SQLITE_OMIT_UTF16 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also ** because it is not tested anywhere else. */ if( rc==SQLITE_OK ){ sqlite3_value *pVal; #ifdef SQLITE_MEMDEBUG |
︙ | ︙ | |||
1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 | } /* ** This is the "static_bind_value" that variables are bound to when ** the FLAG option of sqlite3_bind is "static" */ static char *sqlite_static_bind_value = 0; /* ** Usage: sqlite3_bind VM IDX VALUE FLAGS ** ** Sets the value of the IDX-th occurance of "?" in the original SQL ** string. VALUE is the new value. If FLAGS=="null" then VALUE is ** ignored and the value is set to NULL. If FLAGS=="static" then | > | 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 | } /* ** This is the "static_bind_value" that variables are bound to when ** the FLAG option of sqlite3_bind is "static" */ static char *sqlite_static_bind_value = 0; static int sqlite_static_bind_nbyte = 0; /* ** Usage: sqlite3_bind VM IDX VALUE FLAGS ** ** Sets the value of the IDX-th occurance of "?" in the original SQL ** string. VALUE is the new value. If FLAGS=="null" then VALUE is ** ignored and the value is set to NULL. If FLAGS=="static" then |
︙ | ︙ | |||
1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 | } if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR; if( strcmp(argv[4],"null")==0 ){ rc = sqlite3_bind_null(pStmt, idx); }else if( strcmp(argv[4],"static")==0 ){ rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0); }else if( strcmp(argv[4],"normal")==0 ){ rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT); }else if( strcmp(argv[4],"blob10")==0 ){ rc = sqlite3_bind_text(pStmt, idx, "abc\000xyz\000pq", 10, SQLITE_STATIC); }else{ Tcl_AppendResult(interp, "4th argument should be " "\"null\" or \"static\" or \"normal\"", 0); | > > > | 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 | } if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR; if( strcmp(argv[4],"null")==0 ){ rc = sqlite3_bind_null(pStmt, idx); }else if( strcmp(argv[4],"static")==0 ){ rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0); }else if( strcmp(argv[4],"static-nbytes")==0 ){ rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, sqlite_static_bind_nbyte, 0); }else if( strcmp(argv[4],"normal")==0 ){ rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT); }else if( strcmp(argv[4],"blob10")==0 ){ rc = sqlite3_bind_text(pStmt, idx, "abc\000xyz\000pq", 10, SQLITE_STATIC); }else{ Tcl_AppendResult(interp, "4th argument should be " "\"null\" or \"static\" or \"normal\"", 0); |
︙ | ︙ | |||
3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 | #endif #ifndef SQLITE_OMIT_DISKIO Tcl_LinkVar(interp, "sqlite_opentemp_count", (char*)&sqlite3_opentemp_count, TCL_LINK_INT); #endif Tcl_LinkVar(interp, "sqlite_static_bind_value", (char*)&sqlite_static_bind_value, TCL_LINK_STRING); Tcl_LinkVar(interp, "sqlite_temp_directory", (char*)&sqlite3_temp_directory, TCL_LINK_STRING); Tcl_LinkVar(interp, "bitmask_size", (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); #if OS_UNIX Tcl_LinkVar(interp, "sqlite_sync_count", (char*)&sqlite3_sync_count, TCL_LINK_INT); | > > | 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 | #endif #ifndef SQLITE_OMIT_DISKIO Tcl_LinkVar(interp, "sqlite_opentemp_count", (char*)&sqlite3_opentemp_count, TCL_LINK_INT); #endif Tcl_LinkVar(interp, "sqlite_static_bind_value", (char*)&sqlite_static_bind_value, TCL_LINK_STRING); Tcl_LinkVar(interp, "sqlite_static_bind_nbyte", (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_temp_directory", (char*)&sqlite3_temp_directory, TCL_LINK_STRING); Tcl_LinkVar(interp, "bitmask_size", (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); #if OS_UNIX Tcl_LinkVar(interp, "sqlite_sync_count", (char*)&sqlite3_sync_count, TCL_LINK_INT); |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
46 47 48 49 50 51 52 | /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, ** then the encoding of the value may not have changed. */ rc = sqlite3VdbeMemTranslate(pMem, desiredEnc); assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); | < < < < < < < < | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, ** then the encoding of the value may not have changed. */ rc = sqlite3VdbeMemTranslate(pMem, desiredEnc); assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); return rc; #endif } /* ** Make the given Mem object MEM_Dyn. ** |
︙ | ︙ | |||
123 124 125 126 127 128 129 | return SQLITE_OK; } /* ** Make sure the given Mem is \u0000 terminated. */ int sqlite3VdbeMemNulTerminate(Mem *pMem){ | < < < < < < < < < < < < < > | > > > | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | return SQLITE_OK; } /* ** Make sure the given Mem is \u0000 terminated. */ int sqlite3VdbeMemNulTerminate(Mem *pMem){ if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){ return SQLITE_OK; /* Nothing to do */ } if( pMem->flags & (MEM_Static|MEM_Ephem) ){ return sqlite3VdbeMemMakeWriteable(pMem); }else{ char *z = sqliteMalloc(pMem->n+2); if( !z ) return SQLITE_NOMEM; memcpy(z, pMem->z, pMem->n); z[pMem->n] = 0; z[pMem->n+1] = 0; if( pMem->xDel ){ pMem->xDel(pMem->z); }else{ sqliteFree(pMem->z); } pMem->xDel = 0; pMem->z = z; } return SQLITE_OK; } /* |
︙ | ︙ | |||
778 779 780 781 782 783 784 | sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){ assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ return 0; } } | > > | | 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 | sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){ assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ return 0; } } sqlite3VdbeMemNulTerminate(pVal); }else{ assert( (pVal->flags&MEM_Blob)==0 ); sqlite3VdbeMemStringify(pVal, enc); assert( 0==(1&(int)pVal->z) ); } assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || sqlite3MallocFailed() ); if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ return pVal->z; }else{ |
︙ | ︙ |
Added test/misc6.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 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 45 | # 2006 September 4 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # 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. # # This file implements tests to make sure sqlite3_value_text() # always returns a null-terminated string. # # $Id: misc6.test,v 1.1 2006/09/04 15:53:53 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test misc6-1.1 { set DB [sqlite3_connection_pointer db] sqlite3_create_function $DB set STMT [sqlite3_prepare $DB {SELECT hex8(?)} -1 DUMMY] set sqlite_static_bind_value {0123456789} set sqlite_static_bind_nbyte 5 sqlite_bind $STMT 1 {} static-nbytes sqlite3_step $STMT } SQLITE_ROW do_test misc6-1.2 { sqlite3_column_text $STMT 0 } {3031323334} do_test misc6-1.3 { sqlite3_finalize $STMT set STMT [sqlite3_prepare $DB {SELECT hex16(?)} -1 DUMMY] set sqlite_static_bind_value {0123456789} set sqlite_static_bind_nbyte 5 sqlite_bind $STMT 1 {} static-nbytes sqlite3_step $STMT } SQLITE_ROW do_test misc6-1.4 { sqlite3_column_text $STMT 0 } {00300031003200330034} finish_test |