Sync libiberty with upstream GCC.
authorIain Buclaw <ibuclaw@gdcproject.org>
Sun, 25 Jun 2017 09:39:05 +0000 (11:39 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Sun, 25 Jun 2017 09:39:05 +0000 (11:39 +0200)
libiberty/ChangeLog:

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.

* cp-demangle.c (MAX_RECURSION_COUNT): New constant.
(struct d_print_info): Add recursion field.
(d_print_init): Initialize recursion.
(d_print_comp): Check and update d_print_info recursion depth.

* cp-demangle.c (d_substitution): Return NULL if d_add_substitution
fails.

* cp-demangle.h (struct d_info): Remove did_subs field.
* cp-demangle.c (struct d_info_checkpoint): Likewise.
(d_template_param): Don't update did_subs.
(d_substitution): Likewise.
(d_checkpoint): Don't assign did_subs.
(d_backtrack): Likewise.
(cplus_demangle_init_info): Don't initialize did_subs.

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

index 4b19fef64f9c62ba7c158008d877e9a8beb849bd..84be7272a259dff2ecab52e1f1c5fd8c7baa9d70 100644 (file)
@@ -9,6 +9,37 @@
        * waitpid.c (wait) [__MINGW32__]: Define as a macro
        that calls _cwait, so that this function works on MinGW.
 
+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.
+       (struct d_print_info): Add recursion field.
+       (d_print_init): Initialize recursion.
+       (d_print_comp): Check and update d_print_info recursion depth.
+
+2017-04-21  Mark Wielaard  <mark@klomp.org>
+
+       * cp-demangle.c (d_substitution): Return NULL if d_add_substitution
+       fails.
+
+2017-04-21  Mark Wielaard  <mark@klomp.org>
+
+       * cp-demangle.h (struct d_info): Remove did_subs field.
+       * cp-demangle.c (struct d_info_checkpoint): Likewise.
+       (d_template_param): Don't update did_subs.
+       (d_substitution): Likewise.
+       (d_checkpoint): Don't assign did_subs.
+       (d_backtrack): Likewise.
+       (cplus_demangle_init_info): Don't initialize did_subs.
+
 2017-03-27  Pedro Alves  <palves@redhat.com>
 
        * cp-demint.c (cplus_demangle_fill_component): Handle
index 04832ff6830ab341c63480974dea848ef4c65f4f..7b8d0b4cbaa699544f11e5cc78f081053e4c9dc8 100644 (file)
@@ -316,10 +316,12 @@ struct d_info_checkpoint
   const char *n;
   int next_comp;
   int next_sub;
-  int did_subs;
   int expansion;
 };
 
+/* Maximum number of times d_print_comp may be called recursively.  */
+#define MAX_RECURSION_COUNT 1024
+
 enum { D_PRINT_BUFFER_LENGTH = 256 };
 struct d_print_info
 {
@@ -342,6 +344,9 @@ struct d_print_info
   struct d_print_mod *modifiers;
   /* Set to 1 if we saw a demangling error.  */
   int demangle_failure;
+  /* Number of times d_print_comp was recursively called.  Should not
+     be bigger than MAX_RECURSION_COUNT.  */
+  int recursion;
   /* Non-zero if we're printing a lambda argument.  A template
      parameter reference actually means 'auto'.  */
   int is_lambda_arg;
@@ -1687,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);
@@ -3075,8 +3082,6 @@ d_template_param (struct d_info *di)
   if (param < 0)
     return NULL;
 
-  ++di->did_subs;
-
   return d_make_template_param (di, param);
 }
 
@@ -3846,8 +3851,6 @@ d_substitution (struct d_info *di, int prefix)
       if (id >= (unsigned int) di->next_sub)
        return NULL;
 
-      ++di->did_subs;
-
       return di->subs[id];
     }
   else
@@ -3896,7 +3899,8 @@ d_substitution (struct d_info *di, int prefix)
                  /* If there are ABI tags on the abbreviation, it becomes
                     a substitution candidate.  */
                  dc = d_abi_tags (di, dc);
-                 d_add_substitution (di, dc);
+                 if (! d_add_substitution (di, dc))
+                   return NULL;
                }
              return dc;
            }
@@ -3912,7 +3916,6 @@ d_checkpoint (struct d_info *di, struct d_info_checkpoint *checkpoint)
   checkpoint->n = di->n;
   checkpoint->next_comp = di->next_comp;
   checkpoint->next_sub = di->next_sub;
-  checkpoint->did_subs = di->did_subs;
   checkpoint->expansion = di->expansion;
 }
 
@@ -3922,7 +3925,6 @@ d_backtrack (struct d_info *di, struct d_info_checkpoint *checkpoint)
   di->n = checkpoint->n;
   di->next_comp = checkpoint->next_comp;
   di->next_sub = checkpoint->next_sub;
-  di->did_subs = checkpoint->did_subs;
   di->expansion = checkpoint->expansion;
 }
 
@@ -4157,6 +4159,7 @@ d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
   dpi->opaque = opaque;
 
   dpi->demangle_failure = 0;
+  dpi->recursion = 0;
   dpi->is_lambda_arg = 0;
 
   dpi->component_stack = NULL;
@@ -5691,13 +5694,14 @@ d_print_comp (struct d_print_info *dpi, int options,
              struct demangle_component *dc)
 {
   struct d_component_stack self;
-  if (dc == NULL || dc->d_printing > 1)
+  if (dc == NULL || dc->d_printing > 1 || dpi->recursion > MAX_RECURSION_COUNT)
     {
       d_print_error (dpi);
       return;
     }
-  else
-    dc->d_printing++;
+
+  dc->d_printing++;
+  dpi->recursion++;
 
   self.dc = dc;
   self.parent = dpi->component_stack;
@@ -5707,6 +5711,7 @@ d_print_comp (struct d_print_info *dpi, int options,
 
   dpi->component_stack = self.parent;
   dc->d_printing--;
+  dpi->recursion--;
 }
 
 /* Print a Java dentifier.  For Java we try to handle encoded extended
@@ -6159,7 +6164,6 @@ cplus_demangle_init_info (const char *mangled, int options, size_t len,
      chars in the mangled string.  */
   di->num_subs = len;
   di->next_sub = 0;
-  di->did_subs = 0;
 
   di->last_name = NULL;
 
index a2657755f11d5359794857eb43e61bbd1656ae49..d4a4ab604d84bd38d7d7b6724a34a2c3732351e5 100644 (file)
@@ -111,10 +111,6 @@ struct d_info
   int next_sub;
   /* The number of available entries in the subs array.  */
   int num_subs;
-  /* The number of substitutions which we actually made from the subs
-     array, plus the number of template parameter references we
-     saw.  */
-  int did_subs;
   /* The last name we saw, for constructors and destructors.  */
   struct demangle_component *last_name;
   /* A running total of the length of large expansions from the
index a990e072975e2b7137817ec8b316201954c34a6e..81c17a3207d8d69e7d3c34e5f7f53fbb54876ddc 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 45c572268b3be4b6dcc7b630659ddd86e1a0f313..f2a12b9a7d1fd6a2678bc700ff5805d3b588edc4 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