Begin adding code to explicitly limit the size of strings and blobs. (CVS 3943)
FossilOrigin-Name: 031a5915b68ec6827fee38b8b9dc74a9e0e09302
This commit is contained in:
parent
7a7364cee8
commit
023ae03a72
20
manifest
20
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
|
||||
|
@ -1 +1 @@
|
||||
47d1678d2d795196e51b7f0f185198f2b338636b
|
||||
031a5915b68ec6827fee38b8b9dc74a9e0e09302
|
30
src/func.c
30
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 <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;
|
||||
|
@ -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;
|
||||
|
58
src/vdbe.c
58
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 && 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.
|
||||
*/
|
||||
|
@ -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*);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user