diff mbox

D demangle: Check identifier length before using strncmp

Message ID CABOHX+eVJyS9-p1CYuC7rqz9bZLWPUCEcPdRQpN5MWFo7QaVyw@mail.gmail.com
State New
Headers show

Commit Message

Iain Buclaw May 10, 2015, 1:09 p.m. UTC
Noticed this when I was in the middle of testing out some tightening
up of parsing checks.  Currently when the pointer to the mangled
string has reached the end of the buffer, or no longer satisfies any
constraints in an abrupt fashion, the parsing logic just exits early
in all parsing routines before finally returning success at the top
level.

This will be followed up with a patch to address this shortly, but
until then. This addresses a subtle logic error.

---
libiberty/ChangeLog

2015-05-10 Iain Buclaw  <ibuclaw@gdcproject.org>

    * d-demangle.c (dlang_identifier): Check encoded length of identifier
    to verify strncmp matches entire string.
    * testsuite/d-demangle-expected: Fix wrong test for postblit symbols.
---
diff mbox

Patch

diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c
index bb481c0..0d0f9b0 100644
--- a/libiberty/d-demangle.c
+++ b/libiberty/d-demangle.c
@@ -622,65 +622,82 @@  dlang_identifier (string *decl, const char *mangled)
 	  return NULL;
 	}
 
-      if (strncmp (mangled, "__ctor", i) == 0)
+      switch (i)
 	{
-	  /* Constructor symbol for a class/struct.  */
-	  string_append (decl, "this");
-	  mangled += i;
-	  return mangled;
-	}
-      else if (strncmp (mangled, "__dtor", i) == 0)
-	{
-	  /* Destructor symbol for a class/struct.  */
-	  string_append (decl, "~this");
-	  mangled += i;
-	  return mangled;
-	}
-      else if (strncmp (mangled, "__postblit", i) == 0)
-	{
-	  /* Postblit symbol for a struct.  */
-	  string_append (decl, "this(this)");
-	  mangled += i;
-	  return mangled;
-	}
-      else if (strncmp (mangled, "__initZ", i+1) == 0)
-	{
-	  /* The static initialiser for a given symbol.  */
-	  string_append (decl, "init$");
-	  mangled += i + 1;
-	  return mangled;
-	}
-      else if (strncmp (mangled, "__ClassZ", i+1) == 0)
-	{
-	  /* The classinfo symbol for a given class.  */
-	  string_prepend (decl, "ClassInfo for ");
-	  string_setlength (decl, string_length (decl) - 1);
-	  mangled += i + 1;
-	  return mangled;
-	}
-      else if (strncmp (mangled, "__vtblZ", i+1) == 0)
-	{
-	  /* The vtable symbol for a given class.  */
-	  string_prepend (decl, "vtable for ");
-	  string_setlength (decl, string_length (decl) - 1);
-	  mangled += i + 1;
-	  return mangled;
-	}
-      else if (strncmp (mangled, "__InterfaceZ", i+1) == 0)
-	{
-	  /* The interface symbol for a given class.  */
-	  string_prepend (decl, "Interface for ");
-	  string_setlength (decl, string_length (decl) - 1);
-	  mangled += i + 1;
-	  return mangled;
-	}
-      else if (strncmp (mangled, "__ModuleInfoZ", i+1) == 0)
-	{
-	  /* The ModuleInfo symbol for a given module.  */
-	  string_prepend (decl, "ModuleInfo for ");
-	  string_setlength (decl, string_length (decl) - 1);
-	  mangled += i + 1;
-	  return mangled;
+	case 6:
+	  if (strncmp (mangled, "__ctor", i) == 0)
+	    {
+	      /* Constructor symbol for a class/struct.  */
+	      string_append (decl, "this");
+	      mangled += i;
+	      return mangled;
+	    }
+	  else if (strncmp (mangled, "__dtor", i) == 0)
+	    {
+	      /* Destructor symbol for a class/struct.  */
+	      string_append (decl, "~this");
+	      mangled += i;
+	      return mangled;
+	    }
+	  else if (strncmp (mangled, "__initZ", i+1) == 0)
+	    {
+	      /* The static initialiser for a given symbol.  */
+	      string_append (decl, "init$");
+	      mangled += i;
+	      return mangled;
+	    }
+	  else if (strncmp (mangled, "__vtblZ", i+1) == 0)
+	    {
+	      /* The vtable symbol for a given class.  */
+	      string_prepend (decl, "vtable for ");
+	      string_setlength (decl, string_length (decl) - 1);
+	      mangled += i;
+	      return mangled;
+	    }
+	  break;
+
+	case 7:
+	  if (strncmp (mangled, "__ClassZ", i+1) == 0)
+	    {
+	      /* The classinfo symbol for a given class.  */
+	      string_prepend (decl, "ClassInfo for ");
+	      string_setlength (decl, string_length (decl) - 1);
+	      mangled += i;
+	      return mangled;
+	    }
+	  break;
+
+	case 10:
+	  if (strncmp (mangled, "__postblitMFZ", i+3) == 0)
+	    {
+	      /* Postblit symbol for a struct.  */
+	      string_append (decl, "this(this)");
+	      mangled += i + 3;
+	      return mangled;
+	    }
+	  break;
+
+	case 11:
+	  if (strncmp (mangled, "__InterfaceZ", i+1) == 0)
+	    {
+	      /* The interface symbol for a given class.  */
+	      string_prepend (decl, "Interface for ");
+	      string_setlength (decl, string_length (decl) - 1);
+	      mangled += i;
+	      return mangled;
+	    }
+	  break;
+
+	case 12:
+	  if (strncmp (mangled, "__ModuleInfoZ", i+1) == 0)
+	    {
+	      /* The ModuleInfo symbol for a given module.  */
+	      string_prepend (decl, "ModuleInfo for ");
+	      string_setlength (decl, string_length (decl) - 1);
+	      mangled += i;
+	      return mangled;
+	    }
+	  break;
 	}
 
       string_appendn (decl, mangled, i);
diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected
index 2aeacb8..330a830 100644
--- a/libiberty/testsuite/d-demangle-expected
+++ b/libiberty/testsuite/d-demangle-expected
@@ -502,7 +502,7 @@  _D8demangle4test6__dtorMFZv
 demangle.test.~this()
 #
 --format=dlang
-_D8demangle4test6__postblitMFZv
+_D8demangle4test10__postblitMFZv
 demangle.test.this(this)
 #
 --format=dlang