aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/intrinsics/link.c
diff options
context:
space:
mode:
authorJanne Blomqvist <jb@gcc.gnu.org>2014-11-13 14:05:01 +0200
committerJanne Blomqvist <jb@gcc.gnu.org>2014-11-13 14:05:01 +0200
commit581d232670be67eb51d3839c43f1113507a89185 (patch)
treec1593d21b75ed82f1d44f238217eb2c1724e03ac /libgfortran/intrinsics/link.c
parent95cc11e1634c8faa09ab161564a13c1ae9ec1794 (diff)
downloadgcc-581d232670be67eb51d3839c43f1113507a89185.zip
gcc-581d232670be67eb51d3839c43f1113507a89185.tar.gz
gcc-581d232670be67eb51d3839c43f1113507a89185.tar.bz2
PR 60324 Unbounded stack allocations in libgfortran.
2014-11-13 Janne Blomqvist <jb@gcc.gnu.org> PR libfortran/60324 * configure: Regenerated. * configure.ac (AM_CFLAGS): Add Werror=vla. * libgfortran.h (gfc_alloca): Remove macro. (fc_strdup_notrim): New prototype. * intrinsics/access.c (access_func): Use fc_strdup rather than stack allocation. * intrinsics/chdir.c (chdir_i4_sub): Likewise. (chdir_i8_sub): Likewise. * intrinsics/chmod.c (chmod_internal): New function, move logic here. (chmod_func): Call chmod_internal. * intrinsics/env.c (getenv): Use fc_strdup rather than stack allocation. (get_environment_variable_i4): Likewise. * intrinsics/execute_command_line.c (execute_command_line): Likewise. * intrinsics/hostnm.c (hostnm_0): New function, use static buffer rather than VLA. (hostnm_i4_sub): Call hostnm_0. (hostnm_i8_sub): Likewise. (hostnm): Likewise. * intrinsics/link.c (link_internal): New function, use fc_strdup rather than stack allocation. (link_i4_sub): Call link_internal. (link_i8_sub): Likewise. (link_i4): Likewise. (link_i8): Likewise. * intrinsics/perror.c (perror_sub): Use fc_strdup rather than stack allocation. * intrinsics/random.c (random_seed_i4): Use static buffer rather than VLA, use _Static_assert to make sure it's big enough. * intrinsics/rename.c (rename_internal): New function, use fc_strdup rather than stack allocation. (rename_i4_sub): Call rename_internal. (rename_i8_sub): Likewise. (rename_i4): Likewise. (rename_i8): Likewise. * intrinsics/stat.c (stat_i4_sub_0): Use fc_strdup rather than stack allocation. (stat_i8_sub_0): Likewise. * intrinsics/symlink.c (symlnk_internal): New function, use fc_strdup rather than stack allocation. (symlnk_i4_sub): Call symlnk_internal. (symlnk_i8_sub): Likewise. (symlnk_i4): Likewise. (symlnk_i8): Likewise. * intrinsics/system.c (system_sub): Use fc_strdup rather than stack allocation. * intrinsics/unlink.c (unlink_i4_sub): Likewise. * io/file_pos.c (READ_CHUNK): Make it a macro rather than variable. * io/list_read.c (nml_get_obj_data): Use fixed stack buffer, fall back to xmalloc/free for large sizes. * io/read.c (read_f): Likewise. * io/transfer.c (MAX_READ): Make it a macro rather than variable. (WRITE_CHUNK): Likewise. * io/write_float.def (write_float): Use fixed stack buffer, fall back to xmalloc/free for large sizes. * runtime/string.c (fc_strdup_notrim): New function. From-SVN: r217480
Diffstat (limited to 'libgfortran/intrinsics/link.c')
-rw-r--r--libgfortran/intrinsics/link.c75
1 files changed, 28 insertions, 47 deletions
diff --git a/libgfortran/intrinsics/link.c b/libgfortran/intrinsics/link.c
index 2018c62..c6084a1 100644
--- a/libgfortran/intrinsics/link.c
+++ b/libgfortran/intrinsics/link.c
@@ -2,7 +2,7 @@
Copyright (C) 2005-2014 Free Software Foundation, Inc.
Contributed by François-Xavier Coudert <coudert@clipper.ens.fr>
-This file is part of the GNU Fortran 95 runtime library (libgfortran).
+This file is part of the GNU Fortran runtime library (libgfortran).
Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
@@ -37,36 +37,39 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
INTEGER, INTENT(OUT), OPTIONAL :: STATUS */
#ifdef HAVE_LINK
-extern void link_i4_sub (char *, char *, GFC_INTEGER_4 *, gfc_charlen_type,
- gfc_charlen_type);
-iexport_proto(link_i4_sub);
-void
-link_i4_sub (char *path1, char *path2, GFC_INTEGER_4 *status,
- gfc_charlen_type path1_len, gfc_charlen_type path2_len)
+static int
+link_internal (char *path1, char *path2, gfc_charlen_type path1_len,
+ gfc_charlen_type path2_len)
{
int val;
char *str1, *str2;
- /* Trim trailing spaces from paths. */
- while (path1_len > 0 && path1[path1_len - 1] == ' ')
- path1_len--;
- while (path2_len > 0 && path2[path2_len - 1] == ' ')
- path2_len--;
-
/* Make a null terminated copy of the strings. */
- str1 = gfc_alloca (path1_len + 1);
- memcpy (str1, path1, path1_len);
- str1[path1_len] = '\0';
-
- str2 = gfc_alloca (path2_len + 1);
- memcpy (str2, path2, path2_len);
- str2[path2_len] = '\0';
+ str1 = fc_strdup (path1, path1_len);
+ str2 = fc_strdup (path2, path2_len);
val = link (str1, str2);
+ free (str1);
+ free (str2);
+
+ return ((val == 0) ? 0 : errno);
+}
+
+
+extern void link_i4_sub (char *, char *, GFC_INTEGER_4 *, gfc_charlen_type,
+ gfc_charlen_type);
+iexport_proto(link_i4_sub);
+
+void
+link_i4_sub (char *path1, char *path2, GFC_INTEGER_4 *status,
+ gfc_charlen_type path1_len, gfc_charlen_type path2_len)
+{
+ int val = link_internal (path1, path2, path1_len, path2_len);
+
if (status != NULL)
- *status = (val == 0) ? 0 : errno;
+ *status = val;
}
iexport(link_i4_sub);
@@ -78,28 +81,10 @@ void
link_i8_sub (char *path1, char *path2, GFC_INTEGER_8 *status,
gfc_charlen_type path1_len, gfc_charlen_type path2_len)
{
- int val;
- char *str1, *str2;
-
- /* Trim trailing spaces from paths. */
- while (path1_len > 0 && path1[path1_len - 1] == ' ')
- path1_len--;
- while (path2_len > 0 && path2[path2_len - 1] == ' ')
- path2_len--;
-
- /* Make a null terminated copy of the strings. */
- str1 = gfc_alloca (path1_len + 1);
- memcpy (str1, path1, path1_len);
- str1[path1_len] = '\0';
-
- str2 = gfc_alloca (path2_len + 1);
- memcpy (str2, path2, path2_len);
- str2[path2_len] = '\0';
-
- val = link (str1, str2);
+ int val = link_internal (path1, path2, path1_len, path2_len);
if (status != NULL)
- *status = (val == 0) ? 0 : errno;
+ *status = val;
}
iexport(link_i8_sub);
@@ -111,9 +96,7 @@ GFC_INTEGER_4
link_i4 (char *path1, char *path2, gfc_charlen_type path1_len,
gfc_charlen_type path2_len)
{
- GFC_INTEGER_4 val;
- link_i4_sub (path1, path2, &val, path1_len, path2_len);
- return val;
+ return link_internal (path1, path2, path1_len, path2_len);
}
extern GFC_INTEGER_8 link_i8 (char *, char *, gfc_charlen_type,
@@ -124,8 +107,6 @@ GFC_INTEGER_8
link_i8 (char *path1, char *path2, gfc_charlen_type path1_len,
gfc_charlen_type path2_len)
{
- GFC_INTEGER_8 val;
- link_i8_sub (path1, path2, &val, path1_len, path2_len);
- return val;
+ return link_internal (path1, path2, path1_len, path2_len);
}
#endif