172 lines
5.4 KiB
Diff
172 lines
5.4 KiB
Diff
From f9fce963132b2a56a0f91bc19223a5c60f9786cb Mon Sep 17 00:00:00 2001
|
|
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
|
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
|
|
<bla>�</bla>
|
|
^
|
|
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
|
|
<bla>�</bla>
|
|
^
|
|
./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
|
|
|