/* Illustration of incorrect handling by *scanf of %c when a field width is specified. ANSI/ISO C99 states: c Matches a sequence of characters of exactly the number specified by the field width (1 if no field width is present in the directive). However, glibc's scanf returns success when fewer than the specified number of characters is read. $ diff -u glibc uClibc --- glibc 2003-08-14 09:00:03.000000000 -0500 +++ uClibc 2003-08-14 09:00:09.000000000 -0500 @@ -1,3 +1,3 @@ -r=1 buf="123456??????????????????" n1=6 -r=1 buf="123456??????????????????" n1=6 -r=1 buf="123456??????????????????" n1=6 +r=-1 buf="123456??????????????????" n1=-1 +r=-1 buf="123456??????????????????" n1=-1 +r=-1 buf="123456??????????????????" n1=-1 */ #define _GNU_SOURCE #include #include #include #include #include #include int main(void) { int r, n1, n2; FILE *fp; static const char fmt[] = "%7c%n"; static char membuf[] = { '1', '2', '3', '4', '5', '6' }; char buf[25]; memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; n1 = n2 = -1; errno = 0; r = sscanf(membuf, fmt, buf, &n1); printf("r=%d buf=\"%s\" n1=%d\n", r, buf, n1); if (!(fp = fmemopen(membuf, sizeof(membuf), "r"))) { printf("fmemopen failed\n"); return EXIT_FAILURE; } memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; n1 = n2 = -1; errno = 0; r = fscanf(fp, fmt, buf, &n1); printf("r=%d buf=\"%s\" n1=%d\n", r, buf, n1); fclose(fp); if (!(fp = fopen("scanf-c-bug.tst", "w+"))) { printf("fopen failed\n"); return EXIT_FAILURE; } if (fwrite(membuf, 1, sizeof(membuf), fp) != sizeof(membuf)) { printf("fwrite failed\n"); return EXIT_FAILURE; } rewind(fp); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; n1 = n2 = -1; errno = 0; r = fscanf(fp, fmt, buf, &n1); printf("r=%d buf=\"%s\" n1=%d\n", r, buf, n1); fclose(fp); return 0; }