* 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
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
{
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;
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);
if (param < 0)
return NULL;
- ++di->did_subs;
-
return d_make_template_param (di, param);
}
if (id >= (unsigned int) di->next_sub)
return NULL;
- ++di->did_subs;
-
return di->subs[id];
}
else
/* 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;
}
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;
}
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;
}
dpi->opaque = opaque;
dpi->demangle_failure = 0;
+ dpi->recursion = 0;
dpi->is_lambda_arg = 0;
dpi->component_stack = NULL;
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;
dpi->component_stack = self.parent;
dc->d_printing--;
+ dpi->recursion--;
}
/* Print a Java dentifier. For Java we try to handle encoded extended
chars in the mangled string. */
di->num_subs = len;
di->next_sub = 0;
- di->did_subs = 0;
di->last_name = NULL;
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
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)++;
}
delta = consume_count (mangled);
if (delta == -1)
success = 0;
+ else if (**mangled != '_')
+ success = 0;
else
{
char *method = internal_cplus_demangle (work, ++*mangled);
_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