Remove all precision and width limits from formatting fields in the
sqlite3_mprintf() family of functions. Malloc for space as necessary. The prevents a stack overflow on very large numbers using %f. FossilOrigin-Name: 1f843fb383583ee7ef51c13b8a820744e450101a
This commit is contained in:
parent
67855877ff
commit
59eedf7925
14
manifest
14
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
|
||||
|
@ -1 +1 @@
|
||||
9325c1a8c413dfbf0381190d8347f0a446ae5f5b
|
||||
1f843fb383583ee7ef51c13b8a820744e450101a
|
62
src/printf.c
62
src/printf.c
@ -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 */
|
||||
|
||||
|
@ -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) %}
|
||||
|
Loading…
Reference in New Issue
Block a user