Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/newlib
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2010-01-20 02:16:45 +0300
committerJeff Johnston <jjohnstn@redhat.com>2010-01-20 02:16:45 +0300
commit044cd635339556d9876d322e858a6b96af9ce509 (patch)
treeb3b98d9b69afe0c3432220b9466e96cd987317ca /newlib
parent8c72ebb7e01640ea1916fa2637f20c0dab38e633 (diff)
2010-01-19 Andy Koppe <andy.koppe@gmail.com>
* libc/stdio/vfscanf.c (__SVFSCANF_R): Fix handling of non-ASCII characters and allow invalid bytes in format string.
Diffstat (limited to 'newlib')
-rw-r--r--newlib/ChangeLog5
-rw-r--r--newlib/libc/stdio/vfscanf.c19
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 <andy.koppe@gmail.com>
+
+ * libc/stdio/vfscanf.c (__SVFSCANF_R): Fix handling of non-ASCII
+ characters and allow invalid bytes in format string.
+
2010-01-19 Corinna Vinschen <corinna@vinschen.de>
* 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;