/ Check-in [95625ef3]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Another change to avoid a problem caused by integer overflow in the printf() code.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 95625ef3adc3c408d67e70f877f390445fbb8292
User & Date: dan 2015-04-07 14:38:57
References
2015-05-20
19:48
Avoid signed integer overflow when converting oversized in-line integer widths and precisions in printf(). Cherrypick of [c494171f77dc], [5ce4e7d7651e], [95625ef3adc3] and [8e4ac2ce2441]. check-in: b330c7ff user: dan tags: branch-3.8.6
Context
2015-05-20
19:48
Avoid signed integer overflow when converting oversized in-line integer widths and precisions in printf(). Cherrypick of [c494171f77dc], [5ce4e7d7651e], [95625ef3adc3] and [8e4ac2ce2441]. check-in: b330c7ff user: dan tags: branch-3.8.6
2015-04-07
15:39
Avoid signed integer overflow when converting oversized in-line integer widths and precisions in printf(). check-in: 8e4ac2ce user: drh tags: trunk
14:38
Another change to avoid a problem caused by integer overflow in the printf() code. check-in: 95625ef3 user: dan tags: trunk
13:28
Further changes to guard against integer overflow in the width and precision of printf() arguments. check-in: 5ce4e7d7 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/printf.c.

   266    266         c = *++fmt;
   267    267       }else{
   268    268         while( c>='0' && c<='9' ){
   269    269           width = width*10 + c - '0';
   270    270           c = *++fmt;
   271    271         }
   272    272       }
          273  +    if( width<0 ) width = 0; /* force to non-negative after int overflow */
          274  +
   273    275       /* Get the precision */
   274    276       if( c=='.' ){
   275    277         precision = 0;
   276    278         c = *++fmt;
   277    279         if( c=='*' ){
   278    280           if( bArgList ){
   279    281             precision = (int)getIntArg(pArgList);
   280    282           }else{
   281    283             precision = va_arg(ap,int);
   282    284           }
   283         -        if( precision<0 ) precision = -precision;
   284    285           c = *++fmt;
   285    286         }else{
   286    287           while( c>='0' && c<='9' ){
   287    288             precision = precision*10 + c - '0';
   288    289             c = *++fmt;
   289    290           }
   290    291         }
          292  +
          293  +      /* If a negative precision has been specified, use its absolute value
          294  +      ** instead. This is (probably) not standard printf() behaviour, but
          295  +      ** it is what sqlite3_mprintf() and friends have always done. If the
          296  +      ** precision specified is -2147483648, use 0. */
          297  +      if( precision<0 ) precision = (-precision) & 0x7fffffff;
   291    298       }else{
   292    299         precision = -1;
   293    300       }
   294    301       /* Get the conversion type modifier */
   295    302       if( c=='l' ){
   296    303         flag_long = 1;
   297    304         c = *++fmt;
................................................................................
   386    393           if( longvalue==0 ) flag_alternateform = 0;
   387    394           if( flag_zeropad && precision<width-(prefix!=0) ){
   388    395             precision = width-(prefix!=0);
   389    396           }
   390    397           if( precision<etBUFSIZE-10 ){
   391    398             nOut = etBUFSIZE;
   392    399             zOut = buf;
   393         -          if( precision<0 ) precision = 0;
   394    400           }else{
   395    401             nOut = precision + 10;
   396    402             zOut = zExtra = sqlite3Malloc( nOut );
   397    403             if( zOut==0 ){
   398    404               setStrAccumError(pAccum, STRACCUM_NOMEM);
   399    405               return;
   400    406             }

Changes to test/printf.test.

   476    476     sqlite3_mprintf_int {abd: %2147483647d %2147483647x %2147483647o} 1 1 1
   477    477   } {}
   478    478   do_test printf-1.17.2 {
   479    479     sqlite3_mprintf_int {abd: %*d %x} 2147483647 1 1
   480    480   } {}
   481    481   do_test printf-1.17.3 {
   482    482     sqlite3_mprintf_int {abd: %*d %x} -2147483648 1 1
   483         -} {}
          483  +} {abd: 1 1}
   484    484   do_test printf-1.17.4 {
   485    485     sqlite3_mprintf_int {abd: %.2147483648d %x %x} 1 1 1
   486    486   } {abd: 1 1 1}
   487    487   do_test printf-2.1.1.1 {
   488    488     sqlite3_mprintf_double {abc: (%*.*f) :xyz} 1 1 0.001
   489    489   } {abc: (0.0) :xyz}
   490    490   do_test printf-2.1.1.2 {
................................................................................
  3482   3482     sqlite3_mprintf_str {%d %d A String: (%-30s)} 1 2 {This is the string}
  3483   3483   } [format {%d %d A String: (%-30s)} 1 2 {This is the string}]
  3484   3484   do_test printf-3.7 {
  3485   3485     sqlite3_mprintf_str {%d A String: (%*s)} 1 2147483647 {This is the string}
  3486   3486   } []
  3487   3487   do_test printf-3.8 {
  3488   3488     sqlite3_mprintf_str {%d A String: (%*s)} 1 -2147483648 {This is the string}
  3489         -} []
         3489  +} {1 A String: (This is the string)}
  3490   3490   do_test printf-3.9 {
  3491   3491     sqlite3_mprintf_str {%d A String: (%.*s)} 1 -2147483648 {This is the string}
  3492         -} {1 A String: (This is the string)}
         3492  +} {1 A String: ()}
  3493   3493   do_test snprintf-3.11 {
  3494   3494     sqlite3_snprintf_str 2 {x%d %d %s} 10 10 {This is the string}
  3495   3495   } {x}
  3496   3496   do_test snprintf-3.12 {
  3497   3497     sqlite3_snprintf_str 3 {x%d %d %s} 10 10 {This is the string}
  3498   3498   } {x1}
  3499   3499   do_test snprintf-3.13 {
................................................................................
  3705   3705   } {Inf}
  3706   3706   do_test printf-13.5 {
  3707   3707     sqlite3_mprintf_hexdouble %.20f fff0000000000000
  3708   3708   } {-Inf}
  3709   3709   do_test printf-13.6 {
  3710   3710     sqlite3_mprintf_hexdouble %.20f fff8000000000000
  3711   3711   } {NaN}
         3712  +do_test printf-13.7 {
         3713  +  sqlite3_mprintf_hexdouble %3000000000.10000f 4693b8b5b5056e17
         3714  +} "100000000000000000000000000000000.[string repeat 0 10000]"
  3712   3715   
  3713   3716   do_test printf-14.1 {
  3714   3717     sqlite3_mprintf_str {abc-%y-123} 0 0 {not used}
  3715   3718   } {abc-}
  3716   3719   do_test printf-14.2 {
  3717   3720     sqlite3_mprintf_n_test {xyzzy}
  3718   3721   } 5