2017-03-08 Mark Wielaard PR demangler/70909 PR demangler/67264 * include/demangle.h: Add d_printing to struct demangle_component and pass struct demangle_component as non const. libiberty/ 2017-03-08 Mark Wielaard PR demangler/70909 PR demangler/67264 * cp-demangle.c: Fix endless recursion. Pass struct demangle_component as non const. (d_make_empty): Initialize variable. (d_print_comp_inner): Limit recursion. (d_print_comp): Decrement variable. * cp-demint.c (cplus_demangle_fill_component): Initialize variable. (cplus_demangle_fill_builtin_type): Likewise. (cplus_demangle_fill_operator): Likewise. * testsuite/demangle-expected: Add tests. Index: b/include/demangle.h =================================================================== --- a/include/demangle.h +++ b/include/demangle.h @@ -494,6 +494,11 @@ struct demangle_component /* The type of this component. */ enum demangle_component_type type; + /* Guard against recursive component printing. + Initialize to zero. Private to d_print_comp. + All other fields are final after initialization. */ + int d_printing; + union { /* For DEMANGLE_COMPONENT_NAME. */ @@ -688,7 +693,7 @@ cplus_demangle_v3_components (const char extern char * cplus_demangle_print (int options, - const struct demangle_component *tree, + struct demangle_component *tree, int estimated_length, size_t *p_allocated_size); @@ -708,7 +713,7 @@ cplus_demangle_print (int options, extern int cplus_demangle_print_callback (int options, - const struct demangle_component *tree, + struct demangle_component *tree, demangle_callbackref callback, void *opaque); #ifdef __cplusplus Index: b/libiberty/testsuite/demangle-expected =================================================================== --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -4686,3 +4686,34 @@ void g(S<&A::operator+>) _Z1gI1AEv1SIXadsrT_plEE void g(S<&A::operator+>) + +# +# Test recursion PR67264 +_Z1KIStcvT_E +_Z1KIStcvT_E + +_ZcvT_IIS0_EE +_ZcvT_IIS0_EE + +_ZcvT_IZcvT_E1fE +_ZcvT_IZcvT_E1fE + +_Z1gINcvT_EE +_Z1gINcvT_EE + +_ZcvT_ILZcvDTT_EEE +_ZcvT_ILZcvDTT_EEE + +_Z1gIJOOT_EEOT_c +_Z1gIJOOT_EEOT_c + +_Z1KMMMMMMMMMMMMMMMA_xooooooooooooooo +_Z1KMMMMMMMMMMMMMMMA_xooooooooooooooo + +_ZdvMMMMMMMMMMMMMrrrrA_DTdvfp_fp_Eededilfdfdfdfd +_ZdvMMMMMMMMMMMMMrrrrA_DTdvfp_fp_Eededilfdfdfdfd +# +# Test for Infinite Recursion PR70909 + +_Z1MA_aMMMMA_MMA_MMMMMMMMSt1MS_o11T0000000000t2M0oooozoooo +_Z1MA_aMMMMA_MMA_MMMMMMMMSt1MS_o11T0000000000t2M0oooozoooo Index: b/libiberty/cp-demint.c =================================================================== --- a/libiberty/cp-demint.c +++ b/libiberty/cp-demint.c @@ -123,6 +123,7 @@ cplus_demangle_fill_component (struct de p->type = type; p->u.s_binary.left = left; p->u.s_binary.right = right; + p->d_printing = 0; return 1; } @@ -146,6 +147,7 @@ cplus_demangle_fill_builtin_type (struct { p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE; p->u.s_builtin.type = &cplus_demangle_builtin_types[i]; + p->d_printing = 0; return 1; } } @@ -172,6 +174,7 @@ cplus_demangle_fill_operator (struct dem { p->type = DEMANGLE_COMPONENT_OPERATOR; p->u.s_operator.op = &cplus_demangle_operators[i]; + p->d_printing = 0; return 1; } } Index: b/libiberty/cp-demangle.c =================================================================== --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -173,10 +173,10 @@ static struct demangle_component *d_mang static struct demangle_component *d_type (struct d_info *); #define cplus_demangle_print d_print -static char *d_print (int, const struct demangle_component *, int, size_t *); +static char *d_print (int, struct demangle_component *, int, size_t *); #define cplus_demangle_print_callback d_print_callback -static int d_print_callback (int, const struct demangle_component *, +static int d_print_callback (int, struct demangle_component *, demangle_callbackref, void *); #define cplus_demangle_init_info d_init_info @@ -265,7 +265,7 @@ struct d_print_mod in which they appeared in the mangled string. */ struct d_print_mod *next; /* The modifier. */ - const struct demangle_component *mod; + struct demangle_component *mod; /* Whether this modifier was printed. */ int printed; /* The list of templates which applies to this modifier. */ @@ -531,7 +531,7 @@ static inline void d_append_string (stru static inline char d_last_char (struct d_print_info *); static void -d_print_comp (struct d_print_info *, int, const struct demangle_component *); +d_print_comp (struct d_print_info *, int, struct demangle_component *); static void d_print_java_identifier (struct d_print_info *, const char *, int); @@ -540,25 +540,25 @@ static void d_print_mod_list (struct d_print_info *, int, struct d_print_mod *, int); static void -d_print_mod (struct d_print_info *, int, const struct demangle_component *); +d_print_mod (struct d_print_info *, int, struct demangle_component *); static void d_print_function_type (struct d_print_info *, int, - const struct demangle_component *, + struct demangle_component *, struct d_print_mod *); static void d_print_array_type (struct d_print_info *, int, - const struct demangle_component *, + struct demangle_component *, struct d_print_mod *); static void -d_print_expr_op (struct d_print_info *, int, const struct demangle_component *); +d_print_expr_op (struct d_print_info *, int, struct demangle_component *); static void d_print_cast (struct d_print_info *, int, - const struct demangle_component *); + struct demangle_component *); static void d_print_conversion (struct d_print_info *, int, - const struct demangle_component *); + struct demangle_component *); static int d_demangle_callback (const char *, int, demangle_callbackref, void *); @@ -924,6 +924,7 @@ d_make_empty (struct d_info *di) if (di->next_comp >= di->num_comps) return NULL; p = &di->comps[di->next_comp]; + p->d_printing = 0; ++di->next_comp; return p; } @@ -4246,7 +4247,7 @@ d_last_char (struct d_print_info *dpi) CP_STATIC_IF_GLIBCPP_V3 int cplus_demangle_print_callback (int options, - const struct demangle_component *dc, + struct demangle_component *dc, demangle_callbackref callback, void *opaque) { struct d_print_info dpi; @@ -4289,7 +4290,7 @@ cplus_demangle_print_callback (int optio CP_STATIC_IF_GLIBCPP_V3 char * -cplus_demangle_print (int options, const struct demangle_component *dc, +cplus_demangle_print (int options, struct demangle_component *dc, int estimate, size_t *palc) { struct d_growable_string dgs; @@ -4449,7 +4450,7 @@ d_args_length (struct d_print_info *dpi, static void d_print_subexpr (struct d_print_info *dpi, int options, - const struct demangle_component *dc) + struct demangle_component *dc) { int simple = 0; if (dc->type == DEMANGLE_COMPONENT_NAME @@ -4525,9 +4526,9 @@ d_get_saved_scope (struct d_print_info * static int d_maybe_print_fold_expression (struct d_print_info *dpi, int options, - const struct demangle_component *dc) + struct demangle_component *dc) { - const struct demangle_component *ops, *operator_, *op1, *op2; + struct demangle_component *ops, *operator_, *op1, *op2; int save_idx; const char *fold_code = d_left (dc)->u.s_operator.op->code; @@ -4588,11 +4589,11 @@ d_maybe_print_fold_expression (struct d_ static void d_print_comp_inner (struct d_print_info *dpi, int options, - const struct demangle_component *dc) + struct demangle_component *dc) { /* Magic variable to let reference smashing skip over the next modifier without needing to modify *dc. */ - const struct demangle_component *mod_inner = NULL; + struct demangle_component *mod_inner = NULL; /* Variable used to store the current templates while a previously captured scope is used. */ @@ -4977,7 +4978,7 @@ d_print_comp_inner (struct d_print_info case DEMANGLE_COMPONENT_RVALUE_REFERENCE: { /* Handle reference smashing: & + && = &. */ - const struct demangle_component *sub = d_left (dc); + struct demangle_component *sub = d_left (dc); if (!dpi->is_lambda_arg && sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM) { @@ -5680,9 +5681,16 @@ d_print_comp_inner (struct d_print_info static void d_print_comp (struct d_print_info *dpi, int options, - const struct demangle_component *dc) + struct demangle_component *dc) { struct d_component_stack self; + if (dc == NULL || dc->d_printing > 1) + { + d_print_error (dpi); + return; + } + else + dc->d_printing++; self.dc = dc; self.parent = dpi->component_stack; @@ -5691,6 +5699,7 @@ d_print_comp (struct d_print_info *dpi, d_print_comp_inner (dpi, options, dc); dpi->component_stack = self.parent; + dc->d_printing--; } /* Print a Java dentifier. For Java we try to handle encoded extended @@ -5832,7 +5841,7 @@ d_print_mod_list (struct d_print_info *d static void d_print_mod (struct d_print_info *dpi, int options, - const struct demangle_component *mod) + struct demangle_component *mod) { switch (mod->type) { @@ -5924,7 +5933,7 @@ d_print_mod (struct d_print_info *dpi, i static void d_print_function_type (struct d_print_info *dpi, int options, - const struct demangle_component *dc, + struct demangle_component *dc, struct d_print_mod *mods) { int need_paren; @@ -6002,7 +6011,7 @@ d_print_function_type (struct d_print_in static void d_print_array_type (struct d_print_info *dpi, int options, - const struct demangle_component *dc, + struct demangle_component *dc, struct d_print_mod *mods) { int need_space; @@ -6056,7 +6065,7 @@ d_print_array_type (struct d_print_info static void d_print_expr_op (struct d_print_info *dpi, int options, - const struct demangle_component *dc) + struct demangle_component *dc) { if (dc->type == DEMANGLE_COMPONENT_OPERATOR) d_append_buffer (dpi, dc->u.s_operator.op->name, @@ -6069,7 +6078,7 @@ d_print_expr_op (struct d_print_info *dp static void d_print_cast (struct d_print_info *dpi, int options, - const struct demangle_component *dc) + struct demangle_component *dc) { d_print_comp (dpi, options, d_left (dc)); } @@ -6078,7 +6087,7 @@ d_print_cast (struct d_print_info *dpi, static void d_print_conversion (struct d_print_info *dpi, int options, - const struct demangle_component *dc) + struct demangle_component *dc) { struct d_print_template dpt;