Make sure strings returned by sqlite3_value_text() and sqlite3_value_text16()
are always '\000'-terminated. (CVS 3391) FossilOrigin-Name: 2c63588b45f4e1ab9b9f1b72c901f3800433424a
This commit is contained in:
parent
f80ad49f72
commit
f0313813ec
15
manifest
15
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sbugs\sin\stest\sscripts\sso\sthat\sfulltest\swill\spass.\s(CVS\s3390)
|
||||
D 2006-09-02T22:14:59
|
||||
C Make\ssure\sstrings\sreturned\sby\ssqlite3_value_text()\sand\ssqlite3_value_text16()\nare\salways\s'\\000'-terminated.\s(CVS\s3391)
|
||||
D 2006-09-04T15:53:53
|
||||
F Makefile.in cabd42d34340f49260bc2a7668c38eba8d4cfd99
|
||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -91,7 +91,7 @@ F src/sqlite3ext.h 11a046b3519c4b9b7709e6d6a95c3a36366f684a
|
||||
F src/sqliteInt.h 259adce944cc3b28da1fa3df9beb9ba86017a45d
|
||||
F src/table.c d8817f43a6c6bf139487db161760b9e1e02da3f1
|
||||
F src/tclsqlite.c e029f739bed90071789fe81a226d53e97a80a4d8
|
||||
F src/test1.c cb3688f5d2094dc708a7959bd99aed411e096e49
|
||||
F src/test1.c c8c3b2fd9e71cda3e6598f84357734cfd4fb93e2
|
||||
F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
|
||||
F src/test3.c 85135c09560c48bdb0a23c9b890ab405486b8ec9
|
||||
F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
|
||||
@ -118,7 +118,7 @@ F src/vdbeInt.h e3eaab262b67b84474625cfc38aec1125c32834b
|
||||
F src/vdbeapi.c 81f531d7dc5c898131b02ef85f6c6144ab2892cf
|
||||
F src/vdbeaux.c 9fab61427a0741c9c123e8ff16e349b1f90397be
|
||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||
F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
|
||||
F src/vdbemem.c 26623176bf1c616aa478da958fac49502491a921
|
||||
F src/vtab.c 7fc0624c2bb6156c3d99e2ce706f2a5b54094e36
|
||||
F src/where.c 75a89957fcb8c068bec55caa4e9d2ed5fa0b0724
|
||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||
@ -234,6 +234,7 @@ F test/misc2.test 9740c2fb7e4a69b2bebd4c5fd9ba45ae27b27e98
|
||||
F test/misc3.test 7bd937e2c62bcc6be71939faf068d506467b1e03
|
||||
F test/misc4.test b043a05dea037cca5989f3ae09552fa16119bc80
|
||||
F test/misc5.test 83bceca3d38ed10ced00271e02b26b24795def83
|
||||
F test/misc6.test 6d1b1535ad9e8788334ac2462deec662a2f82c57
|
||||
F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
|
||||
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
||||
F test/null.test 9503e1f63e959544c006d9f01709c5b5eab67d54
|
||||
@ -395,7 +396,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||
P 7279ddd08444d54712f738d997c5d11f6af064c1
|
||||
R 0154a554f51203117c37cdba6d80f9d4
|
||||
P 367bd8376f323beb3148eab86ada1a3cb379ba3b
|
||||
R 65d3fac7dc50afc9b2c593fb5d16df61
|
||||
U drh
|
||||
Z 1d0c9fd6f6dadab65fcbce0df688ab5a
|
||||
Z 7a672874943fae922a528231fba04d93
|
||||
|
@ -1 +1 @@
|
||||
367bd8376f323beb3148eab86ada1a3cb379ba3b
|
||||
2c63588b45f4e1ab9b9f1b72c901f3800433424a
|
40
src/test1.c
40
src/test1.c
@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test1.c,v 1.218 2006/09/02 14:50:24 drh Exp $
|
||||
** $Id: test1.c,v 1.219 2006/09/04 15:53:53 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@ -442,6 +442,34 @@ static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** 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.
|
||||
*/
|
||||
@ -548,6 +576,10 @@ static int test_create_function(
|
||||
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
|
||||
@ -1417,6 +1449,7 @@ static int test_changes(
|
||||
** 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
|
||||
@ -1449,6 +1482,9 @@ static int test_bind(
|
||||
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 ){
|
||||
@ -3968,6 +4004,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
#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",
|
||||
|
@ -50,14 +50,6 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
|
||||
assert(rc==SQLITE_OK || rc==SQLITE_NOMEM);
|
||||
assert(rc==SQLITE_OK || pMem->enc!=desiredEnc);
|
||||
assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);
|
||||
|
||||
if( rc==SQLITE_NOMEM ){
|
||||
/*
|
||||
sqlite3VdbeMemRelease(pMem);
|
||||
pMem->flags = MEM_Null;
|
||||
pMem->z = 0;
|
||||
*/
|
||||
}
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
@ -127,22 +119,9 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
||||
** Make sure the given Mem is \u0000 terminated.
|
||||
*/
|
||||
int sqlite3VdbeMemNulTerminate(Mem *pMem){
|
||||
/* In SQLite, a string without a nul terminator occurs when a string
|
||||
** is loaded from disk (in this case the memory management is ephemeral),
|
||||
** or when it is supplied by the user as a bound variable or function
|
||||
** return value. Therefore, the memory management of the string must be
|
||||
** either ephemeral, static or controlled by a user-supplied destructor.
|
||||
*/
|
||||
assert(
|
||||
!(pMem->flags&MEM_Str) || /* it's not a string, or */
|
||||
(pMem->flags&MEM_Term) || /* it's nul term. already, or */
|
||||
(pMem->flags&(MEM_Ephem|MEM_Static)) || /* it's static or ephem, or */
|
||||
(pMem->flags&MEM_Dyn && pMem->xDel) /* external management */
|
||||
);
|
||||
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{
|
||||
@ -151,7 +130,11 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
|
||||
memcpy(z, pMem->z, pMem->n);
|
||||
z[pMem->n] = 0;
|
||||
z[pMem->n+1] = 0;
|
||||
pMem->xDel(pMem->z);
|
||||
if( pMem->xDel ){
|
||||
pMem->xDel(pMem->z);
|
||||
}else{
|
||||
sqliteFree(pMem->z);
|
||||
}
|
||||
pMem->xDel = 0;
|
||||
pMem->z = z;
|
||||
}
|
||||
@ -782,7 +765,9 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}else if( !(pVal->flags&MEM_Blob) ){
|
||||
sqlite3VdbeMemNulTerminate(pVal);
|
||||
}else{
|
||||
assert( (pVal->flags&MEM_Blob)==0 );
|
||||
sqlite3VdbeMemStringify(pVal, enc);
|
||||
assert( 0==(1&(int)pVal->z) );
|
||||
}
|
||||
|
45
test/misc6.test
Normal file
45
test/misc6.test
Normal file
@ -0,0 +1,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
|
Loading…
Reference in New Issue
Block a user