diff options
author | Mikhail Maltsev <maltsevm@gmail.com> | 2015-11-28 16:39:29 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-11-28 16:39:29 +0000 |
commit | d81bf7ddc2ad497037fbfde5d15cfa8d81a9e959 (patch) | |
tree | 926b0c2c076cb449874747186878d3da93564104 /libiberty/cp-demangle.h | |
parent | 6a8796db3691b9a53dc5475eaec5388bc1af115d (diff) | |
download | gdb-d81bf7ddc2ad497037fbfde5d15cfa8d81a9e959.zip gdb-d81bf7ddc2ad497037fbfde5d15cfa8d81a9e959.tar.gz gdb-d81bf7ddc2ad497037fbfde5d15cfa8d81a9e959.tar.bz2 |
Fix several crashes of C++ demangler on fuzzed input.
libiberty/
* cp-demangle.c (d_dump): Fix syntax error.
(d_identifier): Adjust type of len to match d_source_name.
(d_expression_1): Fix out-of-bounds access. Check code variable for
NULL before dereferencing it.
(d_find_pack): Do not recurse for FIXED_TYPE, DEFAULT_ARG and NUMBER.
(d_print_comp_inner): Add NULL pointer check.
* cp-demangle.h (d_peek_next_char): Define as inline function when
CHECK_DEMANGLER is defined.
(d_advance): Likewise.
* testsuite/demangle-expected: Add new testcases.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225727 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libiberty/cp-demangle.h')
-rw-r--r-- | libiberty/cp-demangle.h | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/libiberty/cp-demangle.h b/libiberty/cp-demangle.h index 6fce025..197883e 100644 --- a/libiberty/cp-demangle.h +++ b/libiberty/cp-demangle.h @@ -135,12 +135,37 @@ struct d_info - call d_check_char(di, '\0') Everything else is safe. */ #define d_peek_char(di) (*((di)->n)) -#define d_peek_next_char(di) ((di)->n[1]) -#define d_advance(di, i) ((di)->n += (i)) +#ifndef CHECK_DEMANGLER +# define d_peek_next_char(di) ((di)->n[1]) +# define d_advance(di, i) ((di)->n += (i)) +#endif #define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0) #define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++)) #define d_str(di) ((di)->n) +#ifdef CHECK_DEMANGLER +static inline char +d_peek_next_char (const struct d_info *di) +{ + if (!di->n[0]) + abort (); + return di->n[1]; +} + +static inline void +d_advance (struct d_info *di, int i) +{ + if (i < 0) + abort (); + while (i--) + { + if (!di->n[0]) + abort (); + di->n++; + } +} +#endif + /* Functions and arrays in cp-demangle.c which are referenced by functions in cp-demint.c. */ #ifdef IN_GLIBCPP_V3 |