aboutsummaryrefslogtreecommitdiff
path: root/libiberty/cp-demangle.h
diff options
context:
space:
mode:
authorMikhail Maltsev <maltsevm@gmail.com>2015-11-28 16:39:29 +0000
committerPedro Alves <palves@redhat.com>2015-11-28 16:39:29 +0000
commitd81bf7ddc2ad497037fbfde5d15cfa8d81a9e959 (patch)
tree926b0c2c076cb449874747186878d3da93564104 /libiberty/cp-demangle.h
parent6a8796db3691b9a53dc5475eaec5388bc1af115d (diff)
downloadfsf-binutils-gdb-d81bf7ddc2ad497037fbfde5d15cfa8d81a9e959.zip
fsf-binutils-gdb-d81bf7ddc2ad497037fbfde5d15cfa8d81a9e959.tar.gz
fsf-binutils-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.h29
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