{"thread":{"id":"25330","subject":"[PATCH] xdiff: cast arguments for ctype functions to unsigned char","startedAt":"2010-10-04T09:09:17Z","lastAt":"2010-10-04T09:09:17Z","messageCount":1,"participants":["Jonathan Nieder"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"152495","messageId":"20101004090917.GA14566@burratino","threadId":"25330","inReplyTo":null,"subject":"[PATCH] xdiff: cast arguments for ctype functions to unsigned char","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-10-04T09:09:17Z","receivedAt":"2010-10-04T09:09:17Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The ctype functions isspace(), isalnum(), et al take an integer\nargument representing an unsigned character, or -1 for EOF.  On\nplatforms with a signed char, it is unsafe to pass a char to them\nwithout casting it to unsigned char first.\n\nMost of git is already shielded against this by the ctype\nimplementation in git-compat-util.h, but xdiff, which uses libc\nctype.h, ought to be fixed.\n\nNoticed-by: der Mouse <mouse@Rodents-Montreal.ORG>\nReported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n xdiff/xmacros.h |    1 +\n xdiff/xmerge.c  |    2 +-\n xdiff/xutils.c  |   18 +++++++++---------\n 3 files changed, 11 insertions(+), 10 deletions(-)\n\ndiff --git a/xdiff/xmacros.h b/xdiff/xmacros.h\nindex 8ef232c..165a895 100644\n--- a/xdiff/xmacros.h\n+++ b/xdiff/xmacros.h\n@@ -30,6 +30,7 @@\n #define XDL_MAX(a, b) ((a) > (b) ? (a): (b))\n #define XDL_ABS(v) ((v) >= 0 ? (v): -(v))\n #define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9')\n+#define XDL_ISSPACE(c) (isspace((unsigned char)(c)))\n #define XDL_ADDBITS(v,b)\t((v) + ((v) >> (b)))\n #define XDL_MASKBITS(b)\t\t((1UL << (b)) - 1)\n #define XDL_HASHLONG(v,b)\t(XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))\ndiff --git a/xdiff/xmerge.c b/xdiff/xmerge.c\nindex 6d6fc1b..9e13b25 100644\n--- a/xdiff/xmerge.c\n+++ b/xdiff/xmerge.c\n@@ -336,7 +336,7 @@ static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m,\n static int line_contains_alnum(const char *ptr, long size)\n {\n \twhile (size--)\n-\t\tif (isalnum(*(ptr++)))\n+\t\tif (isalnum((unsigned char)*(ptr++)))\n \t\t\treturn 1;\n \treturn 0;\n }\ndiff --git a/xdiff/xutils.c b/xdiff/xutils.c\nindex 22f9bd6..ab65034 100644\n--- a/xdiff/xutils.c\n+++ b/xdiff/xutils.c\n@@ -211,18 +211,18 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)\n \t\t\tif (l1[i1++] != l2[i2++])\n \t\t\t\treturn 0;\n \t\tskip_ws:\n-\t\t\twhile (i1 < s1 && isspace(l1[i1]))\n+\t\t\twhile (i1 < s1 && XDL_ISSPACE(l1[i1]))\n \t\t\t\ti1++;\n-\t\t\twhile (i2 < s2 && isspace(l2[i2]))\n+\t\t\twhile (i2 < s2 && XDL_ISSPACE(l2[i2]))\n \t\t\t\ti2++;\n \t\t}\n \t} else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {\n \t\twhile (i1 < s1 && i2 < s2) {\n-\t\t\tif (isspace(l1[i1]) && isspace(l2[i2])) {\n+\t\t\tif (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) {\n \t\t\t\t/* Skip matching spaces and try again */\n-\t\t\t\twhile (i1 < s1 && isspace(l1[i1]))\n+\t\t\t\twhile (i1 < s1 && XDL_ISSPACE(l1[i1]))\n \t\t\t\t\ti1++;\n-\t\t\t\twhile (i2 < s2 && isspace(l2[i2]))\n+\t\t\t\twhile (i2 < s2 && XDL_ISSPACE(l2[i2]))\n \t\t\t\t\ti2++;\n \t\t\t\tcontinue;\n \t\t\t}\n@@ -241,13 +241,13 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)\n \t * while there still are characters remaining on both lines.\n \t */\n \tif (i1 < s1) {\n-\t\twhile (i1 < s1 && isspace(l1[i1]))\n+\t\twhile (i1 < s1 && XDL_ISSPACE(l1[i1]))\n \t\t\ti1++;\n \t\tif (s1 != i1)\n \t\t\treturn 0;\n \t}\n \tif (i2 < s2) {\n-\t\twhile (i2 < s2 && isspace(l2[i2]))\n+\t\twhile (i2 < s2 && XDL_ISSPACE(l2[i2]))\n \t\t\ti2++;\n \t\treturn (s2 == i2);\n \t}\n@@ -260,10 +260,10 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data,\n \tchar const *ptr = *data;\n \n \tfor (; ptr < top && *ptr != '\\n'; ptr++) {\n-\t\tif (isspace(*ptr)) {\n+\t\tif (XDL_ISSPACE(*ptr)) {\n \t\t\tconst char *ptr2 = ptr;\n \t\t\tint at_eol;\n-\t\t\twhile (ptr + 1 < top && isspace(ptr[1])\n+\t\t\twhile (ptr + 1 < top && XDL_ISSPACE(ptr[1])\n \t\t\t\t\t&& ptr[1] != '\\n')\n \t\t\t\tptr++;\n \t\t\tat_eol = (top <= ptr + 1 || ptr[1] == '\\n');\n-- \n1.7.2.3\n"}]}