[PATCH] xdiff: cast arguments for ctype functions to unsigned char

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The ctype functions isspace(), isalnum(), et al take an integer
argument representing an unsigned character, or -1 for EOF.  On
platforms with a signed char, it is unsafe to pass a char to them
without casting it to unsigned char first.

Most of git is already shielded against this by the ctype
implementation in git-compat-util.h, but xdiff, which uses libc
ctype.h, ought to be fixed.

Noticed-by: der Mouse <mouse@xxxxxxxxxxxxxxxxxxxx>
Reported-by: Ãvar ArnfjÃrà Bjarmason <avarab@xxxxxxxxx>
Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx>
---
 xdiff/xmacros.h |    1 +
 xdiff/xmerge.c  |    2 +-
 xdiff/xutils.c  |   18 +++++++++---------
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/xdiff/xmacros.h b/xdiff/xmacros.h
index 8ef232c..165a895 100644
--- a/xdiff/xmacros.h
+++ b/xdiff/xmacros.h
@@ -30,6 +30,7 @@
 #define XDL_MAX(a, b) ((a) > (b) ? (a): (b))
 #define XDL_ABS(v) ((v) >= 0 ? (v): -(v))
 #define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
+#define XDL_ISSPACE(c) (isspace((unsigned char)(c)))
 #define XDL_ADDBITS(v,b)	((v) + ((v) >> (b)))
 #define XDL_MASKBITS(b)		((1UL << (b)) - 1)
 #define XDL_HASHLONG(v,b)	(XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
diff --git a/xdiff/xmerge.c b/xdiff/xmerge.c
index 6d6fc1b..9e13b25 100644
--- a/xdiff/xmerge.c
+++ b/xdiff/xmerge.c
@@ -336,7 +336,7 @@ static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m,
 static int line_contains_alnum(const char *ptr, long size)
 {
 	while (size--)
-		if (isalnum(*(ptr++)))
+		if (isalnum((unsigned char)*(ptr++)))
 			return 1;
 	return 0;
 }
diff --git a/xdiff/xutils.c b/xdiff/xutils.c
index 22f9bd6..ab65034 100644
--- a/xdiff/xutils.c
+++ b/xdiff/xutils.c
@@ -211,18 +211,18 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
 			if (l1[i1++] != l2[i2++])
 				return 0;
 		skip_ws:
-			while (i1 < s1 && isspace(l1[i1]))
+			while (i1 < s1 && XDL_ISSPACE(l1[i1]))
 				i1++;
-			while (i2 < s2 && isspace(l2[i2]))
+			while (i2 < s2 && XDL_ISSPACE(l2[i2]))
 				i2++;
 		}
 	} else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
 		while (i1 < s1 && i2 < s2) {
-			if (isspace(l1[i1]) && isspace(l2[i2])) {
+			if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) {
 				/* Skip matching spaces and try again */
-				while (i1 < s1 && isspace(l1[i1]))
+				while (i1 < s1 && XDL_ISSPACE(l1[i1]))
 					i1++;
-				while (i2 < s2 && isspace(l2[i2]))
+				while (i2 < s2 && XDL_ISSPACE(l2[i2]))
 					i2++;
 				continue;
 			}
@@ -241,13 +241,13 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
 	 * while there still are characters remaining on both lines.
 	 */
 	if (i1 < s1) {
-		while (i1 < s1 && isspace(l1[i1]))
+		while (i1 < s1 && XDL_ISSPACE(l1[i1]))
 			i1++;
 		if (s1 != i1)
 			return 0;
 	}
 	if (i2 < s2) {
-		while (i2 < s2 && isspace(l2[i2]))
+		while (i2 < s2 && XDL_ISSPACE(l2[i2]))
 			i2++;
 		return (s2 == i2);
 	}
@@ -260,10 +260,10 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data,
 	char const *ptr = *data;
 
 	for (; ptr < top && *ptr != '\n'; ptr++) {
-		if (isspace(*ptr)) {
+		if (XDL_ISSPACE(*ptr)) {
 			const char *ptr2 = ptr;
 			int at_eol;
-			while (ptr + 1 < top && isspace(ptr[1])
+			while (ptr + 1 < top && XDL_ISSPACE(ptr[1])
 					&& ptr[1] != '\n')
 				ptr++;
 			at_eol = (top <= ptr + 1 || ptr[1] == '\n');
-- 
1.7.2.3

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]