Fix stack overflow crash in getcwd intrinsic.
2014-05-12 Janne Blomqvist <jb@gcc.gnu.org> PR libfortran/61035 * intrinsics/getcwd.c (getcwd_i4_sub): Avoid potentially large stack allocation, avoid extra copying in the common case. From-SVN: r210335
This commit is contained in:
parent
f7b6856fa4
commit
16e60fff0b
@ -1,3 +1,9 @@
|
||||
2014-05-12 Janne Blomqvist <jb@gcc.gnu.org>
|
||||
|
||||
PR libfortran/61035
|
||||
* intrinsics/getcwd.c (getcwd_i4_sub): Avoid potentially large
|
||||
stack allocation, avoid extra copying in the common case.
|
||||
|
||||
2014-05-12 Janne Blomqvist <jb@gcc.gnu.org>
|
||||
|
||||
* configure.ac (AM_CFLAGS): Use -std=gnu11.
|
||||
|
@ -2,7 +2,7 @@
|
||||
Copyright (C) 2004-2014 Free Software Foundation, Inc.
|
||||
Contributed by Steven G. Kargl <kargls@comcast.net>.
|
||||
|
||||
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
|
||||
@ -40,20 +40,35 @@ iexport_proto(getcwd_i4_sub);
|
||||
void
|
||||
getcwd_i4_sub (char *cwd, GFC_INTEGER_4 *status, gfc_charlen_type cwd_len)
|
||||
{
|
||||
char str[cwd_len + 1];
|
||||
GFC_INTEGER_4 stat;
|
||||
int err;
|
||||
|
||||
memset(cwd, ' ', (size_t) cwd_len);
|
||||
|
||||
if (!getcwd (str, (size_t) cwd_len + 1))
|
||||
stat = errno;
|
||||
else
|
||||
if (getcwd (cwd, cwd_len))
|
||||
{
|
||||
stat = 0;
|
||||
memcpy (cwd, str, strlen (str));
|
||||
size_t len = strlen (cwd);
|
||||
memset (cwd + len, ' ', cwd_len - len);
|
||||
err = 0;
|
||||
}
|
||||
else if (errno == ERANGE)
|
||||
{
|
||||
/* There is a possibility that the previous attempt failed due
|
||||
to not enough space for the terminating null byte. Try again
|
||||
with a buffer one char longer. */
|
||||
char *buf = xmalloc (cwd_len + 1);
|
||||
if (getcwd (buf, cwd_len + 1))
|
||||
{
|
||||
memcpy (cwd, buf, cwd_len);
|
||||
err = 0;
|
||||
}
|
||||
else
|
||||
err = errno;
|
||||
free (buf);
|
||||
}
|
||||
else
|
||||
err = errno;
|
||||
if (err)
|
||||
memset (cwd, ' ', cwd_len);
|
||||
if (status != NULL)
|
||||
*status = stat;
|
||||
*status = err;
|
||||
}
|
||||
iexport(getcwd_i4_sub);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user