PR demangler/80513 check for overflows and invalid characters in thunks
authorJonathan Wakely <jwakely@redhat.com>
Thu, 27 Apr 2017 09:44:28 +0000 (10:44 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 27 Apr 2017 09:44:28 +0000 (10:44 +0100)
PR demangler/80513
* cp-demangle.c (d_number): Check for overflow.
* cplus-dem.c (consume_count): Fix overflow check.
(gnu_special): Check for underscore after thunk delta.
* testsuite/demangle-expected: Add tests for overflows and invalid
characters in thunks.

From-SVN: r247300

libiberty/ChangeLog
libiberty/cp-demangle.c
libiberty/cplus-dem.c
libiberty/testsuite/demangle-expected

index 34e585e..1e7a6c6 100644 (file)
@@ -1,3 +1,12 @@
+2017-04-27  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR demangler/80513
+       * cp-demangle.c (d_number): Check for overflow.
+       * cplus-dem.c (consume_count): Fix overflow check.
+       (gnu_special): Check for underscore after thunk delta.
+       * testsuite/demangle-expected: Add tests for overflows and invalid
+       characters in thunks.
+
 2017-04-21  Mark Wielaard  <mark@klomp.org>
 
        * cp-demangle.c (MAX_RECURSION_COUNT): New constant.
index e1db900..7b8d0b4 100644 (file)
@@ -1692,6 +1692,8 @@ d_number (struct d_info *di)
            ret = - ret;
          return ret;
        }
+      if (ret > ((INT_MAX - (peek - '0')) / 10))
+        return -1;
       ret = ret * 10 + peek - '0';
       d_advance (di, 1);
       peek = d_peek_char (di);
index a990e07..81c17a3 100644 (file)
@@ -520,21 +520,17 @@ consume_count (const char **type)
 
   while (ISDIGIT ((unsigned char)**type))
     {
-      count *= 10;
-
-      /* Check for overflow.
-        We assume that count is represented using two's-complement;
-        no power of two is divisible by ten, so if an overflow occurs
-        when multiplying by ten, the result will not be a multiple of
-        ten.  */
-      if ((count % 10) != 0)
+      const int digit = **type - '0';
+      /* Check for overflow.  */
+      if (count > ((INT_MAX - digit) / 10))
        {
          while (ISDIGIT ((unsigned char) **type))
            (*type)++;
          return -1;
        }
 
-      count += **type - '0';
+      count *= 10;
+      count += digit;
       (*type)++;
     }
 
@@ -3173,6 +3169,8 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp)
       delta = consume_count (mangled);
       if (delta == -1)
        success = 0;
+      else if (**mangled != '_')
+        success = 0;
       else
        {
          char *method = internal_cplus_demangle (work, ++*mangled);
index 45c5722..f2a12b9 100644 (file)
@@ -4720,3 +4720,18 @@ _ZdvMMMMMMMMMMMMMrrrrA_DTdvfp_fp_Eededilfdfdfdfd
 
 _Z1MA_aMMMMA_MMA_MMMMMMMMSt1MS_o11T0000000000t2M0oooozoooo
 _Z1MA_aMMMMA_MMA_MMMMMMMMSt1MS_o11T0000000000t2M0oooozoooo
+
+#
+# demangler/80513 Test for overflow in d_number
+_Z4294967297x
+_Z4294967297x
+
+#
+# demangler/80513 Test for bogus characters after __thunk_
+__thunk_16a_$_1x
+__thunk_16a_$_1x
+
+#
+# demangler/80513 Test for overflow in consume_count
+__thunk_4294967297__$_1x
+__thunk_4294967297__$_1x