]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove all precision and width limits from formatting fields in the
authordrh <drh@noemail.net>
Tue, 11 Oct 2011 17:54:54 +0000 (17:54 +0000)
committerdrh <drh@noemail.net>
Tue, 11 Oct 2011 17:54:54 +0000 (17:54 +0000)
sqlite3_mprintf() family of functions. Malloc for space as necessary.
The prevents a stack overflow on very large numbers using %f.

FossilOrigin-Name: 1f843fb383583ee7ef51c13b8a820744e450101a

manifest
manifest.uuid
src/printf.c
test/printf.test

index 79c4572a2b4691a50cc3e2ecdaeab9e59845bd66..f38e0e3be470c2ec92a8e9d4b6b8c664dcfd3c02 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\srequirements\smarks\sassociate\swith\sSTAT3.
-D 2011-10-11T12:39:19.194
+C Remove\sall\sprecision\sand\swidth\slimits\sfrom\sformatting\sfields\sin\sthe\nsqlite3_mprintf()\sfamily\sof\sfunctions.\sMalloc\sfor\sspace\sas\snecessary.\nThe\sprevents\sa\sstack\soverflow\son\svery\slarge\snumbers\susing\s%f.
+D 2011-10-11T17:54:54.587
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -175,7 +175,7 @@ F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
 F src/pcache1.c 24f5e85a78514584b46190260ba7ab0a66312197
 F src/pragma.c 68d7db4fc9de8bcfae94c1d43120531ec252b9c0
 F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
-F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
+F src/printf.c 1cd24df913bafc0cb69dc7ae68af85cc480925aa
 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
 F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4
 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
@@ -624,7 +624,7 @@ F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
 F test/permutations.test ad17319066a90e2db71823c3ff104795ffc71b31
 F test/pragma.test c8108e01da04f16e67e5754e610bc62c1b993f6c
 F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
-F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
+F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
 F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
@@ -966,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5
 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P e5169f9a5b7e20b8adaf6ebb7868a64e44fd7321
-R fa1bfea306973bc99ccb0d80c9355cfe
+P 9325c1a8c413dfbf0381190d8347f0a446ae5f5b
+R e5d1b1fb843cbf71cdab9d042be23020
 U drh
