/ Check-in [8e4ac2ce]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Avoid signed integer overflow when converting oversized in-line integer widths and precisions in printf().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8e4ac2ce24415926247961b00a62425ae85d6ffb
User & Date: drh 2015-04-07 15:39:29
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-08
12:16
Version 3.8.9 check-in: 8a8ffc86 user: drh tags: trunk, release, version-3.8.9
2015-04-07
23:10
Merge printf() width and precision overflow fixes from trunk. check-in: aeca95ac user: drh tags: sessions
21:18
Merge updates from trunk. check-in: c458db41 user: mistachkin tags: expShell
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
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/printf.c.

257
258
259
260
261
262
263
264
265
266
267

268
269
270
271


272
273
274
275
276
277
278
279
280
281
282
283
284
285



286

287
288
289
290


291
292
293
294
295
296
297
298
299
300
301
302
303
304
      if( bArgList ){
        width = (int)getIntArg(pArgList);
      }else{
        width = va_arg(ap,int);
      }
      if( width<0 ){
        flag_leftjustify = 1;
        width = -width;
      }
      c = *++fmt;
    }else{

      while( c>='0' && c<='9' ){
        width = width*10 + c - '0';
        c = *++fmt;
      }


    }
    if( width<0 ) width = 0; /* force to non-negative after int overflow */

    /* Get the precision */
    if( c=='.' ){
      precision = 0;
      c = *++fmt;
      if( c=='*' ){
        if( bArgList ){
          precision = (int)getIntArg(pArgList);
        }else{
          precision = va_arg(ap,int);
        }
        c = *++fmt;



      }else{

        while( c>='0' && c<='9' ){
          precision = precision*10 + c - '0';
          c = *++fmt;
        }


      }

      /* If a negative precision has been specified, use its absolute value
      ** instead. This is (probably) not standard printf() behaviour, but
      ** it is what sqlite3_mprintf() and friends have always done. If the
      ** precision specified is -2147483648, use 0. */
      if( precision<0 ) precision = (-precision) & 0x7fffffff;
    }else{
      precision = -1;
    }
    /* Get the conversion type modifier */
    if( c=='l' ){
      flag_long = 1;
      c = *++fmt;







|



>

|


>
>

<












>
>
>

>

|


>
>

<
<
<
<
<
<







257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299






300
301
302
303
304
305
306
      if( bArgList ){
        width = (int)getIntArg(pArgList);
      }else{
        width = va_arg(ap,int);
      }
      if( width<0 ){
        flag_leftjustify = 1;
        width = width >= -2147483647 ? -width : 0;
      }
      c = *++fmt;
    }else{
      unsigned wx = 0;
      while( c>='0' && c<='9' ){
        wx = wx*10 + c - '0';
        c = *++fmt;
      }
      testcase( wx>0x7fffffff );
      width = wx & 0x7fffffff;
    }


    /* Get the precision */
    if( c=='.' ){
      precision = 0;
      c = *++fmt;
      if( c=='*' ){
        if( bArgList ){
          precision = (int)getIntArg(pArgList);
        }else{
          precision = va_arg(ap,int);
        }
        c = *++fmt;
        if( precision<0 ){
          precision = precision >= -2147483647 ? -precision : -1;
        }
      }else{
        unsigned px = 0;
        while( c>='0' && c<='9' ){
          px = px*10 + c - '0';
          c = *++fmt;
        }
        testcase( px>0x7fffffff );
        precision = px & 0x7fffffff;
      }






    }else{
      precision = -1;
    }
    /* Get the conversion type modifier */
    if( c=='l' ){
      flag_long = 1;
      c = *++fmt;

Changes to test/printf.test.

479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
....
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
....
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
  sqlite3_mprintf_int {abd: %*d %x} 2147483647 1 1
} {}
do_test printf-1.17.3 {
  sqlite3_mprintf_int {abd: %*d %x} -2147483648 1 1
} {abd: 1 1}
do_test printf-1.17.4 {
  sqlite3_mprintf_int {abd: %.2147483648d %x %x} 1 1 1
} {abd: 1 1 1}
do_test printf-2.1.1.1 {
  sqlite3_mprintf_double {abc: (%*.*f) :xyz} 1 1 0.001
} {abc: (0.0) :xyz}
do_test printf-2.1.1.2 {
  sqlite3_mprintf_double {abc: (%*.*e) :xyz} 1 1 0.001
} {abc: (1.0e-03) :xyz}
do_test printf-2.1.1.3 {
................................................................................
  sqlite3_mprintf_str {%d A String: (%*s)} 1 2147483647 {This is the string}
} []
do_test printf-3.8 {
  sqlite3_mprintf_str {%d A String: (%*s)} 1 -2147483648 {This is the string}
} {1 A String: (This is the string)}
do_test printf-3.9 {
  sqlite3_mprintf_str {%d A String: (%.*s)} 1 -2147483648 {This is the string}
} {1 A String: ()}
do_test snprintf-3.11 {
  sqlite3_snprintf_str 2 {x%d %d %s} 10 10 {This is the string}
} {x}
do_test snprintf-3.12 {
  sqlite3_snprintf_str 3 {x%d %d %s} 10 10 {This is the string}
} {x1}
do_test snprintf-3.13 {
................................................................................
do_test printf-13.5 {
  sqlite3_mprintf_hexdouble %.20f fff0000000000000
} {-Inf}
do_test printf-13.6 {
  sqlite3_mprintf_hexdouble %.20f fff8000000000000
} {NaN}
do_test printf-13.7 {
  sqlite3_mprintf_hexdouble %3000000000.10000f 4693b8b5b5056e17
} "100000000000000000000000000000000.[string repeat 0 10000]"

do_test printf-14.1 {
  sqlite3_mprintf_str {abc-%y-123} 0 0 {not used}
} {abc-}
do_test printf-14.2 {
  sqlite3_mprintf_n_test {xyzzy}
} 5







|







 







|







 







|
|







479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
....
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
....
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
  sqlite3_mprintf_int {abd: %*d %x} 2147483647 1 1
} {}
do_test printf-1.17.3 {
  sqlite3_mprintf_int {abd: %*d %x} -2147483648 1 1
} {abd: 1 1}
do_test printf-1.17.4 {
  sqlite3_mprintf_int {abd: %.2147483648d %x %x} 1 1 1
} {/.*/}
do_test printf-2.1.1.1 {
  sqlite3_mprintf_double {abc: (%*.*f) :xyz} 1 1 0.001
} {abc: (0.0) :xyz}
do_test printf-2.1.1.2 {
  sqlite3_mprintf_double {abc: (%*.*e) :xyz} 1 1 0.001
} {abc: (1.0e-03) :xyz}
do_test printf-2.1.1.3 {
................................................................................
  sqlite3_mprintf_str {%d A String: (%*s)} 1 2147483647 {This is the string}
} []
do_test printf-3.8 {
  sqlite3_mprintf_str {%d A String: (%*s)} 1 -2147483648 {This is the string}
} {1 A String: (This is the string)}
do_test printf-3.9 {
  sqlite3_mprintf_str {%d A String: (%.*s)} 1 -2147483648 {This is the string}
} {1 A String: (This is the string)}
do_test snprintf-3.11 {
  sqlite3_snprintf_str 2 {x%d %d %s} 10 10 {This is the string}
} {x}
do_test snprintf-3.12 {
  sqlite3_snprintf_str 3 {x%d %d %s} 10 10 {This is the string}
} {x1}
do_test snprintf-3.13 {
................................................................................
do_test printf-13.5 {
  sqlite3_mprintf_hexdouble %.20f fff0000000000000
} {-Inf}
do_test printf-13.6 {
  sqlite3_mprintf_hexdouble %.20f fff8000000000000
} {NaN}
do_test printf-13.7 {
  sqlite3_mprintf_hexdouble %2147483648.10000f 4693b8b5b5056e17
} {/100000000000000000000000000000000.00/}

do_test printf-14.1 {
  sqlite3_mprintf_str {abc-%y-123} 0 0 {not used}
} {abc-}
do_test printf-14.2 {
  sqlite3_mprintf_n_test {xyzzy}
} 5