/* Illustration of incorrect behavior for %.{precision}s when the corresponding arg is an illegal multibyte sequence in the current locale. ANSI/ISO C99 states If no l length modifier is present, the argument shall be a pointer to the initial element of an array of character type. {237: No special provisions are made for multibyte characters.} Characters from the array are written up to (but not including) the terminating null character. If the precision is specified, no more than that many bytes are written. $ diff -u glibc uClibc --- glibc 2003-08-13 18:04:38.000000000 -0500 +++ uClibc 2003-08-13 18:04:30.000000000 -0500 @@ -1,4 +1,5 @@ locale: en_US.UTF-8 n=3 buf="??????" n=15 buf=" ??????" -n=18 buf="n=-1 Invalid or incomplete multibyte or wide character +n=18 buf="??????" +n=16 Success */ #include #include #include #include int main(void) { const char *s; int n; unsigned char illegal_utf8[] = "\x80\x80\x80"; char buf[128]; if (!(s = setlocale(LC_ALL, "en_US.UTF-8"))) { printf("setlocale failed!\n"); return EXIT_FAILURE; } printf("locale: %s\n", s); memset(buf, 'x', 10); buf[10] = 0; n = snprintf(buf, sizeof(buf), "%s", illegal_utf8); n = printf("n=%d buf=\"%s\"\n", n, buf); n = printf("n=%d buf=\"%5s\"\n", n, buf); n = printf("n=%d buf=\"%.5s\"\n", n, buf); fflush(stdout); fprintf(stderr, "n=%d %m\n", n); return EXIT_SUCCESS; }