/* Illustration of errors in glibc's scanf implementation when dealing with grouped integers. Excess digits and grouping characters are inappropriately consumed, even when they should cause matching failures. Also, grouping is not handled correctly in the te_IN.UTF-8 locale. diff -u glibc uClibc --- glibc 2003-08-16 21:45:02.000000000 -0500 +++ uClibc 2003-08-16 21:45:02.000000000 -0500 @@ -1,17 +1,17 @@ -locale: en_US.UTF-8 grouping: 3 3 -r= 2 i= 12 n1=0 n2= 6 buf="x" -r= 1 i= 12 n1=0 n2= 4 buf="?????????" -r= 1 i= 12456789 n1=0 n2= 12 buf="?????????" +locale: en_US.UTF-8 grouping: 3 +r= 0 i= 0 n1=0 n2= -1 buf="?????????" +r= 2 i= 12 n1=0 n2= 3 buf="," +r= 2 i= 12456789 n1=0 n2= 11 buf="," locale: en_IN.UTF-8 grouping: 3 2 -r= 1 i= 1234567 n1=0 n2= 11 buf="?????????" -r= 1 i= 12345 n1=0 n2= 11 buf="?????????" -r= 1 i= 123 n1=0 n2= 8 buf="?????????" -r= 1 i= 12345 n1=0 n2= 8 buf="?????????" +r= 2 i= 1234567 n1=0 n2= 10 buf="," +r= 2 i= 12345 n1=0 n2= 7 buf=",67," +r= 2 i= 123 n1=0 n2= 4 buf=",45," +r= 2 i= 12345 n1=0 n2= 7 buf="," locale: te_IN.UTF-8 grouping: 2 3 -r= 1 i= 12 n1=0 n2= 11 buf="?????????" -r= 1 i= 1234567 n1=0 n2= 11 buf="?????????" -r= 1 i= 12345 n1=0 n2= 8 buf="?????????" -r= 1 i= 1234 n1=0 n2= 8 buf="?????????" -r= 1 i= 1234 n1=0 n2= 7 buf="?????????" -r= 1 i= 1234 n1=0 n2= 7 buf="?????????" -r= 1 i= 12 n1=0 n2= 5 buf="?????????" +r= 2 i= 1234 n1=0 n2= 6 buf=",567," +r= 2 i= 1234567 n1=0 n2= 10 buf="," +r= 2 i= 12345 n1=0 n2= 7 buf="," +r=-1 i= 0 n1=0 n2= -1 buf="?????????" +r= 2 i= 1234 n1=0 n2= 6 buf="5" +r= 2 i= 1234 n1=0 n2= 6 buf="," +r=-1 i= 0 n1=0 n2= -1 buf="?????????" */ #include #include #include #include #include int main(void) { int r, n1, n2, i; const char *s; const char *g; struct lconv *lc; char buf[10]; if (!(s = setlocale(LC_ALL, "en_US.UTF-8"))) { printf("setlocale failed!\n"); return EXIT_FAILURE; } lc = localeconv(); printf("locale: %s grouping:", s); for (g = lc->grouping ; *g ; g++) { printf(" %d", *g); } printf("\n"); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,34x", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,456,789,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); if (!(s = setlocale(LC_ALL, "en_IN.UTF-8"))) { printf("setlocale failed!\n"); return EXIT_FAILURE; } lc = localeconv(); printf("locale: %s grouping:", s); for (g = lc->grouping ; *g ; g++) { printf(" %d", *g); } printf("\n"); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,34,567,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,345,67,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 123,45,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,345,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); if (!(s = setlocale(LC_ALL, "te_IN.UTF-8"))) { printf("setlocale failed!\n"); return EXIT_FAILURE; } lc = localeconv(); printf("locale: %s grouping:", s); for (g = lc->grouping ; *g ; g++) { printf(" %d", *g); } printf("\n"); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,34,567,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,345,67,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 123,45,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,345,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,345", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,34,", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); memset(buf, '?', sizeof(buf)); buf[sizeof(buf)-1] = 0; i = 0; n1 = n2 = -1; errno = 0; r = sscanf(" 12,3", "%n%'i%n%s", &n1, &i, &n2, buf); printf("r=%2d i=%11i n1=%d n2=%3d buf=\"%s\"\n", r, i, n1,n2, buf); return 0; }