Skip to content

Commit

Permalink
xdiff: cast arguments for ctype functions to unsigned char
Browse files Browse the repository at this point in the history
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@Rodents-Montreal.ORG>
Reported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jonathan Nieder authored and Junio C Hamano committed Oct 6, 2010
1 parent 9173912 commit 349362c
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 10 deletions.
1 change: 1 addition & 0 deletions xdiff/xmacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion xdiff/xmerge.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
18 changes: 9 additions & 9 deletions xdiff/xutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);
}
Expand All @@ -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');
Expand Down

0 comments on commit 349362c

Please sign in to comment.