Commit 78c4b06a by Harald Anlauf

PR fortran/95090 - ICE: identifier overflow

The initial fix for this PR uncovered several latent issues with further
too small string buffers which showed up only when testing on i686.
Provide sufficiently large temporaries.

2020-05-29  Harald Anlauf  <anlauf@gmx.de>

gcc/fortran/
	PR fortran/95090
	* class.c (get_unique_type_string): Enlarge temporary for
	name-mangling.  Use strncpy to prevent buffer overrun.
	(get_unique_hashed_string): Enlarge temporary.
	(gfc_hash_value): Enlarge temporary for name-mangling.

(cherry picked from commit 7deca8c0b3765787627b11387b56b97b01a8bf33)
parent 2ee8913b
...@@ -479,11 +479,12 @@ gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr) ...@@ -479,11 +479,12 @@ gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
static void static void
get_unique_type_string (char *string, gfc_symbol *derived) get_unique_type_string (char *string, gfc_symbol *derived)
{ {
char dt_name[GFC_MAX_SYMBOL_LEN+1]; /* Provide sufficient space to hold "Pdtsymbol". */
char dt_name[GFC_MAX_SYMBOL_LEN+4];
if (derived->attr.unlimited_polymorphic) if (derived->attr.unlimited_polymorphic)
strcpy (dt_name, "STAR"); strcpy (dt_name, "STAR");
else else
strcpy (dt_name, gfc_dt_upper_string (derived->name)); strncpy (dt_name, gfc_dt_upper_string (derived->name), sizeof (dt_name));
if (derived->attr.unlimited_polymorphic) if (derived->attr.unlimited_polymorphic)
sprintf (string, "_%s", dt_name); sprintf (string, "_%s", dt_name);
else if (derived->module) else if (derived->module)
...@@ -501,7 +502,8 @@ get_unique_type_string (char *string, gfc_symbol *derived) ...@@ -501,7 +502,8 @@ get_unique_type_string (char *string, gfc_symbol *derived)
static void static void
get_unique_hashed_string (char *string, gfc_symbol *derived) get_unique_hashed_string (char *string, gfc_symbol *derived)
{ {
char tmp[2*GFC_MAX_SYMBOL_LEN+2]; /* Provide sufficient space to hold "symbol_Pdtsymbol". */
char tmp[2*GFC_MAX_SYMBOL_LEN+5];
get_unique_type_string (&tmp[0], derived); get_unique_type_string (&tmp[0], derived);
/* If string is too long, use hash value in hex representation (allow for /* If string is too long, use hash value in hex representation (allow for
extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab). extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
...@@ -523,7 +525,8 @@ unsigned int ...@@ -523,7 +525,8 @@ unsigned int
gfc_hash_value (gfc_symbol *sym) gfc_hash_value (gfc_symbol *sym)
{ {
unsigned int hash = 0; unsigned int hash = 0;
char c[2*(GFC_MAX_SYMBOL_LEN+1)]; /* Provide sufficient space to hold "symbol_Pdtsymbol". */
char c[2*GFC_MAX_SYMBOL_LEN+5];
int i, len; int i, len;
get_unique_type_string (&c[0], sym); get_unique_type_string (&c[0], sym);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment