Merge printf() width and precision overflow fixes from trunk.

FossilOrigin-Name: aeca95ac77f6f320a916f7e3c5a7a588ef4a20c8
diff --git a/manifest b/manifest
index b10685e..42a45e4 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\sobscure\sproblem\sfixes\sfrom\strunk.
-D 2015-04-06T12:08:24.946
+C Merge\sprintf()\swidth\sand\sprecision\soverflow\sfixes\sfrom\strunk.
+D 2015-04-07T23:10:44.364
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 3083cf0c2bc6618e532b9478ce735bb512322985
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -243,7 +243,7 @@
 F src/pragma.c ac4f3f856b4234e85f55b0f069698a4766011100
 F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
 F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9
-F src/printf.c 8da9a2687a396daa19860f4dc90975d319304744
+F src/printf.c 8ae1fa9d30c1200a9268a390ba9e9cea9197b27a
 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
 F src/resolve.c 41aa91af56d960e9414ce1d7c17cfb68e0d1c6cb
 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
@@ -814,7 +814,7 @@
 F test/pragma.test ad99d05e411c7687302124be56f3b362204be041
 F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028
 F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
-F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
+F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
 F test/printf2.test b4acd4bf8734243257f01ddefa17c4fb090acc8a
 F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
@@ -1267,7 +1267,7 @@
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P aea439bdc6d4d3a8568423171abf381843188826 3ad829e50faca538db3abb2afb898b5521550c5c
-R 6129dbea29890bb446b2e1739ab50b2e
+P 271c110bcf5bf2ea7e113dd01dec876a08e3c047 8e4ac2ce24415926247961b00a62425ae85d6ffb
+R e52a83cd9a76eb22e0a9f49afec82395
 U drh
-Z 721c9e42efa32f899b87a4468b9be4bf
+Z 65d91c87ac07196da2d7921b7b9389b5
diff --git a/manifest.uuid b/manifest.uuid
index f982055..e451de8 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-271c110bcf5bf2ea7e113dd01dec876a08e3c047
\ No newline at end of file
+aeca95ac77f6f320a916f7e3c5a7a588ef4a20c8
\ No newline at end of file
diff --git a/src/printf.c b/src/printf.c
index 81efa05..9714fa1 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -261,15 +261,19 @@
       }
       if( width<0 ){
         flag_leftjustify = 1;
-        width = -width;
+        width = width >= -2147483647 ? -width : 0;
       }
       c = *++fmt;
     }else{
+      unsigned wx = 0;
       while( c>='0' && c<='9' ){
-        width = width*10 + c - '0';
+        wx = wx*10 + c - '0';
         c = *++fmt;
       }
+      testcase( wx>0x7fffffff );
+      width = wx & 0x7fffffff;
     }
+
     /* Get the precision */
     if( c=='.' ){
       precision = 0;
@@ -280,13 +284,18 @@
         }else{
           precision = va_arg(ap,int);
         }
-        if( precision<0 ) precision = -precision;
         c = *++fmt;
+        if( precision<0 ){
+          precision = precision >= -2147483647 ? -precision : -1;
+        }
       }else{
+        unsigned px = 0;
         while( c>='0' && c<='9' ){
-          precision = precision*10 + c - '0';
+          px = px*10 + c - '0';
           c = *++fmt;
         }
+        testcase( px>0x7fffffff );
+        precision = px & 0x7fffffff;
       }
     }else{
       precision = -1;
@@ -450,7 +459,8 @@
           else                         prefix = 0;
         }
         if( xtype==etGENERIC && precision>0 ) precision--;
-        for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
+        testcase( precision>0xfff );
+        for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
         if( xtype==etFLOAT ) realvalue += rounder;
         /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
         exp = 0;
@@ -505,8 +515,9 @@
         }else{
           e2 = exp;
         }
-        if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
-          bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
+        if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
+          bufpt = zExtra 
+              = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
           if( bufpt==0 ){
             setStrAccumError(pAccum, STRACCUM_NOMEM);
             return;
@@ -738,7 +749,7 @@
 */
 static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
   char *zNew;
-  assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */
+  assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
   if( p->accError ){
     testcase(p->accError==STRACCUM_TOOBIG);
     testcase(p->accError==STRACCUM_NOMEM);
@@ -787,7 +798,10 @@
 ** Append N copies of character c to the given string buffer.
 */
 void sqlite3AppendChar(StrAccum *p, int N, char c){
-  if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
+  testcase( p->nChar + (i64)N > 0x7fffffff );
+  if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
+    return;
+  }
   while( (N--)>0 ) p->zText[p->nChar++] = c;
 }
 
diff --git a/test/printf.test b/test/printf.test
index 7322272..6103d8a 100644
--- a/test/printf.test
+++ b/test/printf.test
@@ -472,6 +472,18 @@
   sqlite3_mprintf_int {abc: (%#6d) (%#6x) (%#6o) :xyz}\
        0xff676981 0xff676981 0xff676981
 } {abc: (-9999999) (0xff676981) (037731664601) :xyz}
+do_test printf-1.17.1 {
+  sqlite3_mprintf_int {abd: %2147483647d %2147483647x %2147483647o} 1 1 1
+} {}
+do_test printf-1.17.2 {
+  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}
@@ -526,6 +538,9 @@
 do_test printf-2.1.2.9 {
   sqlite3_mprintf_double {abc: %d %d (%1.1g) :xyz} 1 1 1.0e-20
 } {abc: 1 1 (1e-20) :xyz}
+do_test printf-2.1.2.10 {
+  sqlite3_mprintf_double {abc: %*.*f}  2000000000 1000000000 1.0e-20
+} {abc: }
 do_test printf-2.1.3.1 {
   sqlite3_mprintf_double {abc: (%*.*f) :xyz} 1 1 1.0
 } {abc: (1.0) :xyz}
@@ -3466,6 +3481,15 @@
 do_test printf-3.6 {
   sqlite3_mprintf_str {%d %d A String: (%-30s)} 1 2 {This is the string}
 } [format {%d %d A String: (%-30s)} 1 2 {This is the string}]
+do_test printf-3.7 {
+  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}
@@ -3685,6 +3709,9 @@
 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}