diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/func.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/src/func.c b/src/func.c index baedf178b..da6b872d4 100644 --- a/src/func.c +++ b/src/func.c @@ -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; |