From: Jonathan Nieder Date: Mon, 4 Oct 2010 09:09:17 +0000 (-0500) Subject: xdiff: cast arguments for ctype functions to unsigned char X-Git-Tag: v1.7.3.2~22 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=349362cc207c96bbf31f503db989f0289c13c05d;p=git.git xdiff: cast arguments for ctype functions to unsigned char 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 Reported-by: Ævar Arnfjörð Bjarmason Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- diff --git a/xdiff/xmacros.h b/xdiff/xmacros.h index 8ef232cfa..165a895a9 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 6d6fc1bc5..9e13b25ab 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 22f9bd692..ab6503460 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');