aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libiberty/ChangeLog9
-rw-r--r--libiberty/cp-demangle.c2
-rw-r--r--libiberty/cplus-dem.c16
-rw-r--r--libiberty/testsuite/demangle-expected15
4 files changed, 33 insertions, 9 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 34e585e..1e7a6c6 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,12 @@
+2017-04-27 Jonathan Wakely <jwakely@redhat.com>
+
+ PR demangler/80513
+ * cp-demangle.c (d_number): Check for overflow.
+ * cplus-dem.c (consume_count): Fix overflow check.
+ (gnu_special): Check for underscore after thunk delta.
+ * testsuite/demangle-expected: Add tests for overflows and invalid
+ characters in thunks.
+
2017-04-21 Mark Wielaard <mark@klomp.org>
* cp-demangle.c (MAX_RECURSION_COUNT): New constant.
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index e1db900..7b8d0b4 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -1692,6 +1692,8 @@ d_number (struct d_info *di)
ret = - ret;
return ret;
}
+ if (ret > ((INT_MAX - (peek - '0')) / 10))
+ return -1;
ret = ret * 10 + peek - '0';
d_advance (di, 1);
peek = d_peek_char (di);
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index a990e07..81c17a3 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -520,21 +520,17 @@ consume_count (const char **type)
while (ISDIGIT ((unsigned char)**type))
{
- count *= 10;
-
- /* Check for overflow.
- We assume that count is represented using two's-complement;
- no power of two is divisible by ten, so if an overflow occurs
- when multiplying by ten, the result will not be a multiple of
- ten. */
- if ((count % 10) != 0)
+ const int digit = **type - '0';
+ /* Check for overflow. */
+ if (count > ((INT_MAX - digit) / 10))
{
while (ISDIGIT ((unsigned char) **type))
(*type)++;
return -1;
}
- count += **type - '0';
+ count *= 10;
+ count += digit;
(*type)++;
}
@@ -3173,6 +3169,8 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp)
delta = consume_count (mangled);
if (delta == -1)
success = 0;
+ else if (**mangled != '_')
+ success = 0;
else
{
char *method = internal_cplus_demangle (work, ++*mangled);
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 45c5722..f2a12b9 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -4720,3 +4720,18 @@ _ZdvMMMMMMMMMMMMMrrrrA_DTdvfp_fp_Eededilfdfdfdfd
_Z1MA_aMMMMA_MMA_MMMMMMMMSt1MS_o11T0000000000t2M0oooozoooo
_Z1MA_aMMMMA_MMA_MMMMMMMMSt1MS_o11T0000000000t2M0oooozoooo
+
+#
+# demangler/80513 Test for overflow in d_number
+_Z4294967297x
+_Z4294967297x
+
+#
+# demangler/80513 Test for bogus characters after __thunk_
+__thunk_16a_$_1x
+__thunk_16a_$_1x
+
+#
+# demangler/80513 Test for overflow in consume_count
+__thunk_4294967297__$_1x
+__thunk_4294967297__$_1x