/* Illustration of glibc's scanf accepting numeric strings as valid even though they are missing required digits. The problem affects both hexadecimal integer and floating point conversions. $ diff -u glibc uClibc --- glibc 2003-08-16 19:31:23.000000000 -0500 +++ uClibc 2003-08-16 19:31:22.000000000 -0500 @@ -1,7 +1,7 @@ -count=2 n=3 quant=0.000000 buf="!" -count=2 n=5 quant=0.000000 buf="!" -count=2 n=3 quant=0.000000 buf="!" -count=2 n=4 quant=0.000000 buf="!" -count=2 n=5 quant=0.000000 buf="!" -count=2 n=2 iquant=0 buf="!" -count=1 n=2 iquant=0 buf="?????????" +count=0 n=-1 quant=nan buf="?????????" +count=0 n=-1 quant=nan buf="?????????" +count=0 n=-1 quant=nan buf="?????????" +count=0 n=-1 quant=nan buf="?????????" +count=0 n=-1 quant=nan buf="?????????" +count=0 n=-1 iquant=-2147483648 buf="?????????" +count=2 n=1 iquant=0 buf="x" */ #define _GNU_SOURCE #include #include #include #include #include #include #include int main(void) { FILE *fp; float quant; int count, n, iquant; char buf[10]; static char membuf[] = "0xp!\n" "0xp-!\n" "0e!\n" ".0e!\n" ".0e+!\n" ; if (!(fp = fmemopen(membuf, sizeof(membuf)-1, "r"))) { /* omit trailing nul */ printf("fmemopen failed\n"); return EXIT_FAILURE; } do { quant = 0./0.; n = -1; memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; count = fscanf(fp, "%f%n%s", &quant, &n, buf); if (ferror(fp)) { printf("stream error indicator is set!\n"); fclose(fp); return EXIT_FAILURE; } if (feof(fp)) { fclose(fp); break; } printf("count=%d n=%d quant=%f buf=\"%s\"\n", count, n, quant, buf); fscanf(fp,"%*[^\n]"); } while (1); iquant = INT_MIN; n = -1; memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; count = sscanf("0x!", "%x%n%s", &iquant, &n, buf); printf("count=%d n=%d iquant=%d buf=\"%s\"\n", count, n, iquant, buf); iquant = INT_MIN; n = -1; memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; count = sscanf("0x", "%x%n%s", &iquant, &n, buf); printf("count=%d n=%d iquant=%d buf=\"%s\"\n", count, n, iquant, buf); return EXIT_SUCCESS; }