From 044cd635339556d9876d322e858a6b96af9ce509 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Tue, 19 Jan 2010 23:16:45 +0000 Subject: [PATCH] 2010-01-19 Andy Koppe * libc/stdio/vfscanf.c (__SVFSCANF_R): Fix handling of non-ASCII characters and allow invalid bytes in format string. --- newlib/ChangeLog | 5 +++++ newlib/libc/stdio/vfscanf.c | 19 +++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 281529b5c..7ff327b9c 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,8 @@ +2010-01-19 Andy Koppe + + * libc/stdio/vfscanf.c (__SVFSCANF_R): Fix handling of non-ASCII + characters and allow invalid bytes in format string. + 2010-01-19 Corinna Vinschen * libc/stdlib/wcstombs_r.c (_wcstombs_r): Handle invalid characters diff --git a/newlib/libc/stdio/vfscanf.c b/newlib/libc/stdio/vfscanf.c index 065dc3e89..fa4c598cf 100644 --- a/newlib/libc/stdio/vfscanf.c +++ b/newlib/libc/stdio/vfscanf.c @@ -459,7 +459,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), u_long (*ccfn)CCFN_PARAMS=0; /* conversion function (strtol/strtoul) */ char ccltab[256]; /* character class table for %[...] */ char buf[BUF]; /* buffer for numeric conversions */ - char *lptr; /* literal pointer */ + unsigned char *lptr; /* literal pointer */ char *cp; short *sp; @@ -501,16 +501,25 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), nassigned = 0; nread = 0; +#ifdef _MB_CAPABLE + memset (&state, 0, sizeof (state)); +#endif + for (;;) { #ifndef _MB_CAPABLE wc = *fmt; #else - memset (&state, '\0', sizeof (state)); nbytes = __mbtowc (rptr, &wc, fmt, MB_CUR_MAX, __locale_charset (), &state); + if (nbytes < 0) { + wc = 0xFFFD; /* Unicode replacement character */ + nbytes = 1; + memset (&state, 0, sizeof (state)); + } #endif fmt += nbytes; + if (wc == 0) goto all_done; if (nbytes == 1 && isspace (wc)) @@ -839,6 +848,8 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), #if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2 if (flags & LONG) { + mbstate_t state; + memset (&state, 0, sizeof (mbstate_t)); if ((flags & SUPPRESS) == 0) wcp = GET_ARG (N, ap, wchar_t *); else @@ -851,7 +862,6 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), buf[n++] = *fp->_p; fp->_r -= 1; fp->_p += 1; - memset ((_PTR)&state, '\0', sizeof (mbstate_t)); if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state)) == (size_t)-1) goto input_failure; /* Invalid sequence */ @@ -971,6 +981,8 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), if (flags & LONG) { /* Process %S and %ls placeholders */ + mbstate_t state; + memset (&state, 0, sizeof (mbstate_t)); if ((flags & SUPPRESS) == 0) wcp = GET_ARG (N, ap, wchar_t *); else @@ -983,7 +995,6 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), buf[n++] = *fp->_p; fp->_r -= 1; fp->_p += 1; - memset ((_PTR)&state, '\0', sizeof (mbstate_t)); if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state)) == (size_t)-1) goto input_failure;