[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[sharutils PATCH] build: avoid range errors in use of ctype functions
From: |
Eric Blake |
Subject: |
[sharutils PATCH] build: avoid range errors in use of ctype functions |
Date: |
Tue, 6 Jan 2015 17:27:16 -0700 |
On platforms where 'char' is signed, using ctype functions on
'char' arguments produces undefined behavior for arguments that
are larger than 127. In particular, on Cygwin, isspace((char)255)
MUST return the same 0 result as isspace(EOF), while there are some
single-byte locales in which isspace((unsigned char)255) returns 1.
POSIX is explicit that the ctype functions are only well-defined on
the range of EOF plus the values of unsigned char.
There are also a number of ctype abuses in libopts/makeshell.c,
but as that file is generated rather than owned by sharutils, it
will need to be fixed upstream in the autogen package.
* src/shar.c (to_uchar): New helper, borrowed from coreutils.
(ISASCII, IS_GRAPH, process_shar_input, trim): Avoid range errors.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 4 ++++
src/shar.c | 21 +++++++++++++--------
2 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 4c7fa2a..8e0e590 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2015-01-06 Eric Blake <address@hidden>
+ build: avoid range errors in use of ctype functions
+ * src/shar.c (to_uchar): New helper, borrowed from coreutils.
+ (ISASCII, IS_GRAPH, process_shar_input, trim): Avoid range errors.
+
build: avoid error message failure on 64-bit hosts
* src/scribble.c (xscribble_get): Use correct specifier.
diff --git a/src/shar.c b/src/shar.c
index e2b315a..91e7e53 100644
--- a/src/shar.c
+++ b/src/shar.c
@@ -85,14 +85,19 @@ static const char cright_years_z[] =
/* System related declarations. */
+/* Convert a possibly-signed character to an unsigned character. This is
+ a bit safer than casting to unsigned char, since it catches some type
+ errors that the cast doesn't. */
+static inline unsigned char to_uchar (char ch) { return ch; }
+
#if STDC_HEADERS
# define ISASCII(Char) 1
#else
# ifdef isascii
-# define ISASCII(Char) isascii (Char)
+# define ISASCII(Char) isascii (to_uchar (Char))
# else
# if HAVE_ISASCII
-# define ISASCII(Char) isascii (Char)
+# define ISASCII(Char) isascii (to_uchar (Char))
# else
# define ISASCII(Char) ((Char) & 0x7f == (unsigned char) (Char))
# endif
@@ -100,9 +105,9 @@ static const char cright_years_z[] =
#endif
#ifdef isgraph
-#define IS_GRAPH(_c) isgraph (_c)
+#define IS_GRAPH(_c) isgraph (to_uchar (_c))
#else
-#define IS_GRAPH(_c) (isprint (_c) && !isspace (_c))
+#define IS_GRAPH(_c) (isprint (to_uchar (_c)) && !isspace (to_uchar (_c)))
#endif
struct tm *localtime ();
@@ -1580,8 +1585,8 @@ process_shar_input (FILE * input, off_t * size_left, int
* split_flag,
* Find the start of the last token
*/
e = p + strlen(p);
- while ( isspace (e[-1]) && (e > p)) e--;
- while (! isspace (e[-1]) && (e > p)) e--;
+ while ( isspace (to_uchar (e[-1])) && (e > p)) e--;
+ while (! isspace (to_uchar (e[-1])) && (e > p)) e--;
fwrite (p, e - p, 1, output);
fprintf (output, "_sh%05d/%s\n", (int)sharpid, cmpr_state->cmpr_mode);
}
@@ -2079,7 +2084,7 @@ static char *
trim (char * pz)
{
char * res;
- while (isspace (*pz)) pz++;
+ while (isspace (to_uchar (*pz))) pz++;
switch (*pz)
{
case NUL:
@@ -2088,7 +2093,7 @@ trim (char * pz)
}
res = pz;
pz += strlen (pz);
- while (isspace (pz[-1])) pz--;
+ while (isspace (to_uchar (pz[-1]))) pz--;
*pz = NUL;
return res;
}
--
2.1.0
- [sharutils PATCH] build: avoid range errors in use of ctype functions,
Eric Blake <=