2007-10-28 Ulrich Drepper <drepper@redhat.com> [BZ #5225] * stdio-common/vfscanf.c (_IO_vfwscanf): Don't misuse wp pointer to keep track of end of %[ format string element. * stdio-common/Makefile (tests): Add bug20. * stdio-common/bug20.c: New file. --- libc/stdio-common/vfscanf.c 18 Sep 2007 18:56:29 -0000 1.126 +++ libc/stdio-common/vfscanf.c 28 Oct 2007 08:40:36 -0000 1.127 @@ -272,7 +272,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const { \ CHAR_T *old = wp; \ wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \ - wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \ + wp = (CHAR_T *) alloca (wpmax * sizeof (CHAR_T)); \ if (old != NULL) \ MEMCPY (wp, old, wpsize); \ } \ @@ -2314,7 +2314,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const if (__builtin_expect (fc == L'\0', 0)) conv_error (); - wp = (wchar_t *) f - 1; + wchar_t *twend = (wchar_t *) f - 1; #else /* Fill WP with byte flags indexed by character. We will use this flag map for matching input characters. */ @@ -2365,9 +2365,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const /* Test whether it's in the scanlist. */ runp = tw; - while (runp < wp) + while (runp < twend) { - if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp + if (runp[0] == L'-' && runp[1] != '\0' + && runp + 1 != twend && runp != tw && (unsigned int) runp[-1] <= (unsigned int) runp[1]) { @@ -2405,7 +2406,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const } } - if (runp == wp && !not_in) + if (runp == twend && !not_in) { ungetc (c, s); goto out; @@ -2590,9 +2591,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const /* Test whether it's in the scanlist. */ runp = tw; - while (runp < wp) + while (runp < twend) { - if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp + if (runp[0] == L'-' && runp[1] != '\0' + && runp + 1 != twend && runp != tw && (unsigned int) runp[-1] <= (unsigned int) runp[1]) { @@ -2630,7 +2632,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const } } - if (runp == wp && !not_in) + if (runp == twend && !not_in) { ungetc (c, s); goto out2; --- libc/stdio-common/Makefile 18 Sep 2007 18:54:24 -0000 1.108 +++ libc/stdio-common/Makefile 28 Oct 2007 16:45:08 -0000 1.109 @@ -55,7 +55,7 @@ tests := tstscanf test_rdwr test-popen t tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 bug15 \ tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \ tst-fwrite bug16 bug17 tst-sprintf2 bug18 bug18a bug19 bug19a \ - tst-popen2 + tst-popen2 bug20 test-srcs = tst-unbputc tst-printf --- libc/stdio-common/bug20.c 1 Jan 1970 00:00:00 -0000 +++ libc/stdio-common/bug20.c 28 Oct 2007 16:45:01 -0000 1.1 @@ -0,0 +1,32 @@ +/* BZ #5225 */ +#include <stdio.h> +#include <string.h> +#include <wchar.h> + +static int +do_test (void) +{ + wchar_t in[] = L"123,abc,321"; + /* This is the critical part for this test. format must be in + read-only memory. */ + static const wchar_t format[50] = L"%d,%[^,],%d"; + int out_d1, out_d2; + char out_s[50]; + printf ("in='%ls' format='%ls'\n", in, format); + if (swscanf (in, format, &out_d1, out_s, &out_d2) != 3) + { + puts ("swscanf did not return 3"); + return 1; + } + printf ("in='%ls' format='%ls'\n", in, format); + printf ("out_d1=%d out_s='%s' out_d2=%d\n", out_d1, out_s, out_d2); + if (out_d1 != 123 || strcmp (out_s, "abc") != 0 || out_d2 != 321) + { + puts ("swscanf did not return the correct values"); + return 1; + } + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c"