aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libiberty/ChangeLog11
-rw-r--r--libiberty/cplus-dem.c14
-rw-r--r--libiberty/testsuite/demangle-expected20
3 files changed, 41 insertions, 4 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index d0c5595fce..ea12ba277a 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,14 @@
+2016-11-14 Mark Wielaard <mark@klomp.org>
+
+ * cplus-dem.c (demangle_signature): After 'H', template function,
+ no success and don't advance position if end of string reached.
+ (demangle_template): After 'z', template name, return zero on
+ premature end of string.
+ (gnu_special): Guard strchr against searching for zero characters.
+ (do_type): If member, only advance mangled string when 'F' found.
+ * testsuite/demangle-expected: Add examples of strings that could
+ crash the demangler by reading past end of input.
+
2016-11-06 Mark Wielaard <mark@klomp.org>
* configure.ac (ac_libiberty_warn_cflags): Add -Wshadow=local.
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index c955bfbe1e..3125a457b9 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -1654,7 +1654,10 @@ demangle_signature (struct work_stuff *work,
0);
if (!(work->constructor & 1))
expect_return_type = 1;
- (*mangled)++;
+ if (!**mangled)
+ success = 0;
+ else
+ (*mangled)++;
break;
}
/* fall through */
@@ -2133,6 +2136,8 @@ demangle_template (struct work_stuff *work, const char **mangled,
{
int idx;
(*mangled)++;
+ if (**mangled == '\0')
+ return (0);
(*mangled)++;
idx = consume_count_with_underscores (mangled);
@@ -2977,7 +2982,7 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp)
int success = 1;
const char *p;
- if ((*mangled)[0] == '_'
+ if ((*mangled)[0] == '_' && (*mangled)[1] != '\0'
&& strchr (cplus_markers, (*mangled)[1]) != NULL
&& (*mangled)[2] == '_')
{
@@ -2991,7 +2996,7 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp)
&& (*mangled)[3] == 't'
&& (*mangled)[4] == '_')
|| ((*mangled)[1] == 'v'
- && (*mangled)[2] == 't'
+ && (*mangled)[2] == 't' && (*mangled)[3] != '\0'
&& strchr (cplus_markers, (*mangled)[3]) != NULL)))
{
/* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
@@ -3761,11 +3766,12 @@ do_type (struct work_stuff *work, const char **mangled, string *result)
break;
}
- if (*(*mangled)++ != 'F')
+ if (*(*mangled) != 'F')
{
success = 0;
break;
}
+ (*mangled)++;
}
if ((member && !demangle_nested_args (work, mangled, &decl))
|| **mangled != '_')
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 5badc3e584..236161c2fe 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -4606,3 +4606,23 @@ void f<void, int, false>(void (*)(int) noexcept)
_Z1fIvJiELb0EEvPDwiEFT_DpT0_E
void f<void, int, false>(void (*)(int) throw(int))
+
+# Could crash
+_
+_
+
+# Could crash
+_vt
+_vt
+
+# Could crash
+_$_1Acitz
+_$_1Acitz
+
+# Could crash
+_$_H1R
+_$_H1R
+
+# Could crash
+_Q8ccQ4M2e.
+_Q8ccQ4M2e.