]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Begin adding code to explicitly limit the size of strings and blobs. (CVS 3943)
authordrh <drh@noemail.net>
Tue, 8 May 2007 12:12:16 +0000 (12:12 +0000)
committerdrh <drh@noemail.net>
Tue, 8 May 2007 12:12:16 +0000 (12:12 +0000)
FossilOrigin-Name: 031a5915b68ec6827fee38b8b9dc74a9e0e09302

manifest
manifest.uuid
src/func.c
src/main.c
src/vdbe.c
src/vdbeInt.h
src/vdbemem.c

index 270690a99d3c0099fdb46754934c5d4ead80ed34..f7570a5496be8a27a2f50013664a04d0b9e560a9 100644 (file)
--- 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
index 04793f299dde20eb853a97d80b840ca2a6c41b7e..820263f9e59211f7c726914723cc9c20cc941e6a 100644 (file)
@@ -1 +1 @@
-47d1678d2d795196e51b7f0f185198f2b338636b
\ No newline at end of file
+031a5915b68ec6827fee38b8b9dc74a9e0e09302
\ No newline at end of file
index 2403b3d566a928e14a840f74b9f5a68f3bc2040b..5197ccd181282a08f35274165e45bc4f1c1aa353 100644 (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;
index 6e91221042b00f16556b26eb4e4ce4ec874137ee..9f92bd6dff00fff2e20f98bf26bd4ff93499280d 100644 (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;
index fef1993b4bb82db4b683b7b197cd3290a6d76f0e..248103c34846992a86d4c5164edf4aa583b234ed 100644 (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.
   */
index 545079d578b88b5490cbde02e39f28fe854c8c76..538657905902695d8bdfe16aa640ea94cea1762c 100644 (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*);
index 9772b415d5a140d0bab180fdd19584ed027d684c..94188a071d5a2b599d688aba115949601fdbb23e 100644 (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