-Z 7aa6c1f7c4e6214ddb2d3b34feac8ca1
+Z 4feb18f759ff84be86477c96fb244530
index 076bf3c8fdcfa03e6326223f18588b500e67875c..4c5accd9f0c6d3183518fb67c96695faeea1b4db 100644 (file)
@@ -1 +1 @@
-9325c1a8c413dfbf0381190d8347f0a446ae5f5b
\ No newline at end of file
+1f843fb383583ee7ef51c13b8a820744e450101a
\ No newline at end of file
index 2a3dd81d7d2603a072d5074973004ab48123bc7f..2f6945577b61bd969729a9b5e891c696d0b11615 100644 (file)
@@ -190,11 +190,7 @@ static void appendSpace(StrAccum *pAccum, int N){
 ** SQLITE_PRINT_BUF_SIZE to be less than 350.
 */
 #ifndef SQLITE_PRINT_BUF_SIZE
-# if defined(SQLITE_SMALL_STACK)
-#   define SQLITE_PRINT_BUF_SIZE 50
-# else
-#   define SQLITE_PRINT_BUF_SIZE 350
-# endif
+# define SQLITE_PRINT_BUF_SIZE 70
 #endif
 #define etBUFSIZE SQLITE_PRINT_BUF_SIZE  /* Size of the output buffer */
 
@@ -250,6 +246,8 @@ void sqlite3VXPrintf(
   LONGDOUBLE_TYPE realvalue; /* Value for real types */
   const et_info *infop;      /* Pointer to the appropriate info structure */
   char buf[etBUFSIZE];       /* Conversion buffer */
+  char *zOut;                /* Rendering buffer */
+  int nOut;                  /* Size of the rendering buffer */
   char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
   etByte xtype = 0;          /* Conversion paradigm */
   char *zExtra;              /* Extra memory used for etTCLESCAPE conversions */
@@ -258,7 +256,6 @@ void sqlite3VXPrintf(
   double rounder;            /* Used for rounding floating point values */
   etByte flag_dp;            /* True if decimal point should be shown */
   etByte flag_rtz;           /* True if trailing zeros should be removed */
-  etByte flag_exp;           /* True to force display of the exponent */
   int nsd;                   /* Number of significant digits returned */
 #endif
 
@@ -307,9 +304,6 @@ void sqlite3VXPrintf(
         c = *++fmt;
       }
     }
-    if( width > etBUFSIZE-10 ){
-      width = etBUFSIZE-10;
-    }
     /* Get the precision */
     if( c=='.' ){
       precision = 0;
@@ -356,12 +350,6 @@ void sqlite3VXPrintf(
     }
     zExtra = 0;
 
-
-    /* Limit the precision to prevent overflowing buf[] during conversion */
-    if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
-      precision = etBUFSIZE-40;
-    }
-
     /*
     ** At this point, variables are initialized as follows:
     **
@@ -426,16 +414,26 @@ void sqlite3VXPrintf(
         if( flag_zeropad && precision<width-(prefix!=0) ){
           precision = width-(prefix!=0);
         }
-        bufpt = &buf[etBUFSIZE-1];
+        if( precision<etBUFSIZE-10 ){
+          nOut = etBUFSIZE;
+          zOut = buf;
+        }else{
+          nOut = precision + 10;
+          zOut = zExtra = sqlite3Malloc( nOut );
+          if( zOut==0 ){
+            pAccum->mallocFailed = 1;
+            return;
+          }
+        }
+        bufpt = &zOut[nOut-1];
         if( xtype==etORDINAL ){
           static const char zOrd[] = "thstndrd";
           int x = (int)(longvalue % 10);
           if( x>=4 || (longvalue/10)%10==1 ){
             x = 0;
           }
-          buf[etBUFSIZE-3] = zOrd[x*2];
-          buf[etBUFSIZE-2] = zOrd[x*2+1];
-          bufpt -= 2;
+          *(--bufpt) = zOrd[x*2+1];
+          *(--bufpt) = zOrd[x*2];
         }
         {
           register const char *cset;      /* Use registers for speed */
@@ -447,7 +445,7 @@ void sqlite3VXPrintf(
             longvalue = longvalue/base;
           }while( longvalue>0 );
         }
-        length = (int)(&buf[etBUFSIZE-1]-bufpt);
+        length = (int)(&zOut[nOut-1]-bufpt);
         for(idx=precision-length; idx>0; idx--){
           *(--bufpt) = '0';                             /* Zero pad */
         }
@@ -458,7 +456,7 @@ void sqlite3VXPrintf(
           pre = &aPrefix[infop->prefix];
           for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
         }
-        length = (int)(&buf[etBUFSIZE-1]-bufpt);
+        length = (int)(&zOut[nOut-1]-bufpt);
         break;
       case etFLOAT:
       case etEXP:
@@ -468,7 +466,6 @@ void sqlite3VXPrintf(
         length = 0;
 #else
         if( precision<0 ) precision = 6;         /* Set default precision */
-        if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10;
         if( realvalue<0.0 ){
           realvalue = -realvalue;
           prefix = '-';
@@ -516,7 +513,6 @@ void sqlite3VXPrintf(
         ** If the field type is etGENERIC, then convert to either etEXP
         ** or etFLOAT, as appropriate.
         */
-        flag_exp = xtype==etEXP;
         if( xtype!=etFLOAT ){
           realvalue += rounder;
           if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
@@ -537,6 +533,14 @@ void sqlite3VXPrintf(
         }else{
           e2 = exp;
         }
+        if( e2+precision+width > etBUFSIZE - 15 ){
+          bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
+          if( bufpt==0 ){
+            pAccum->mallocFailed = 1;
+            return;
+          }
+        }
+        zOut = bufpt;
         nsd = 0;
         flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
         /* The sign in front of the number */
@@ -568,7 +572,7 @@ void sqlite3VXPrintf(
         /* Remove trailing zeros and the "." if no digits follow the "." */
         if( flag_rtz && flag_dp ){
           while( bufpt[-1]=='0' ) *(--bufpt) = 0;
-          assert( bufpt>buf );
+          assert( bufpt>zOut );
           if( bufpt[-1]=='.' ){
             if( flag_altform2 ){
               *(bufpt++) = '0';
@@ -578,7 +582,7 @@ void sqlite3VXPrintf(
           }
         }
         /* Add the "eNNN" suffix */
-        if( flag_exp || xtype==etEXP ){
+        if( xtype==etEXP ){
           *(bufpt++) = aDigits[infop->charset];
           if( exp<0 ){
             *(bufpt++) = '-'; exp = -exp;
@@ -597,8 +601,8 @@ void sqlite3VXPrintf(
         /* The converted number is in buf[] and zero terminated. Output it.
         ** Note that the number is in the usual order, not reversed as with
         ** integer conversions. */
-        length = (int)(bufpt-buf);
-        bufpt = buf;
+        length = (int)(bufpt-zOut);
+        bufpt = zOut;
 
         /* Special case:  Add leading zeros if the flag_zeropad flag is
         ** set and we are not left justified */
@@ -736,9 +740,7 @@ void sqlite3VXPrintf(
         appendSpace(pAccum, nspace);
       }
     }
-    if( zExtra ){
-      sqlite3_free(zExtra);
-    }
+    sqlite3_free(zExtra);
   }/* End for loop over the format string */
 } /* End of function */
 
index 100ce96b12e066c832a2d1a08ff55f07d6192533..73222720abad5c8da656d0f01858e0bf03ec541c 100644 (file)
@@ -3547,7 +3547,7 @@ do_test printf-4.16 {
 do_test printf-5.1 {
   set x [sqlite3_mprintf_str {%d %d %100000s} 0 0 {Hello}]
   string length $x
-} {344}
+} {100004}
 do_test printf-5.2 {
   sqlite3_mprintf_str {%d %d (%-10.10s) %} -9 -10 {HelloHelloHello}
 } {-9 -10 (HelloHello) %}