[PATCH v2] newlib: libc: Fix bugs in the commit 3d94e07c49b5.

Takashi Yano <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
The commit 3d94e07c49b5 has a few bugs which cause testsuite failure
in libstdc++. This is due to excess orientation check in __srefill_r()
and _ungetc_r(). Further, sscanf() family also calls ssvfscanf() family
with fp->_file == -1. This causes undesired orientation set/check for
sscanf() family. This patch fixes these problems.

Fixes: 3d94e07c49b5 ("newlib: libc: Fix crash on fprintf to a wide-oriented stream.")
Reported-by: Christophe Lyon <[email protected]>
Reported-by: Joel Sherrill <[email protected]>
Reviewed-by: Corinna Vinschen <[email protected]>
Signed-off-by: Takashi Yano <[email protected]>
---
 newlib/libc/stdio/local.h   | 35 ++++++++++++++++++++---------------
 newlib/libc/stdio/refill.c  |  3 ---
 newlib/libc/stdio/ungetc.c  |  8 ++------
 newlib/libc/stdio/ungetwc.c |  2 ++
 4 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h
index 3b86cf19a..dfb9fbbd0 100644
--- a/newlib/libc/stdio/local.h
+++ b/newlib/libc/stdio/local.h
@@ -231,21 +231,26 @@ extern _READ_WRITE_RETURN_TYPE __swrite64 (struct _reent *, void *,
  * Set the orientation for a stream. If o > 0, the stream has wide-
  * orientation. If o < 0, the stream has byte-orientation.
  */
-#define ORIENT(fp,ori)			\
-  (					\
-    (					\
-      ((fp)->_flags & __SORD) ?		\
-	0				\
-      :					\
-	(				\
-	  ((fp)->_flags |= __SORD),	\
-	  (ori > 0) ?			\
-	    ((fp)->_flags2 |= __SWID)	\
-	  :				\
-	    ((fp)->_flags2 &= ~__SWID)	\
-	)				\
-    ),					\
-    ((fp)->_flags2 & __SWID) ? 1 : -1	\
+#define ORIENT(fp,ori)				\
+  (						\
+    ((fp)->_file < 0) ?				\
+      ((ori > 0) ? 1 : -1)			\
+    :						\
+      (						\
+	(					\
+	  ((fp)->_flags & __SORD) ?		\
+	    0					\
+	  :					\
+	    (					\
+	      ((fp)->_flags |= __SORD),		\
+	      (ori > 0) ?			\
+		((fp)->_flags2 |= __SWID)	\
+	      :					\
+		((fp)->_flags2 &= ~__SWID)	\
+	    )					\
+	),					\
+	((fp)->_flags2 & __SWID) ? 1 : -1	\
+      )						\
   )
 #else
 #define ORIENT(fp,ori) (-1)
diff --git a/newlib/libc/stdio/refill.c b/newlib/libc/stdio/refill.c
index c1ef7e120..cd71ed152 100644
--- a/newlib/libc/stdio/refill.c
+++ b/newlib/libc/stdio/refill.c
@@ -43,9 +43,6 @@ __srefill_r (struct _reent * ptr,
 
   CHECK_INIT (ptr, fp);
 
-  if (ORIENT (fp, -1) != -1)
-    return EOF;
-
   fp->_r = 0;			/* largely a convenience for callers */
 
   /* SysV does not make this test; take it out for compatibility */
diff --git a/newlib/libc/stdio/ungetc.c b/newlib/libc/stdio/ungetc.c
index 79914af08..5053fd6c4 100644
--- a/newlib/libc/stdio/ungetc.c
+++ b/newlib/libc/stdio/ungetc.c
@@ -125,12 +125,6 @@ _ungetc_r (struct _reent *rptr,
 
   _newlib_flockfile_start (fp);
 
-  if (ORIENT (fp, -1) != -1)
-    {
-      _newlib_flockfile_exit (fp);
-      return EOF;
-    }
-
   /* After ungetc, we won't be at eof anymore */
   fp->_flags &= ~__SEOF;
 
@@ -213,6 +207,8 @@ int
 ungetc (int c,
        register FILE *fp)
 {
+  if (ORIENT (fp, -1) != -1)
+    return EOF;
   return _ungetc_r (_REENT, c, fp);
 }
 #endif /* !_REENT_ONLY */
diff --git a/newlib/libc/stdio/ungetwc.c b/newlib/libc/stdio/ungetwc.c
index 18636d773..002b6292a 100644
--- a/newlib/libc/stdio/ungetwc.c
+++ b/newlib/libc/stdio/ungetwc.c
@@ -112,5 +112,7 @@ ungetwc (wint_t wc,
   struct _reent *reent = _REENT;
 
   CHECK_INIT (reent, fp);
+  if (ORIENT (fp, 1) != 1)
+    return WEOF;
   return _ungetwc_r (reent, wc, fp);
 }
-- 
2.39.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.