diff options
Diffstat (limited to 'stdio-common/vfscanf.c')
-rw-r--r-- | stdio-common/vfscanf.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c index aa0f091c06..29d96e48a4 100644 --- a/stdio-common/vfscanf.c +++ b/stdio-common/vfscanf.c @@ -1925,7 +1925,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) be punished. */ tw = (wchar_t *) f; /* Marks the beginning. */ - if (*f == ']' || *f == '-') + if (*f == L']') ++f; while ((fc = *f++) != L'\0' && fc != L']'); @@ -1985,7 +1985,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) runp = tw; while (runp < wp) { - if (runp[0] == L'-' && runp[1] != '\0' && runp[1] != ']' + if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp && runp != tw && (unsigned int) runp[-1] <= (unsigned int) runp[1]) { @@ -1993,32 +1993,40 @@ __vfscanf (FILE *s, const char *format, va_list argptr) first and last character of the sequence. */ wchar_t wc; - for (wc = runp[-1] + 1; wc < runp[1]; ++wc) + for (wc = runp[-1] + 1; wc <= runp[1]; ++wc) if (wc == c) break; - if (wc == runp[1] && !not_in) + if (wc <= runp[1] && !not_in) break; - if (wc == runp[1] && not_in) + if (wc <= runp[1] && not_in) { /* The current character is not in the scanset. */ ungetwc (c, s); goto out; } + + runp += 2; } else { - if (*runp == runp[1] && !not_in) + if (*runp == c && !not_in) break; - if (*runp != runp[1] && not_in) + if (*runp == c && not_in) { - ungetwc (c ,s); + ungetwc (c, s); goto out; } + + ++runp; } + } - ++runp; + if (runp == wp && !not_in) + { + ungetwc (c, s); + goto out; } if (!(flags & SUPPRESS)) @@ -2195,7 +2203,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr) runp = tw; while (runp < wp) { - if (runp[0] == L'-' && runp[1] != '\0' && runp[1] != ']' + if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp && runp != tw && (unsigned int) runp[-1] <= (unsigned int) runp[1]) { @@ -2203,32 +2211,40 @@ __vfscanf (FILE *s, const char *format, va_list argptr) first and last character of the sequence. */ wchar_t wc; - for (wc = runp[-1] + 1; wc < runp[1]; ++wc) + for (wc = runp[-1] + 1; wc <= runp[1]; ++wc) if (wc == c) break; - if (wc == runp[1] && !not_in) + if (wc <= runp[1] && !not_in) break; - if (wc == runp[1] && not_in) + if (wc <= runp[1] && not_in) { /* The current character is not in the scanset. */ ungetwc (c, s); goto out2; } + + runp += 2; } else { - if (*runp == runp[1] && !not_in) + if (*runp == c && !not_in) break; - if (*runp != runp[1] && not_in) + if (*runp == c && not_in) { - ungetwc (c ,s); + ungetwc (c, s); goto out2; } + + ++runp; } + } - ++runp; + if (runp == wp && !not_in) + { + ungetwc (c, s); + goto out2; } if (!(flags & SUPPRESS)) |