From f9fce963132b2a56a0f91bc19223a5c60f9786cb Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Thu, 16 May 2019 21:16:01 +0200 Subject: [PATCH 34/37] Fix unsigned integer overflow It's defined behavior but -fsanitize=unsigned-integer-overflow is useful to discover bugs. --- parser.c | 34 ++++++++++++++++++++-------------- result/errors/charref1.xml.err | 2 +- result/errors/charref1.xml.str | 2 +- timsort.h | 3 ++- uri.c | 6 ++++-- 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/parser.c b/parser.c index 2cab92c..459502b 100644 --- a/parser.c +++ b/parser.c @@ -2281,9 +2281,8 @@ xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) { */ int xmlParseCharRef(xmlParserCtxtPtr ctxt) { - unsigned int val = 0; + int val = 0; int count = 0; - unsigned int outofrange = 0; /* * Using RAW/CUR/NEXT is okay since we are working on ASCII range here @@ -2310,8 +2309,8 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) { val = 0; break; } - if (val > 0x10FFFF) - outofrange = val; + if (val > 0x110000) + val = 0x110000; NEXT; count++; @@ -2339,8 +2338,8 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) { val = 0; break; } - if (val > 0x10FFFF) - outofrange = val; + if (val > 0x110000) + val = 0x110000; NEXT; count++; @@ -2360,7 +2359,11 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) { * Characters referred to using character references must match the * production for Char. */ - if ((IS_CHAR(val) && (outofrange == 0))) { + if (val >= 0x110000) { + xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR, + "xmlParseCharRef: character reference out of bounds\n", + val); + } else if (IS_CHAR(val)) { return(val); } else { xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR, @@ -2392,8 +2395,7 @@ static int xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) { const xmlChar *ptr; xmlChar cur; - unsigned int val = 0; - unsigned int outofrange = 0; + int val = 0; if ((str == NULL) || (*str == NULL)) return(0); ptr = *str; @@ -2413,8 +2415,8 @@ xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) { val = 0; break; } - if (val > 0x10FFFF) - outofrange = val; + if (val > 0x110000) + val = 0x110000; ptr++; cur = *ptr; @@ -2432,8 +2434,8 @@ xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) { val = 0; break; } - if (val > 0x10FFFF) - outofrange = val; + if (val > 0x110000) + val = 0x110000; ptr++; cur = *ptr; @@ -2451,7 +2453,11 @@ xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) { * Characters referred to using character references must match the * production for Char. */ - if ((IS_CHAR(val) && (outofrange == 0))) { + if (val >= 0x110000) { + xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR, + "xmlParseStringCharRef: character reference out of bounds\n", + val); + } else if (IS_CHAR(val)) { return(val); } else { xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR, diff --git a/result/errors/charref1.xml.err b/result/errors/charref1.xml.err index aa43bcf..dbf3005 100644 --- a/result/errors/charref1.xml.err +++ b/result/errors/charref1.xml.err @@ -1,3 +1,3 @@ -./test/errors/charref1.xml:1: parser error : xmlParseCharRef: invalid xmlChar value 60 +./test/errors/charref1.xml:1: parser error : xmlParseCharRef: character reference out of bounds ^ diff --git a/result/errors/charref1.xml.str b/result/errors/charref1.xml.str index 467b4f6..692f614 100644 --- a/result/errors/charref1.xml.str +++ b/result/errors/charref1.xml.str @@ -1,4 +1,4 @@ -./test/errors/charref1.xml:1: parser error : xmlParseCharRef: invalid xmlChar value 60 +./test/errors/charref1.xml:1: parser error : xmlParseCharRef: character reference out of bounds ^ ./test/errors/charref1.xml : failed to parse diff --git a/timsort.h b/timsort.h index e841bd9..622705b 100644 --- a/timsort.h +++ b/timsort.h @@ -404,7 +404,8 @@ static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const in j = curr + A; k = curr + A + B; - while (k-- > curr) { + while (k > curr) { + k--; if ((i > 0) && (j > curr)) { if (SORT_CMP(dst[j - 1], storage[i - 1]) > 0) { dst[k] = dst[--j]; diff --git a/uri.c b/uri.c index 2cf8d9f..9772aaf 100644 --- a/uri.c +++ b/uri.c @@ -325,16 +325,18 @@ static int xmlParse3986Port(xmlURIPtr uri, const char **str) { const char *cur = *str; - unsigned port = 0; /* unsigned for defined overflow behavior */ + int port = 0; if (ISA_DIGIT(cur)) { while (ISA_DIGIT(cur)) { port = port * 10 + (*cur - '0'); + if (port > 99999999) + port = 99999999; cur++; } if (uri != NULL) - uri->port = port & INT_MAX; /* port value modulo INT_MAX+1 */ + uri->port = port; *str = cur; return(0); } -- 1.8.3.1