@matheusbsbs / matheus-bagliano / commits / 349362cc20
Fork 0

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 <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>

Jonathan Nieder committed Oct 4, 2010 at 04:09 UTC 349362cc207c96bbf31f503db989f0289c13c05d
3 files changed +11 -10
xdiff/xmacros.h
+1
@@ -30,6 +30,7 @@
30 #define XDL_MAX(a, b) ((a) > (b) ? (a): (b))
31 #define XDL_ABS(v) ((v) >= 0 ? (v): -(v))
32 #define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
33 +#define XDL_ISSPACE(c) (isspace((unsigned char)(c)))
34 #define XDL_ADDBITS(v,b) ((v) + ((v) >> (b)))
35 #define XDL_MASKBITS(b) ((1UL << (b)) - 1)
36 #define XDL_HASHLONG(v,b) (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
xdiff/xmerge.c
+1 -1
@@ -336,7 +336,7 @@ static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m,
336 static int line_contains_alnum(const char *ptr, long size)
337 {
338 while (size--)
339 - if (isalnum(*(ptr++)))
339 + if (isalnum((unsigned char)*(ptr++)))
340 return 1;
341 return 0;
342 }
xdiff/xutils.c
+9 -9
@@ -211,18 +211,18 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
211 if (l1[i1++] != l2[i2++])
212 return 0;
213 skip_ws:
214 - while (i1 < s1 && isspace(l1[i1]))
214 + while (i1 < s1 && XDL_ISSPACE(l1[i1]))
215 i1++;
216 - while (i2 < s2 && isspace(l2[i2]))
216 + while (i2 < s2 && XDL_ISSPACE(l2[i2]))
217 i2++;
218 }
219 } else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
220 while (i1 < s1 && i2 < s2) {
221 - if (isspace(l1[i1]) && isspace(l2[i2])) {
221 + if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) {
222 /* Skip matching spaces and try again */
223 - while (i1 < s1 && isspace(l1[i1]))
223 + while (i1 < s1 && XDL_ISSPACE(l1[i1]))
224 i1++;
225 - while (i2 < s2 && isspace(l2[i2]))
225 + while (i2 < s2 && XDL_ISSPACE(l2[i2]))
226 i2++;
227 continue;
228 }
@@ -241,13 +241,13 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
241 * while there still are characters remaining on both lines.
242 */
243 if (i1 < s1) {
244 - while (i1 < s1 && isspace(l1[i1]))
244 + while (i1 < s1 && XDL_ISSPACE(l1[i1]))
245 i1++;
246 if (s1 != i1)
247 return 0;
248 }
249 if (i2 < s2) {
250 - while (i2 < s2 && isspace(l2[i2]))
250 + while (i2 < s2 && XDL_ISSPACE(l2[i2]))
251 i2++;
252 return (s2 == i2);
253 }
@@ -260,10 +260,10 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data,
260 char const *ptr = *data;
261
262 for (; ptr < top && *ptr != '\n'; ptr++) {
263 - if (isspace(*ptr)) {
263 + if (XDL_ISSPACE(*ptr)) {
264 const char *ptr2 = ptr;
265 int at_eol;
266 - while (ptr + 1 < top && isspace(ptr[1])
266 + while (ptr + 1 < top && XDL_ISSPACE(ptr[1])
267 && ptr[1] != '\n')
268 ptr++;
269 at_eol = (top <= ptr + 1 || ptr[1] == '\n');