From 4c8555fd4744bb488ecab7f29aa60f0d4217b3ac Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 25 Jun 2009 01:47:11 +0000 Subject: [PATCH] Improved handling of oversize string and blob errors. Other simplifications in support of full coverage testing. (CVS 6813) FossilOrigin-Name: 8b34076668f0f712de0fbbe9bc2e68d42797e1b2 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/main.c | 4 ++-- src/vdbe.c | 7 +++++-- src/vdbeapi.c | 27 +++++++++++++++++++++------ src/vdbemem.c | 19 ++++++++----------- test/sqllimits1.test | 4 ++-- 7 files changed, 49 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index 284e3450f8..5505310695 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sALWAYS()\smacro\sfrom\svdbe.c\sthat\ssometimes\sfails\son\sthread\stests.\s(CVS\s6812) -D 2009-06-24T13:16:04 +C Improved\shandling\sof\soversize\sstring\sand\sblob\serrors.\s\sOther\ssimplifications\nin\ssupport\sof\sfull\scoverage\stesting.\s(CVS\s6813) +D 2009-06-25T01:47:12 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 8b8fb7823264331210cddf103831816c286ba446 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -125,7 +125,7 @@ F src/insert.c 94e51344e01aea6be43e95cd24e8baa014d8c3d6 F src/journal.c e00df0c0da8413ab6e1bb7d7cab5665d4a9000d0 F src/legacy.c 9a56cf126ceee332b56061bf16bd0fb4ff9e26c0 F src/loadext.c 0e88a335665db0b2fb4cece3e49dcb65d832635a -F src/main.c 120d65f0c2d011b0d7f373680a913b84819b2f92 +F src/main.c db6b0aeb37d345c5cd037e6b218bd726b8d76230 F src/malloc.c 7b3b6423f5b355e5d649b91e16ef252d610bcf19 F src/mem0.c f2f84062d1f35814d6535c9f9e33de3bfb3b132c F src/mem1.c e6d5c23941288df8191b8a98c28e3f57771e2270 @@ -203,13 +203,13 @@ F src/update.c b58db45e40f11082281d6f94137cd3b5657771d9 F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff F src/util.c 861d5b5c58be4921f0a254489ea94cb15f550ef8 F src/vacuum.c 0e14f371ea3326c6b8cfba257286d798cd20db59 -F src/vdbe.c 5c4a595077338752245dc51d34ad6c3c47194d96 +F src/vdbe.c e7831536ddb11b14ce29f62a17e0e3860944d570 F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a F src/vdbeInt.h 831c254a6eef237ef4664c8381a0137586567007 -F src/vdbeapi.c 73bd1d2c57b953bc688d1d8c84b24c2084c2aec7 +F src/vdbeapi.c 0ab8ada7260b32031ca97f338caecf0812460624 F src/vdbeaux.c 2801d0183c52e3739abae28b861b4415418e999a F src/vdbeblob.c c25d7e7bc6d5917feeb17270bd275fa771f26e5c -F src/vdbemem.c d244e09b5ca8afc3e1cea3ccf0b1a3fa48926614 +F src/vdbemem.c 1618f685d19b4bcc96e40b3c478487bafd2ae246 F src/vtab.c 98fbffc5efe68d8107511dec0a650efc7daa9446 F src/walker.c 1edca756275f158b80f20eb6f104c8d3fcc96a04 F src/where.c cf0d091748c2fa6f7df96e5b08d2db26fd2eb437 @@ -555,7 +555,7 @@ F test/speed3.test e312d7e442a5047d730569fdae2ba99bc94e1a13 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/sqllimits1.test 06c2c6cbdbfa03af15a1a61ba8cae675d9c8fe31 +F test/sqllimits1.test e90a0ed94452076f6a10209d378e06b5f75ef0a0 F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a @@ -737,7 +737,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746 -P 3b8f9dec24d06865455a75587bbfc199c19c6215 -R 420b3ba279f0ef4dc395350d7f56e7a5 +P 52eac078c7080519911599e19819cbec475de6d6 +R 6ae3c2ac4bc1cff164725bbb4ce26ae6 U drh -Z f0691dda6c10f296a0eff99d0e104f07 +Z bf5a48beb2bf6181503a39e1dcbe0d85 diff --git a/manifest.uuid b/manifest.uuid index 31f2cb4252..6954148441 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -52eac078c7080519911599e19819cbec475de6d6 \ No newline at end of file +8b34076668f0f712de0fbbe9bc2e68d42797e1b2 \ No newline at end of file diff --git a/src/main.c b/src/main.c index f1fd8f6d07..273ea06346 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.558 2009/06/19 14:06:03 drh Exp $ +** $Id: main.c,v 1.559 2009/06/25 01:47:12 drh Exp $ */ #include "sqliteInt.h" @@ -749,7 +749,7 @@ const char *sqlite3ErrStr(int rc){ /* SQLITE_PROTOCOL */ 0, /* SQLITE_EMPTY */ "table contains no data", /* SQLITE_SCHEMA */ "database schema has changed", - /* SQLITE_TOOBIG */ "String or BLOB exceeded size limit", + /* SQLITE_TOOBIG */ "string or blob too big", /* SQLITE_CONSTRAINT */ "constraint failed", /* SQLITE_MISMATCH */ "datatype mismatch", /* SQLITE_MISUSE */ "library routine called out of sequence", diff --git a/src/vdbe.c b/src/vdbe.c index c13c8685cb..62f4946580 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.863 2009/06/24 13:16:04 drh Exp $ +** $Id: vdbe.c,v 1.864 2009/06/25 01:47:12 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -4924,7 +4924,7 @@ case OP_AggFinal: { pMem = &p->aMem[pOp->p1]; assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); - if( rc==SQLITE_ERROR ){ + if( rc ){ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem)); } sqlite3VdbeChangeEncoding(pMem, encoding); @@ -5233,6 +5233,9 @@ case OP_VColumn: { sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = pVtab->zErrMsg; pVtab->zErrMsg = 0; + if( sContext.isError ){ + rc = sContext.isError; + } /* Copy the result of the function to the P3 register. We ** do this regardless of whether or not an error occurred to ensure any diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 45eeda0667..caaebd8160 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -13,7 +13,7 @@ ** This file contains code use to implement APIs that are part of the ** VDBE. ** -** $Id: vdbeapi.c,v 1.166 2009/06/19 14:06:03 drh Exp $ +** $Id: vdbeapi.c,v 1.167 2009/06/25 01:47:12 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -155,7 +155,22 @@ int sqlite3_value_type(sqlite3_value* pVal){ /**************************** sqlite3_result_ ******************************* ** The following routines are used by user-defined functions to specify ** the function result. +** +** The setStrOrError() funtion calls sqlite3VdbeMemSetStr() to store the +** result as a string or blob but if the string or blob is too large, it +** then sets the error code to SQLITE_TOOBIG */ +static void setResultStrOrError( + sqlite3_context *pCtx, /* Function context */ + const char *z, /* String pointer */ + int n, /* Bytes in string, or negative */ + u8 enc, /* Encoding of z. 0 for BLOBs */ + void (*xDel)(void*) /* Destructor function */ +){ + if( sqlite3VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(pCtx); + } +} void sqlite3_result_blob( sqlite3_context *pCtx, const void *z, @@ -164,7 +179,7 @@ void sqlite3_result_blob( ){ assert( n>=0 ); assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel); + setResultStrOrError(pCtx, z, n, 0, xDel); } void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); @@ -201,7 +216,7 @@ void sqlite3_result_text( void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); } #ifndef SQLITE_OMIT_UTF16 void sqlite3_result_text16( @@ -211,7 +226,7 @@ void sqlite3_result_text16( void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); } void sqlite3_result_text16be( sqlite3_context *pCtx, @@ -220,7 +235,7 @@ void sqlite3_result_text16be( void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16BE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); } void sqlite3_result_text16le( sqlite3_context *pCtx, @@ -229,7 +244,7 @@ void sqlite3_result_text16le( void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16LE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel); } #endif /* SQLITE_OMIT_UTF16 */ void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ diff --git a/src/vdbemem.c b/src/vdbemem.c index d92b496ea7..9a79c3c912 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -15,7 +15,7 @@ ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value ** -** $Id: vdbemem.c,v 1.149 2009/06/22 19:05:41 drh Exp $ +** $Id: vdbemem.c,v 1.150 2009/06/25 01:47:12 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -96,7 +96,7 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){ } } - if( preserve && pMem->z && pMem->zMalloc && pMem->z!=pMem->zMalloc ){ + if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){ memcpy(pMem->zMalloc, pMem->z, pMem->n); } if( pMem->flags&MEM_Dyn && pMem->xDel ){ @@ -245,7 +245,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){ */ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ int rc = SQLITE_OK; - if( pFunc && pFunc->xFinalize ){ + if( ALWAYS(pFunc && pFunc->xFinalize) ){ sqlite3_context ctx; assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -258,7 +258,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel ); sqlite3DbFree(pMem->db, pMem->zMalloc); memcpy(pMem, &ctx.s, sizeof(ctx.s)); - rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK); + rc = ctx.isError; } return rc; } @@ -533,12 +533,9 @@ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ void sqlite3VdbeMemSetRowSet(Mem *pMem){ sqlite3 *db = pMem->db; assert( db!=0 ); - if( pMem->flags & MEM_RowSet ){ - sqlite3RowSetClear(pMem->u.pRowSet); - }else{ - sqlite3VdbeMemRelease(pMem); - pMem->zMalloc = sqlite3DbMallocRaw(db, 64); - } + assert( (pMem->flags & MEM_RowSet)==0 ); + sqlite3VdbeMemRelease(pMem); + pMem->zMalloc = sqlite3DbMallocRaw(db, 64); if( db->mallocFailed ){ pMem->flags = MEM_Null; }else{ @@ -880,7 +877,7 @@ int sqlite3VdbeMemFromBtree( } assert( zData!=0 ); - if( offset+amt<=available && ((pMem->flags&MEM_Dyn)==0 || pMem->xDel) ){ + if( offset+amt<=available && (pMem->flags&MEM_Dyn)==0 ){ sqlite3VdbeMemRelease(pMem); pMem->z = &zData[offset]; pMem->flags = MEM_Blob|MEM_Ephem; diff --git a/test/sqllimits1.test b/test/sqllimits1.test index 933a94f942..bf4a262678 100644 --- a/test/sqllimits1.test +++ b/test/sqllimits1.test @@ -12,7 +12,7 @@ # This file contains tests to verify that the limits defined in # sqlite source file limits.h are enforced. # -# $Id: sqllimits1.test,v 1.32 2009/06/12 12:04:16 drh Exp $ +# $Id: sqllimits1.test,v 1.33 2009/06/25 01:47:12 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -404,7 +404,7 @@ do_test sqllimits1-6.1 { set N [expr {(50000 / [string length $tail])+1}] append sql [string repeat $tail $N] catchsql $sql -} {1 {String or BLOB exceeded size limit}} +} {1 {string or blob too big}} do_test sqllimits1-6.3 { sqlite3_limit db SQLITE_LIMIT_SQL_LENGTH 50000 set sql "SELECT 1 WHERE 1==1"