mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
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:
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fix\srequirements\smarks\sassociate\swith\sSTAT3.
|
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-11T12:39:19.194
|
D 2011-10-11T17:54:54.587
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897
|
F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -175,7 +175,7 @@ F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
|
|||||||
F src/pcache1.c 24f5e85a78514584b46190260ba7ab0a66312197
|
F src/pcache1.c 24f5e85a78514584b46190260ba7ab0a66312197
|
||||||
F src/pragma.c 68d7db4fc9de8bcfae94c1d43120531ec252b9c0
|
F src/pragma.c 68d7db4fc9de8bcfae94c1d43120531ec252b9c0
|
||||||
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
|
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
|
||||||
F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
|
F src/printf.c 1cd24df913bafc0cb69dc7ae68af85cc480925aa
|
||||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||||
F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4
|
F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4
|
||||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||||
@ -624,7 +624,7 @@ F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
|||||||
F test/permutations.test ad17319066a90e2db71823c3ff104795ffc71b31
|
F test/permutations.test ad17319066a90e2db71823c3ff104795ffc71b31
|
||||||
F test/pragma.test c8108e01da04f16e67e5754e610bc62c1b993f6c
|
F test/pragma.test c8108e01da04f16e67e5754e610bc62c1b993f6c
|
||||||
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
|
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
|
||||||
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
|
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
||||||
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
|
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
|
||||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||||
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
||||||
@ -966,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5
|
|||||||
F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||||
P e5169f9a5b7e20b8adaf6ebb7868a64e44fd7321
|
P 9325c1a8c413dfbf0381190d8347f0a446ae5f5b
|
||||||
R fa1bfea306973bc99ccb0d80c9355cfe
|
R e5d1b1fb843cbf71cdab9d042be23020
|
||||||
U drh
|
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.
|
** SQLITE_PRINT_BUF_SIZE to be less than 350.
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_PRINT_BUF_SIZE
|
#ifndef SQLITE_PRINT_BUF_SIZE
|
||||||
# if defined(SQLITE_SMALL_STACK)
|
# define SQLITE_PRINT_BUF_SIZE 70
|
||||||
# define SQLITE_PRINT_BUF_SIZE 50
|
|
||||||
# else
|
|
||||||
# define SQLITE_PRINT_BUF_SIZE 350
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
|
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
|
||||||
|
|
||||||
@ -250,6 +246,8 @@ void sqlite3VXPrintf(
|
|||||||
LONGDOUBLE_TYPE realvalue; /* Value for real types */
|
LONGDOUBLE_TYPE realvalue; /* Value for real types */
|
||||||
const et_info *infop; /* Pointer to the appropriate info structure */
|
const et_info *infop; /* Pointer to the appropriate info structure */
|
||||||
char buf[etBUFSIZE]; /* Conversion buffer */
|
char buf[etBUFSIZE]; /* Conversion buffer */
|
||||||
|
char *zOut; /* Rendering buffer */
|
||||||
|
int nOut; /* Size of the rendering buffer */
|
||||||
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
|
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
|
||||||
etByte xtype = 0; /* Conversion paradigm */
|
etByte xtype = 0; /* Conversion paradigm */
|
||||||
char *zExtra; /* Extra memory used for etTCLESCAPE conversions */
|
char *zExtra; /* Extra memory used for etTCLESCAPE conversions */
|
||||||
@ -258,7 +256,6 @@ void sqlite3VXPrintf(
|
|||||||
double rounder; /* Used for rounding floating point values */
|
double rounder; /* Used for rounding floating point values */
|
||||||
etByte flag_dp; /* True if decimal point should be shown */
|
etByte flag_dp; /* True if decimal point should be shown */
|
||||||
etByte flag_rtz; /* True if trailing zeros should be removed */
|
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 */
|
int nsd; /* Number of significant digits returned */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -307,9 +304,6 @@ void sqlite3VXPrintf(
|
|||||||
c = *++fmt;
|
c = *++fmt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( width > etBUFSIZE-10 ){
|
|
||||||
width = etBUFSIZE-10;
|
|
||||||
}
|
|
||||||
/* Get the precision */
|
/* Get the precision */
|
||||||
if( c=='.' ){
|
if( c=='.' ){
|
||||||
precision = 0;
|
precision = 0;
|
||||||
@ -356,12 +350,6 @@ void sqlite3VXPrintf(
|
|||||||
}
|
}
|
||||||
zExtra = 0;
|
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:
|
** At this point, variables are initialized as follows:
|
||||||
**
|
**
|
||||||
@ -426,16 +414,26 @@ void sqlite3VXPrintf(
|
|||||||
if( flag_zeropad && precision<width-(prefix!=0) ){
|
if( flag_zeropad && precision<width-(prefix!=0) ){
|
||||||
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 ){
|
if( xtype==etORDINAL ){
|
||||||
static const char zOrd[] = "thstndrd";
|
static const char zOrd[] = "thstndrd";
|
||||||
int x = (int)(longvalue % 10);
|
int x = (int)(longvalue % 10);
|
||||||
if( x>=4 || (longvalue/10)%10==1 ){
|
if( x>=4 || (longvalue/10)%10==1 ){
|
||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
buf[etBUFSIZE-3] = zOrd[x*2];
|
*(--bufpt) = zOrd[x*2+1];
|
||||||
buf[etBUFSIZE-2] = zOrd[x*2+1];
|
*(--bufpt) = zOrd[x*2];
|
||||||
bufpt -= 2;
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
register const char *cset; /* Use registers for speed */
|
register const char *cset; /* Use registers for speed */
|
||||||
@ -447,7 +445,7 @@ void sqlite3VXPrintf(
|
|||||||
longvalue = longvalue/base;
|
longvalue = longvalue/base;
|
||||||
}while( longvalue>0 );
|
}while( longvalue>0 );
|
||||||
}
|
}
|
||||||
length = (int)(&buf[etBUFSIZE-1]-bufpt);
|
length = (int)(&zOut[nOut-1]-bufpt);
|
||||||
for(idx=precision-length; idx>0; idx--){
|
for(idx=precision-length; idx>0; idx--){
|
||||||
*(--bufpt) = '0'; /* Zero pad */
|
*(--bufpt) = '0'; /* Zero pad */
|
||||||
}
|
}
|
||||||
@ -458,7 +456,7 @@ void sqlite3VXPrintf(
|
|||||||
pre = &aPrefix[infop->prefix];
|
pre = &aPrefix[infop->prefix];
|
||||||
for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
|
for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
|
||||||
}
|
}
|
||||||
length = (int)(&buf[etBUFSIZE-1]-bufpt);
|
length = (int)(&zOut[nOut-1]-bufpt);
|
||||||
break;
|
break;
|
||||||
case etFLOAT:
|
case etFLOAT:
|
||||||
case etEXP:
|
case etEXP:
|
||||||
@ -468,7 +466,6 @@ void sqlite3VXPrintf(
|
|||||||
length = 0;
|
length = 0;
|
||||||
#else
|
#else
|
||||||
if( precision<0 ) precision = 6; /* Set default precision */
|
if( precision<0 ) precision = 6; /* Set default precision */
|
||||||
if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10;
|
|
||||||
if( realvalue<0.0 ){
|
if( realvalue<0.0 ){
|
||||||
realvalue = -realvalue;
|
realvalue = -realvalue;
|
||||||
prefix = '-';
|
prefix = '-';
|
||||||
@ -516,7 +513,6 @@ void sqlite3VXPrintf(
|
|||||||
** If the field type is etGENERIC, then convert to either etEXP
|
** If the field type is etGENERIC, then convert to either etEXP
|
||||||
** or etFLOAT, as appropriate.
|
** or etFLOAT, as appropriate.
|
||||||
*/
|
*/
|
||||||
flag_exp = xtype==etEXP;
|
|
||||||
if( xtype!=etFLOAT ){
|
if( xtype!=etFLOAT ){
|
||||||
realvalue += rounder;
|
realvalue += rounder;
|
||||||
if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
|
if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
|
||||||
@ -537,6 +533,14 @@ void sqlite3VXPrintf(
|
|||||||
}else{
|
}else{
|
||||||
e2 = exp;
|
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;
|
nsd = 0;
|
||||||
flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
|
flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
|
||||||
/* The sign in front of the number */
|
/* The sign in front of the number */
|
||||||
@ -568,7 +572,7 @@ void sqlite3VXPrintf(
|
|||||||
/* Remove trailing zeros and the "." if no digits follow the "." */
|
/* Remove trailing zeros and the "." if no digits follow the "." */
|
||||||
if( flag_rtz && flag_dp ){
|
if( flag_rtz && flag_dp ){
|
||||||
while( bufpt[-1]=='0' ) *(--bufpt) = 0;
|
while( bufpt[-1]=='0' ) *(--bufpt) = 0;
|
||||||
assert( bufpt>buf );
|
assert( bufpt>zOut );
|
||||||
if( bufpt[-1]=='.' ){
|
if( bufpt[-1]=='.' ){
|
||||||
if( flag_altform2 ){
|
if( flag_altform2 ){
|
||||||
*(bufpt++) = '0';
|
*(bufpt++) = '0';
|
||||||
@ -578,7 +582,7 @@ void sqlite3VXPrintf(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Add the "eNNN" suffix */
|
/* Add the "eNNN" suffix */
|
||||||
if( flag_exp || xtype==etEXP ){
|
if( xtype==etEXP ){
|
||||||
*(bufpt++) = aDigits[infop->charset];
|
*(bufpt++) = aDigits[infop->charset];
|
||||||
if( exp<0 ){
|
if( exp<0 ){
|
||||||
*(bufpt++) = '-'; exp = -exp;
|
*(bufpt++) = '-'; exp = -exp;
|
||||||
@ -597,8 +601,8 @@ void sqlite3VXPrintf(
|
|||||||
/* The converted number is in buf[] and zero terminated. Output it.
|
/* The converted number is in buf[] and zero terminated. Output it.
|
||||||
** Note that the number is in the usual order, not reversed as with
|
** Note that the number is in the usual order, not reversed as with
|
||||||
** integer conversions. */
|
** integer conversions. */
|
||||||
length = (int)(bufpt-buf);
|
length = (int)(bufpt-zOut);
|
||||||
bufpt = buf;
|
bufpt = zOut;
|
||||||
|
|
||||||
/* Special case: Add leading zeros if the flag_zeropad flag is
|
/* Special case: Add leading zeros if the flag_zeropad flag is
|
||||||
** set and we are not left justified */
|
** set and we are not left justified */
|
||||||
@ -736,9 +740,7 @@ void sqlite3VXPrintf(
|
|||||||
appendSpace(pAccum, nspace);
|
appendSpace(pAccum, nspace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( zExtra ){
|
sqlite3_free(zExtra);
|
||||||
sqlite3_free(zExtra);
|
|
||||||
}
|
|
||||||
}/* End for loop over the format string */
|
}/* End for loop over the format string */
|
||||||
} /* End of function */
|
} /* End of function */
|
||||||
|
|
||||||
|
@ -3547,7 +3547,7 @@ do_test printf-4.16 {
|
|||||||
do_test printf-5.1 {
|
do_test printf-5.1 {
|
||||||
set x [sqlite3_mprintf_str {%d %d %100000s} 0 0 {Hello}]
|
set x [sqlite3_mprintf_str {%d %d %100000s} 0 0 {Hello}]
|
||||||
string length $x
|
string length $x
|
||||||
} {344}
|
} {100004}
|
||||||
do_test printf-5.2 {
|
do_test printf-5.2 {
|
||||||
sqlite3_mprintf_str {%d %d (%-10.10s) %} -9 -10 {HelloHelloHello}
|
sqlite3_mprintf_str {%d %d (%-10.10s) %} -9 -10 {HelloHelloHello}
|
||||||
} {-9 -10 (HelloHello) %}
|
} {-9 -10 (HelloHello) %}
|
||||||
|
Reference in New Issue
Block a user