Begin adding code to explicitly limit the size of strings and blobs. (CVS 3943)

FossilOrigin-Name: 031a5915b68ec6827fee38b8b9dc74a9e0e09302
This commit is contained in:
drh 2007-05-08 12:12:16 +00:00
parent 7a7364cee8
commit 023ae03a72
7 changed files with 107 additions and 22 deletions

View File

@ -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

View File

@ -1 +1 @@
47d1678d2d795196e51b7f0f185198f2b338636b
031a5915b68ec6827fee38b8b9dc74a9e0e09302

View File

@ -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 <ctype.h>
@ -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;

View File

@ -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;

View File

@ -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 && j<p->nVar );
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( p2<nField );
@ -2211,9 +2232,9 @@ case OP_MakeRecord: {
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
Mem *pRowid = 0; /* Rowid appended to the new record */
int nData = 0; /* Number of bytes of data space */
u64 nData = 0; /* Number of bytes of data space */
int nHdr = 0; /* Number of bytes of header space */
int nByte = 0; /* Data space required for this record */
u64 nByte = 0; /* Data space required for this record */
int nZero = 0; /* Number of zero bytes at the end of the record */
int nVarint; /* Number of bytes in a varint */
u32 serial_type; /* Type field */
@ -2284,6 +2305,9 @@ case OP_MakeRecord: {
nHdr++;
}
nByte = nHdr+nData-nZero;
if( nByte>SQLITE_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 && pc<p->nOp );
#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.
*/

View File

@ -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*);

View File

@ -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