__cxa_demangle: ensure that we have a mangled symbol
authorSaleem Abdulrasool <compnerd@compnerd.org>
Mon, 14 Nov 2016 01:55:54 +0000 (01:55 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Mon, 14 Nov 2016 01:55:54 +0000 (01:55 +0000)
Ensure that we have a mangled symbol before attempting to demangle it.  We would
previously treat any input as a mangled symbol rather than checking that the
symbol has the initial C++ Itanium v3 mangling prefix of `_Z`.  This changes the
behaviour from the previous case which would undecorate `f` to `float` rather
than nullptr as it should.

Unfortunately, we do not have any negative testing for the demangler.

llvm-svn: 286788

libcxxabi/src/cxa_demangle.cpp

index 25aa741..8b9dfc9 100644 (file)
@@ -4978,6 +4978,15 @@ __cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status) {
             *status = invalid_args;
         return nullptr;
     }
+
+    size_t len = std::strlen(mangled_name);
+    if (len < 2 || mangled_name[0] != '_' || mangled_name[1] != 'Z')
+    {
+        if (status)
+            *status = invalid_mangled_name;
+        return nullptr;
+    }
+
     size_t internal_size = buf != nullptr ? *n : 0;
     arena<bs> a;
     Db db(a);
@@ -4990,7 +4999,6 @@ __cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status) {
     db.fix_forward_references = false;
     db.try_to_parse_template_args = true;
     int internal_status = success;
-    size_t len = std::strlen(mangled_name);
     demangle(mangled_name, mangled_name + len, db,
              internal_status);
     if (internal_status == success && db.fix_forward_references &&