This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: sscanf() problems
- From: Jeff Johnston <jjohnstn at redhat dot com>
- To: newlib at sourceware dot org
- Date: Wed, 3 Dec 2014 15:25:17 -0500 (EST)
- Subject: Re: sscanf() problems
- Authentication-results: sourceware.org; auth=none
- References: <547DA0B0 dot 1070707 at weiss-robotics dot de> <134867476 dot 16062418 dot 1417552087594 dot JavaMail dot zimbra at redhat dot com> <1417558948473 dot 17646 at LGSInnovations dot com> <696075606 dot 16204919 dot 1417564939882 dot JavaMail dot zimbra at redhat dot com>
I have checked in the attached patch.
-- Jeff J.
----- Original Message -----
> From: "Jeff Johnston" <jjohnstn@redhat.com>
> To: newlib@sourceware.org
> Sent: Tuesday, December 2, 2014 7:02:19 PM
> Subject: Re: sscanf() problems
>
> IMO, the correct thing to do is to alter the header file, but to do so
> without a warning. A comment should be added and noted that the library
> will ignore the macros if it has not been configured properly. The users
> that
> actually have a problem will get an error and have a way to find out why.
>
> -- Jeff J.
>
> ----- Original Message -----
> > From: "Craig D Howland" <howland@LGSInnovations.com>
> > To: newlib@sourceware.org
> > Sent: Tuesday, December 2, 2014 5:22:28 PM
> > Subject: RE: sscanf() problems
> >
> > Jeff:
> >
> > This sounds plausible, but then is also a bug: the SCN*8 defines in
> > inttypes.h should not be defined when _WANT_IO_C99_FORMATS is not. This
> > would provide a compilation error for the given test case. A #warning in
> > inttypes.h might be appropriate. (The C99 standard does explicitly call
> > for
> > the corresponding macros to not be defined if fscanf does not have a
> > suitable length modifier for the type.)
> >
> > For that matter, however, inttypes.h was added for C99, so an argument
> > could
> > be made that the entire file really should not be used if
> > _WANT_IO_C99_FORMATS has not been defined. In which case inttypes.h should
> > have a #error.
> >
> > So, for example something along these lines:
> >
> > Case 1, altered inttypes.h
> > #if !defined(_WANT_IO_C99_FORMATS)
> > #warning "inttypes.h is not entirely safe to use when
> > _WANT_IO_C99_FORMATS
> > is not defined"
> > #else
> > // define the SCN*8 stuff
> > #endif
> >
> > or
> >
> > Case 2, no inttypes.h
> > #if !defined(_WANT_IO_C99_FORMATS)
> > #error "inttypes.h must not be used when not full C99"
> > #endif
> >
> > Thoughts on which approach is better? The first choice is major approach,
> > for
> > either no or altered inttypes.h. If altered, there's a question as to
> > having
> > a #warning or not. The warning would be spurious for people not using
> > SCN*8.
> > People using SCN*8 will find out when compilation fails with or without a
> > #warning, but the #warning would give them an immediate clue as to why.
> >
> > Craig
> > ________________________________________
> > From: newlib-owner@sourceware.org <newlib-owner@sourceware.org> on behalf
> > of
> > Jeff Johnston <jjohnstn@redhat.com>
> > Sent: Tuesday, December 2, 2014 3:28 PM
> > To: Steffen Wolfer
> > Cc: newlib@sourceware.org
> > Subject: Re: sscanf() problems
> >
> > I believe I know what is happening.
> >
> > The SCNu8 macro expands to be hhu
> >
> > The vfscanf.c code only supports hh if the flag _WANT_IO_C99_FORMATS is set
> > to true. By default it is false in newlib/configure.host and for a few
> > select
> > platforms, it is set to true.
> >
> > If you did not configure your library with --enable-newlib-io-c99-formats,
> > then
> > it is false as arm doesn't set it to true.
> >
> > ...
> >
> > -- Jeff J.
> >
> > ----- Original Message -----
> > > From: "Steffen Wolfer" <wolfer@weiss-robotics.de>
> > > To: newlib@sourceware.org
> > > Sent: Tuesday, December 2, 2014 6:21:20 AM
> > > Subject: sscanf() problems
> > >
> > > -----BEGIN PGP SIGNED MESSAGE-----
> > > Hash: SHA1
> > >
> > > Dear all,
> > >
> > > I'm having the following, interesting problem using Newlib's sscanf().
> > > ...
> > >
> > >
> > > Thanks,
> > > Steffen
> >
> >
>
Index: inttypes.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/inttypes.h,v
retrieving revision 1.8
diff -u -p -r1.8 inttypes.h
--- inttypes.h 6 Nov 2014 17:45:14 -0000 1.8
+++ inttypes.h 3 Dec 2014 20:24:45 -0000
@@ -13,6 +13,7 @@
#ifndef _INTTYPES_H
#define _INTTYPES_H
+#include <newlib.h>
#include <sys/_intsup.h>
#include <stdint.h>
#define __need_wchar_t
@@ -22,7 +23,20 @@
/* 8-bit types */
#define __PRI8(x) __STRINGIFY(x)
-#define __SCN8(x) __STRINGIFY(hh##x)
+
+/* NOTICE: scanning 8-bit types requires use of the hh specifier
+ * which is only supported on newlib platforms that
+ * are built with C99 I/O format support enabled. If the flag in
+ * newlib.h hasn't been set during configuration to indicate this, the 8-bit
+ * scanning format macros are disabled here as they result in undefined
+ * behaviour which can include memory overwrite. Overriding the flag after the
+ * library has been built is not recommended as it will expose the underlying
+ * undefined behaviour.
+ */
+
+#if defined(_WANT_IO_C99_FORMATS)
+ #define __SCN8(x) __STRINGIFY(hh##x)
+#endif /* _WANT_IO_C99_FORMATS */
#define PRId8 __PRI8(d)
@@ -32,12 +46,17 @@
#define PRIx8 __PRI8(x)
#define PRIX8 __PRI8(X)
+/* Macros below are only enabled for a newlib built with C99 I/O format support. */
+#if defined(_WANT_IO_C99_FORMATS)
+
#define SCNd8 __SCN8(d)
#define SCNi8 __SCN8(i)
#define SCNo8 __SCN8(o)
#define SCNu8 __SCN8(u)
#define SCNx8 __SCN8(x)
+#endif /* _WANT_IO_C99_FORMATS */
+
#define PRIdLEAST8 __PRI8(d)
#define PRIiLEAST8 __PRI8(i)
@@ -46,12 +65,16 @@
#define PRIxLEAST8 __PRI8(x)
#define PRIXLEAST8 __PRI8(X)
-#define SCNdLEAST8 __SCN8(d)
-#define SCNiLEAST8 __SCN8(i)
-#define SCNoLEAST8 __SCN8(o)
-#define SCNuLEAST8 __SCN8(u)
-#define SCNxLEAST8 __SCN8(x)
+/* Macros below are only enabled for a newlib built with C99 I/O format support. */
+#if defined(_WANT_IO_C99_FORMATS)
+ #define SCNdLEAST8 __SCN8(d)
+ #define SCNiLEAST8 __SCN8(i)
+ #define SCNoLEAST8 __SCN8(o)
+ #define SCNuLEAST8 __SCN8(u)
+ #define SCNxLEAST8 __SCN8(x)
+
+#endif /* _WANT_IO_C99_FORMATS */
#define PRIdFAST8 __PRI8(d)
#define PRIiFAST8 __PRI8(i)
@@ -60,11 +83,16 @@
#define PRIxFAST8 __PRI8(x)
#define PRIXFAST8 __PRI8(X)
-#define SCNdFAST8 __SCN8(d)
-#define SCNiFAST8 __SCN8(i)
-#define SCNoFAST8 __SCN8(o)
-#define SCNuFAST8 __SCN8(u)
-#define SCNxFAST8 __SCN8(x)
+/* Macros below are only enabled for a newlib built with C99 I/O format support. */
+#if defined(_WANT_IO_C99_FORMATS)
+
+ #define SCNdFAST8 __SCN8(d)
+ #define SCNiFAST8 __SCN8(i)
+ #define SCNoFAST8 __SCN8(o)
+ #define SCNuFAST8 __SCN8(u)
+ #define SCNxFAST8 __SCN8(x)
+
+#endif /* _WANT_IO_C99_FORMATS */
/* 16-bit types */
#define __PRI16(x) __STRINGIFY(x)