[libxml2] Fix unsigned integer overflow



commit f9fce963132b2a56a0f91bc19223a5c60f9786cb
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Thu May 16 21:16:01 2019 +0200

    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 2cab92c6..459502b5 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 aa43bcf4..dbf30054 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
 <bla>&#010100000000000000000000000000000000000000000000000060;</bla>
                                                               ^
diff --git a/result/errors/charref1.xml.str b/result/errors/charref1.xml.str
index 467b4f6a..692f614e 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
 <bla>&#010100000000000000000000000000000000000000000000000060;</bla>
                                                               ^
 ./test/errors/charref1.xml : failed to parse
diff --git a/timsort.h b/timsort.h
index e841bd9c..622705b3 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 2cf8d9f1..9772aafa 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);
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]