fix scanf handling of "0" (followed by immediate EOF) with "%x"
authorRich Felker <dalias@aerifal.cx>
Tue, 13 Mar 2012 16:37:51 +0000 (12:37 -0400)
committerRich Felker <dalias@aerifal.cx>
Tue, 13 Mar 2012 16:37:51 +0000 (12:37 -0400)
other cases with %x were probably broken too.

I would actually like to go ahead and replace this code in scanf with
calls to the new __intparse framework, but for now this calls for a
quick and unobtrusive fix without the risk of breaking other things.

src/stdio/__scanf.c

index 062327d75c5851e7b014bb5e03742e19e6ab1409..7c82cca4016a5297ba3a5b0d23dbeb88772710b7 100644 (file)
@@ -319,34 +319,29 @@ int __scanf(rctx_t *r, const wchar_t *fmt, va_list ap)
                                        unread(r);
                                        break;
                                }
+                               m = 1;
                                if (((c=read(r))|0x20) != 'x') {
-                                       if (t == 'i') {
-                                               t = 'o';
-                                               /* lone 0 is valid octal */
-                                               if ((unsigned)(c-'0') >= 8) {
-                                                       m = 1;
-                                                       goto int_finish;
-                                               }
-                                       }
+                                       if (t == 'i') t = 'o';
                                        unread(r);
                                        break;
                                }
                                t = 'x';
+                               m = 0;
                        }
                }
                
                switch (t) {
                case 'd':
                case 'u':
-                       for (m=0; isdigit(c=read(r)); m=1)
+                       for (; isdigit(c=read(r)); m=1)
                                i = 10*i + c-'0';
                        goto int_finish;
                case 'o':
-                       for (m=0; (unsigned)(c=read(r))-'0' < 8; m=1)
+                       for (; (unsigned)(c=read(r))-'0' < 8; m=1)
                                i = (i<<3) + c-'0';
                        goto int_finish;
                case 'x':
-                       for (m=0; ; m=1) {
+                       for (; ; m=1) {
                                if (isdigit(c=read(r))) {
                                        i = (i<<4) + c-'0';
                                } else if ((unsigned)(c|0x20)-'a' < 6) {