diff options
-rw-r--r-- | libiberty/ChangeLog | 11 | ||||
-rw-r--r-- | libiberty/cplus-dem.c | 14 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 20 |
3 files changed, 41 insertions, 4 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index d0c5595..ea12ba2 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 c955bfb..3125a45 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 5badc3e..236161c 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. |