]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
In the built-in SQL function implementations, improve some comments, fix
authordrh <drh@noemail.net>
Thu, 2 Apr 2009 10:16:17 +0000 (10:16 +0000)
committerdrh <drh@noemail.net>
Thu, 2 Apr 2009 10:16:17 +0000 (10:16 +0000)
an off-by-one error in detecting over-size strings, and add testcase()
macros to verify that boundary values have been tested. (CVS 6434)

FossilOrigin-Name: 868a487f5fd7c795e04a08de36a85ba1e06bc8c6

manifest
manifest.uuid
src/func.c

index edf79d2a779bd8153b6f28dcfd7ea612773213fc..beaec0cb08a61fa21b34532f844e26785cce90b9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enforce\sthe\srun-time\ssqlite3_limit()\slength\slimit\son\szeroblob(),\snot\sjust\nthe\scompile-time\sSQLITE_MAX_LENGTH\slimit.\s(CVS\s6433)
-D 2009-04-02T09:07:13
+C In\sthe\sbuilt-in\sSQL\sfunction\simplementations,\simprove\ssome\scomments,\sfix\nan\soff-by-one\serror\sin\sdetecting\sover-size\sstrings,\sand\sadd\stestcase()\nmacros\sto\sverify\sthat\sboundary\svalues\shave\sbeen\stested.\s(CVS\s6434)
+D 2009-04-02T10:16:18
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -113,7 +113,7 @@ F src/date.c e6263ed8950642f593cb1a2cc8a73dd726cc7888
 F src/delete.c eb1066b2f35489fee46ad765d2b66386fc7d8adf
 F src/expr.c 14853cd56107292de6af664a24c6255111a4257d
 F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
-F src/func.c ac81b4ff36e4e52327097dfcf6a1ba90d9cb63f7
+F src/func.c 13b7a7ecf4f3426a368e751d0c3fbdcf567baf69
 F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c
 F src/hash.c 5824e6ff7ba78cd34c8d6cd724367713583e5b55
 F src/hash.h 28f38ebb1006a5beedcb013bcdfe31befe7437ae
@@ -714,7 +714,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P ca3aa3ba7d751be1c2bcd100a203cd9c794a6cef
-R f0264cae48013af5fa04e1ada66682c2
+P a04f9e7959325da18f66a1aa4ead1c50993807cb
+R c982e3384ed11aa8534165a34216b1da
 U drh
-Z 3903933557343f546c355318654d5fcd
+Z 1b80b4935022b19a2dfaa3a1e5ddbc5f
index 46e0bf15c577d4c6eac31f742f5905b7d96b6f61..b376b040b80af15596201731586a66ea78664ac8 100644 (file)
@@ -1 +1 @@
-a04f9e7959325da18f66a1aa4ead1c50993807cb
\ No newline at end of file
+868a487f5fd7c795e04a08de36a85ba1e06bc8c6
\ No newline at end of file
index baedf178b3e1c66dae6e14a5a0c7e3788712309c..da6b872d46e006b838d2a90d3904199212b33569 100644 (file)
@@ -16,7 +16,7 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: func.c,v 1.227 2009/04/02 09:07:13 drh Exp $
+** $Id: func.c,v 1.228 2009/04/02 10:16:18 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdlib.h>
@@ -266,12 +266,17 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
 /*
 ** Allocate nByte bytes of space using sqlite3_malloc(). If the
 ** allocation fails, call sqlite3_result_error_nomem() to notify
-** the database handle that malloc() has failed.
+** the database handle that malloc() has failed and return NULL.
+** If nByte is larger than the maximum string or blob length, then
+** raise an SQLITE_TOOBIG exception and return NULL.
 */
 static void *contextMalloc(sqlite3_context *context, i64 nByte){
   char *z;
+  sqlite3 *db = sqlite3_context_db_handle(context);
   assert( nByte>0 );
-  if( nByte>sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH] ){
+  testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
+  testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
+  if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
     sqlite3_result_error_toobig(context);
     z = 0;
   }else{
@@ -624,6 +629,7 @@ static void likeFunc(
 ){
   const unsigned char *zA, *zB;
   int escape = 0;
+  int nPat;
   sqlite3 *db = sqlite3_context_db_handle(context);
 
   zB = sqlite3_value_text(argv[0]);
@@ -632,8 +638,10 @@ static void likeFunc(
   /* Limit the length of the LIKE or GLOB pattern to avoid problems
   ** of deep recursion and N*N behavior in patternCompare().
   */
-  if( sqlite3_value_bytes(argv[0]) >
-        db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
+  nPat = sqlite3_value_bytes(argv[0]);
+  testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] );
+  testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
+  if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
     sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
     return;
   }
@@ -809,10 +817,13 @@ static void zeroblobFunc(
   sqlite3_value **argv
 ){
   i64 n;
+  sqlite3 *db = sqlite3_context_db_handle(context);
   assert( argc==1 );
   UNUSED_PARAMETER(argc);
   n = sqlite3_value_int64(argv[0]);
-  if( n>sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH] ){
+  testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH] );
+  testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
+  if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
     sqlite3_result_error_toobig(context);
   }else{
     sqlite3_result_zeroblob(context, (int)n);
@@ -878,7 +889,9 @@ static void replaceFunc(
       u8 *zOld;
       sqlite3 *db = sqlite3_context_db_handle(context);
       nOut += nRep - nPattern;
-      if( nOut>=db->aLimit[SQLITE_LIMIT_LENGTH] ){
+      testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
+      testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
+      if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
         sqlite3_result_error_toobig(context);
         sqlite3DbFree(db, zOut);
         return;
@@ -962,7 +975,7 @@ static void trimFunc(
         int len = 0;
         for(i=0; i<nChar; i++){
           len = aLen[i];
-          if( memcmp(zIn, azChar[i], len)==0 ) break;
+          if( len<=nIn && memcmp(zIn, azChar[i], len)==0 ) break;
         }
         if( i>=nChar ) break;
         zIn += len;