summaryrefslogtreecommitdiff
path: root/libiberty/testsuite
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-21 01:29:27 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-21 01:29:27 +0000
commitb785de4a32d5e0cfc9052d44bbcb8c48dc1b2946 (patch)
tree8bbefa55fbcb69174085aaec3d70bd9faf6d986a /libiberty/testsuite
parent24ce1b68ca76ec84a101dc16918d62ed4e80c66e (diff)
downloadgcc-b785de4a32d5e0cfc9052d44bbcb8c48dc1b2946.tar.gz
* cp-demangle.h: Add comment explaining what to do to avoid
overrunning string. (d_check_char): New. (d_next_char): Don't advance past trailing '\0'. * cp-demangle.c (cplus_demangle_mangled_name): Use d_check_char. (d_nested_name): Likewise. (d_special_name): Likewise. (d_call_offset): Likewise. (d_function_type): Likewise. (d_array_type): Likewise. (d_pointer_to_member_type): Likewise. (d_template_param): Likewise. (d_template_args): Likewise. (d_template_arg): Likewise. (d_expr_primary): Likewise. (d_local_name): Likewise. (d_substitution): Likewise. (d_ctor_dtor_name): Use d_advance rather than d_next_char. * testsuite/test-demangle.c: Include sys/mman.h. (MAP_ANONYMOUS): Define. (protect_end): New. (main): Use protect_end. * testsuite/demangle-expected: Add testcases for overrunning the end of the string. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120097 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libiberty/testsuite')
-rw-r--r--libiberty/testsuite/demangle-expected22
-rw-r--r--libiberty/testsuite/test-demangle.c56
2 files changed, 74 insertions, 4 deletions
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 3f5622f79b7..56d9f899155 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -3816,3 +3816,25 @@ f
SASDASDFASDF_sdfsdf
SASDASDFASDF_sdfsdf
SASDASDFASDF_sdfsdf
+# These are all cases of invalid manglings where the demangler would read
+# past the end of the string.
+# d_name wasn't honouring a NULL from d_substitution
+--format=gnu-v3
+_ZSA
+_ZSA
+# d_expr_primary wasn't honouring NULL from cplus_demangle_mangled_name
+--format=gnu-v3
+_ZN1fIL_
+_ZN1fIL_
+# d_operator_name was taking two characters in a row
+--format=gnu-v3
+_Za
+_Za
+# d_prefix wasn't honouring NULL from d_substitution
+--format=gnu-v3
+_ZNSA
+_ZNSA
+# d_prefix wasn't honouring NULL from d_template_param
+--format=gnu-v3
+_ZNT
+_ZNT
diff --git a/libiberty/testsuite/test-demangle.c b/libiberty/testsuite/test-demangle.c
index 93793996fe0..12b07dd6476 100644
--- a/libiberty/testsuite/test-demangle.c
+++ b/libiberty/testsuite/test-demangle.c
@@ -86,6 +86,50 @@ getline(buf)
buf->alloced = alloc;
}
+/* If we have mmap() and mprotect(), copy the string S just before a
+ protected page, so that if the demangler runs over the end of the
+ string we'll get a fault, and return the address of the new string.
+ If no mmap, or it fails, or it looks too hard, just return S. */
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#if defined(MAP_ANON) && ! defined (MAP_ANONYMOUS)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+static const char *
+protect_end (const char * s)
+{
+#if defined(HAVE_MMAP) && defined (MAP_ANONYMOUS)
+ size_t pagesize = getpagesize();
+ static char * buf;
+ size_t s_len = strlen (s);
+ char * result;
+
+ /* Don't try if S is too long. */
+ if (s_len >= pagesize)
+ return s;
+
+ /* Allocate one page of allocated space followed by an unmapped
+ page. */
+ if (buf == NULL)
+ {
+ buf = mmap (NULL, pagesize * 2, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (! buf)
+ return s;
+ munmap (buf + pagesize, pagesize);
+ }
+
+ result = buf + (pagesize - s_len - 1);
+ memcpy (result, s, s_len + 1);
+ return result;
+#else
+ return s;
+#endif
+}
+
static void
fail (lineno, opts, in, out, exp)
int lineno;
@@ -150,6 +194,8 @@ main(argc, argv)
for (;;)
{
+ const char *inp;
+
getline (&format);
if (feof (stdin))
break;
@@ -157,6 +203,8 @@ main(argc, argv)
getline (&input);
getline (&expect);
+ inp = protect_end (input.data);
+
tests++;
no_params = 0;
@@ -237,14 +285,14 @@ main(argc, argv)
{
enum gnu_v3_ctor_kinds kc;
- kc = is_gnu_v3_mangled_ctor (input.data);
+ kc = is_gnu_v3_mangled_ctor (inp);
sprintf (buf, "%d", (int) kc);
}
else
{
enum gnu_v3_dtor_kinds kd;
- kd = is_gnu_v3_mangled_dtor (input.data);
+ kd = is_gnu_v3_mangled_dtor (inp);
sprintf (buf, "%d", (int) kd);
}
@@ -259,7 +307,7 @@ main(argc, argv)
cplus_demangle_set_style (style);
- result = cplus_demangle (input.data,
+ result = cplus_demangle (inp,
DMGL_PARAMS|DMGL_ANSI|DMGL_TYPES
|(ret_postfix ? DMGL_RET_POSTFIX : 0));
@@ -275,7 +323,7 @@ main(argc, argv)
if (no_params)
{
getline (&expect);
- result = cplus_demangle (input.data, DMGL_ANSI|DMGL_TYPES);
+ result = cplus_demangle (inp, DMGL_ANSI|DMGL_TYPES);
if (result
? strcmp (result, expect.data)