]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make sure strings returned by sqlite3_value_text() and sqlite3_value_text16()
authordrh <drh@noemail.net>
Mon, 4 Sep 2006 15:53:53 +0000 (15:53 +0000)
committerdrh <drh@noemail.net>
Mon, 4 Sep 2006 15:53:53 +0000 (15:53 +0000)
are always '\000'-terminated. (CVS 3391)

FossilOrigin-Name: 2c63588b45f4e1ab9b9f1b72c901f3800433424a

manifest
manifest.uuid
src/test1.c
src/vdbemem.c
test/misc6.test [new file with mode: 0644]

index ba574cb32a2e133a0fd4164df41daded855754f0..5d8f3507fd7db6aa9eb06a68b97d27b8ba71184b 100644 (file)
--- a/manifest
+++ b/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
index aa5777c4ac9d0fd246f6ed462a226df7a040b25a..53c7fabd35c68af6c7fbf7d519276b82a8067b95 100644 (file)
@@ -1 +1 @@
-367bd8376f323beb3148eab86ada1a3cb379ba3b
\ No newline at end of file
+2c63588b45f4e1ab9b9f1b72c901f3800433424a
\ No newline at end of file
index e1b80fefa74657b6e38896b485558f8141fbafd0..39de718e9f1d8637e2c0d2821e0dc128553b512a 100644 (file)
@@ -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",
index 51cd6827faffd3c46580c9a7432574417b40c519..18aef149b629a7714b5bd628df92fc89bd7fb4a8 100644 (file)
@@ -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) );
   }
diff --git a/test/misc6.test b/test/misc6.test
new file mode 100644 (file)
index 0000000..d751de8
--- /dev/null
@@ -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