aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald Anlauf <anlauf@gmx.de>2020-06-25 20:32:13 +0200
committerHarald Anlauf <anlauf@gmx.de>2020-06-25 20:32:13 +0200
commit35a335a159216548fc77263ac5df71ff29d3f448 (patch)
tree70460bb97d27ffe4ab264f6024bb0e4ff402c6c1
parent20f466326ca08d7dac58eb34ffdd6bf80428c5ab (diff)
downloadgcc-35a335a159216548fc77263ac5df71ff29d3f448.zip
gcc-35a335a159216548fc77263ac5df71ff29d3f448.tar.gz
gcc-35a335a159216548fc77263ac5df71ff29d3f448.tar.bz2
PR fortran/95826 - Buffer overflows with PDTs and long symbols
With PDTs (parameterized derived types), name mangling results in variably long internal symbols. Use a dynamic buffer instead of a fixed-size one. gcc/fortran/ PR fortran/95826 * decl.c (gfc_match_decl_type_spec): Replace a fixed size buffer by a pointer and reallocate if necessary.
-rw-r--r--gcc/fortran/decl.c8
-rw-r--r--gcc/testsuite/gfortran.dg/pr95826.f9020
2 files changed, 25 insertions, 3 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index c27cfac..ac1f63f 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -4095,7 +4095,7 @@ match
gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
{
/* Provide sufficient space to hold "pdtsymbol". */
- char name[GFC_MAX_SYMBOL_LEN + 1 + 3];
+ char *name = XALLOCAVEC (char, GFC_MAX_SYMBOL_LEN + 1);
gfc_symbol *sym, *dt_sym;
match m;
char c;
@@ -4286,8 +4286,10 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
gcc_assert (!sym->attr.pdt_template && sym->attr.pdt_type);
ts->u.derived = sym;
const char* lower = gfc_dt_lower_string (sym->name);
- size_t len = strnlen (lower, sizeof (name));
- gcc_assert (len < sizeof (name));
+ size_t len = strlen (lower);
+ /* Reallocate with sufficient size. */
+ if (len > GFC_MAX_SYMBOL_LEN)
+ name = XALLOCAVEC (char, len + 1);
memcpy (name, lower, len);
name[len] = '\0';
}
diff --git a/gcc/testsuite/gfortran.dg/pr95826.f90 b/gcc/testsuite/gfortran.dg/pr95826.f90
new file mode 100644
index 0000000..8de04e6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr95826.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-fsecond-underscore" }
+! PR fortran/95826 - ICE in gfc_match_decl_type_spec, at fortran/decl.c:4290
+
+program p
+ type t2345678901234567890123456789012345678901234567890123456789_123 &
+ (a2345678901234567890123456789012345678901234567890123456789_123, &
+ b2345678901234567890123456789012345678901234567890123456789_123)
+ integer, kind :: &
+ a2345678901234567890123456789012345678901234567890123456789_123
+ integer, len :: &
+ b2345678901234567890123456789012345678901234567890123456789_123
+ end type
+ integer, parameter :: &
+ n2345678901234567890123456789012345678901234567890123456789_123 = 16
+ type(t2345678901234567890123456789012345678901234567890123456789_123 &
+ (n2345678901234567890123456789012345678901234567890123456789_123,:)), &
+ allocatable :: &
+ x2345678901234567890123456789012345678901234567890123456789_123
+end