diff --git a/manifest b/manifest index 270690a99d..f7570a5496 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\sthe\stest\slogic\sintroduced\sby\scheck-in\s(3928).\s(CVS\s3942) -D 2007-05-08T11:27:16 +C Begin\sadding\scode\sto\sexplicitly\slimit\sthe\ssize\sof\sstrings\sand\sblobs.\s(CVS\s3943) +D 2007-05-08T12:12:17 F Makefile.in 87b200ad9970907f76df734d29dff3d294c10935 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -71,14 +71,14 @@ F src/date.c c34a9c86ffd6da4cb3903ea038d977ec539d07e2 F src/delete.c 5c0d89b3ef7d48fe1f5124bfe8341f982747fe29 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b F src/expr.c 2f0f9f89efe9170e5e6ca5d5e93a9d5896fff5ac -F src/func.c af70f33e3f68aec76c9357c3f128265eb86a3304 +F src/func.c 755a8c58cd05d290fa2388bd471f8781afe2c1c7 F src/hash.c 67b23e14f0257b69a3e8aa663e4eeadc1a2b6fd5 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564 F src/insert.c e595ca26805dfb3a9ebaabc28e7947c479f3b14d F src/legacy.c 388c71ad7fbcd898ba1bcbfc98a3ac954bfa5d01 F src/limits.h 74b7f201cf75d0cffcfc40757de0e4caeeb1fca1 F src/loadext.c afe4f4755dc49c36ef505748bbdddecb9f1d02a2 -F src/main.c 00e01d7912e40b81546f4e6ddf7bda54b430dbd1 +F src/main.c 35b340716319e88817493172aa63abe8be13b543 F src/malloc.c b89e31258a85158d15795bf87ae3ba007e56329b F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217 F src/os.c 4650e98aadd27abfe1698ff58edf6893c58d4881 @@ -132,14 +132,14 @@ F src/update.c 3359041db390a8f856d67272f299600e2104f350 F src/utf.c e64a48bc21aa973eb622dd47da87d56a4cdcf528 F src/util.c 5eff5cec4ae43490ca3fb97f10a25aac1a5f9b55 F src/vacuum.c 8bd895d29e7074e78d4e80f948e35ddc9cf2beef -F src/vdbe.c a839d32a1b95d994cfcf3545d4b6c3d9ec6d4ce6 +F src/vdbe.c c942cb1882954e029e9788e07b709d12fba7ea47 F src/vdbe.h 0025259af1939fb264a545816c69e4b5b8d52691 -F src/vdbeInt.h cb02cbbceddf3b40d49012e9f41576f17bcbec97 +F src/vdbeInt.h 77a17f1a8bcbbb660bf4515c78d74280b4e8be5c F src/vdbeapi.c 37d793559390bec8a00c556f651f21b5f9e589af F src/vdbeaux.c c432e17fef6efaf102d507e979cee4e47f6ceac4 F src/vdbeblob.c 57127dc9fd01f3fded2eab30b5842f5f96b1c42b F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f -F src/vdbemem.c ba98f8572ec4609846b368fa7580db178022f1bb +F src/vdbemem.c 44b71bf94b88a75b638ceed402e85a58053bbb64 F src/vtab.c c5ebebf615b2f29499fbe97a584c4bb342632aa0 F src/where.c f3920748cc650fc25ac916215500bdb90dee568e F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617 @@ -485,7 +485,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 93b623b232a43f78d2c90bfa2389dd5b28ad7280 -R f8306b3bcfa5052b18e3cea33a102c6a +P 47d1678d2d795196e51b7f0f185198f2b338636b +R b785353f241f93b7ecd6b37b57a11d53 U drh -Z daa5ba85be62426bc10ead0ba639c7a9 +Z 4ce6f9af2bdc06bd49e2cf4b9fd38709 diff --git a/manifest.uuid b/manifest.uuid index 04793f299d..820263f9e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47d1678d2d795196e51b7f0f185198f2b338636b \ No newline at end of file +031a5915b68ec6827fee38b8b9dc74a9e0e09302 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 2403b3d566..5197ccd181 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.146 2007/05/07 19:31:16 drh Exp $ +** $Id: func.c,v 1.147 2007/05/08 12:12:17 drh Exp $ */ #include "sqliteInt.h" #include @@ -156,7 +156,8 @@ static void substrFunc( const unsigned char *z; const unsigned char *z2; int i; - int p1, p2, len; + int len; + i64 p1, p2; assert( argc==3 ); z = sqlite3_value_text(argv[0]); @@ -296,7 +297,13 @@ static void randomBlob( unsigned char *p; assert( argc==1 ); n = sqlite3_value_int(argv[0]); - if( n<1 ) n = 1; + if( n<1 ){ + n = 1; + } + if( n>SQLITE_MAX_LENGTH ){ + sqlite3_result_error(context, "randomblob() too large", -1); + return; + } p = sqliteMalloc(n); if( p ){ sqlite3Randomness(n, p); @@ -616,6 +623,10 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ int nBlob = sqlite3_value_bytes(argv[0]); char const *zBlob = sqlite3_value_blob(argv[0]); + if( 2*nBlob+4>SQLITE_MAX_LENGTH ){ + sqlite3_result_error(context, "BLOB too big to quote", -1); + return; + } zText = (char *)sqliteMalloc((2*nBlob)+4); if( !zText ){ sqlite3_result_error(context, "out of memory", -1); @@ -635,12 +646,17 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ break; } case SQLITE_TEXT: { - int i,j,n; + int i,j; + u64 n; const unsigned char *zArg = sqlite3_value_text(argv[0]); char *z; if( zArg==0 ) return; - for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } + for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } + if( i+n+3>SQLITE_MAX_LENGTH ){ + sqlite3_result_error(context, "string too big to quote", -1); + return; + } z = sqliteMalloc( i+n+3 ); if( z==0 ) return; z[0] = '\''; @@ -672,6 +688,10 @@ static void hexFunc( char *zHex, *z; assert( argc==1 ); n = sqlite3_value_bytes(argv[0]); + if( n*2+1>SQLITE_MAX_LENGTH ){ + sqlite3_result_error(context, "BLOB too big to convert to hex", -1); + return; + } pBlob = sqlite3_value_blob(argv[0]); z = zHex = sqlite3_malloc(n*2 + 1); if( zHex==0 ) return; diff --git a/src/main.c b/src/main.c index 6e91221042..9f92bd6dff 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.374 2007/05/08 01:08:49 drh Exp $ +** $Id: main.c,v 1.375 2007/05/08 12:12:17 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -270,6 +270,7 @@ const char *sqlite3ErrStr(int rc){ case SQLITE_CANTOPEN: z = "unable to open database file"; break; case SQLITE_EMPTY: z = "table contains no data"; break; case SQLITE_SCHEMA: z = "database schema has changed"; break; + case SQLITE_TOOBIG: z = "String or BLOB exceeded size limit"; break; case SQLITE_CONSTRAINT: z = "constraint failed"; break; case SQLITE_MISMATCH: z = "datatype mismatch"; break; case SQLITE_MISUSE: z = "library routine called out of sequence";break; diff --git a/src/vdbe.c b/src/vdbe.c index fef1993b4b..248103c348 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.608 2007/05/08 01:08:49 drh Exp $ +** $Id: vdbe.c,v 1.609 2007/05/08 12:12:17 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -737,6 +737,8 @@ case OP_String8: { /* same as TK_STRING */ assert( pOp->p3!=0 ); pOp->opcode = OP_String; pOp->p1 = strlen(pOp->p3); + assert( SQLITE_MAX_SQL_LENGTH < SQLITE_MAX_LENGTH ); + assert( pOp->p1 < SQLITE_MAX_LENGTH ); #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ @@ -752,6 +754,7 @@ case OP_String8: { /* same as TK_STRING */ pOp->p3type = P3_DYNAMIC; pOp->p3 = pTos->z; pOp->p1 = pTos->n; + assert( pOp->p1 < SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ break; } #endif @@ -763,6 +766,7 @@ case OP_String8: { /* same as TK_STRING */ ** The string value P3 of length P1 (bytes) is pushed onto the stack. */ case OP_String: { + assert( pOp->p1 < SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ pTos++; assert( pOp->p3!=0 ); pTos->flags = MEM_Str|MEM_Static|MEM_Term; @@ -796,6 +800,8 @@ case OP_Null: { case OP_HexBlob: { /* same as TK_BLOB */ pOp->opcode = OP_Blob; pOp->p1 = strlen(pOp->p3)/2; + assert( SQLITE_MAX_SQL_LENGTH < SQLITE_MAX_LENGTH ); + assert( pOp->p1 < SQLITE_MAX_LENGTH ); if( pOp->p1 ){ char *zBlob = sqlite3HexToBlob(pOp->p3); if( !zBlob ) goto no_mem; @@ -826,6 +832,7 @@ case OP_HexBlob: { /* same as TK_BLOB */ */ case OP_Blob: { pTos++; + assert( pOp->p1 < SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ sqlite3VdbeMemSetStr(pTos, pOp->p3, pOp->p1, 0, 0); break; } @@ -842,8 +849,13 @@ case OP_Blob: { */ case OP_Variable: { int j = pOp->p1 - 1; + Mem *pVar; assert( j>=0 && jnVar ); + pVar = &p->aVar[j]; + if( sqlite3VdbeMemTooBig(pVar) ){ + goto too_big; + } pTos++; sqlite3VdbeMemShallowCopy(pTos, &p->aVar[j], MEM_Static); break; @@ -998,7 +1010,7 @@ case OP_Callback: { /* no-push */ */ case OP_Concat: { /* same as TK_CONCAT */ char *zNew; - int nByte; + i64 nByte; int nField; int i, j; Mem *pTerm; @@ -1031,6 +1043,9 @@ case OP_Concat: { /* same as TK_CONCAT */ /* Otherwise malloc() space for the result and concatenate all the ** stack values. */ + if( nByte+2>SQLITE_MAX_LENGTH ){ + goto too_big; + } zNew = sqliteMallocRaw( nByte+2 ); if( zNew==0 ) goto no_mem; j = 0; @@ -1274,6 +1289,9 @@ case OP_Function: { pTos++; pTos->flags = 0; sqlite3VdbeMemMove(pTos, &ctx.s); + if( sqlite3VdbeMemTooBig(pTos) ){ + goto too_big; + } break; } @@ -2003,6 +2021,9 @@ case OP_Column: { assert( pTos->flags==MEM_Null ); break; } + if( payloadSize>SQLITE_MAX_LENGTH ){ + goto too_big; + } assert( p2SQLITE_MAX_LENGTH ){ + goto too_big; + } /* Allocate space for the new record. */ if( nByte>sizeof(zTemp) ){ @@ -3557,10 +3581,16 @@ case OP_RowData: { i64 n64; assert( !pC->isTable ); sqlite3BtreeKeySize(pCrsr, &n64); + if( n64>SQLITE_MAX_LENGTH ){ + goto too_big; + } n = n64; }else{ sqlite3BtreeDataSize(pCrsr, &n); } + if( n>SQLITE_MAX_LENGTH ){ + goto too_big; + } pTos->n = n; if( n<=NBFS ){ pTos->flags = MEM_Blob | MEM_Short; @@ -3579,6 +3609,7 @@ case OP_RowData: { } }else if( pC->pseudoTable ){ pTos->n = pC->nData; + assert( pC->nData<=SQLITE_MAX_LENGTH ); pTos->z = pC->pData; pTos->flags = MEM_Blob|MEM_Ephem; }else{ @@ -4580,6 +4611,9 @@ case OP_AggFinal: { /* no-push */ if( rc==SQLITE_ERROR ){ sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pMem), (char*)0); } + if( sqlite3VdbeMemTooBig(pMem) ){ + goto too_big; + } break; } @@ -4872,7 +4906,12 @@ case OP_VColumn: { pTos->flags = 0; sqlite3VdbeMemMove(pTos, &sContext.s); - if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + if( sqlite3SafetyOn(db) ){ + goto abort_due_to_misuse; + } + if( sqlite3VdbeMemTooBig(pTos) ){ + goto too_big; + } } break; @@ -5032,6 +5071,7 @@ default: { */ if( pTos>=p->aStack && pTos->flags ){ sqlite3VdbeMemSanity(pTos); + assert( !sqlite3VdbeMemTooBig(pTos) ); } assert( pc>=-1 && pcnOp ); #ifdef SQLITE_DEBUG @@ -5076,6 +5116,14 @@ vdbe_halt: p->pTos = pTos; return rc; + /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH + ** is encountered. + */ +too_big: + sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0); + rc = SQLITE_TOOBIG; + goto vdbe_halt; + /* Jump to here if a malloc() fails. It's hard to get a malloc() ** to fail on a modern VM computer, so this code is untested. */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 545079d578..5386579059 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -378,6 +378,7 @@ int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeList(Vdbe*); int sqlite3VdbeHalt(Vdbe*); int sqlite3VdbeChangeEncoding(Mem *, int); +int sqlite3VdbeMemTooBig(Mem*); int sqlite3VdbeMemCopy(Mem*, const Mem*); void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); int sqlite3VdbeMemMove(Mem*, Mem*); diff --git a/src/vdbemem.c b/src/vdbemem.c index 9772b415d5..94188a071d 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -410,6 +410,21 @@ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ pMem->type = SQLITE_FLOAT; } +/* +** Return true if the Mem object contains a TEXT or BLOB that is +** too large - whose size exceeds SQLITE_MAX_LENGTH. +*/ +int sqlite3VdbeMemTooBig(Mem *p){ + if( p->flags & (MEM_Str|MEM_Blob) ){ + int n = p->n; + if( p->flags & MEM_Zero ){ + n += p->u.i; + } + return n>SQLITE_MAX_LENGTH; + } + return 0; +} + /* ** Make an shallow copy of pFrom into pTo. Prior contents of ** pTo are overwritten. The pFrom->z field is not duplicated. If