Commit 0e05c303 by Janne Blomqvist

PR libfortran/62768 Handle filenames with embedded null characters.

testsuite ChangeLog:

2014-09-17  Janne Blomqvist  <jb@gcc.gnu.org>

	PR libfortran/62768
	* gfortran.dg/filename_null.f90: New test.

libgfortran ChangeLog:

2014-09-17  Janne Blomqvist  <jb@gcc.gnu.org>

	PR libfortran/62768
	* io/io.h (gfc_unit): Store C string for the filename.
	* io/close.c (st_close): Use gfc_unit.filename.
	* io/inquire.c (inquire_via_unit): Likewise.
	* io/open.c (new_unit): Likewise.
	(already_open): Likewise, unlink file before freeing filename.
	* io/unit.c (init_units): Likewise.
	(close_unit_1): Likewise.
	(filename_from_unit): Likewise.
	* io/unix.c (compare_file_filename): Likewise.
	(find_file0): Likewise.
	(delete_file): Likewise.

From-SVN: r215307
parent 7425e424
2014-09-17 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/62768
* gfortran.dg/filename_null.f90: New test.
2014-09-16 H.J. Lu <hongjiu.lu@intel.com> 2014-09-16 H.J. Lu <hongjiu.lu@intel.com>
* gcc.dg/pg-override.c: Fix a typo. * gcc.dg/pg-override.c: Fix a typo.
......
! { dg-do run }
! PR 62768
! Filenames with embedded NULL characters are truncated, make sure
! inquire reports the correct truncated name.
program filename_null
implicit none
character(len=15), parameter :: s = "hello" // achar(0) // "world", &
s2 = "hello"
character(len=15) :: r
logical :: l
open(10, file=s)
inquire(unit=10, name=r)
if (r /= s2) call abort()
inquire(file=s2, exist=l)
if (.not. l) call abort()
close(10, status="delete")
end program filename_null
2014-09-17 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/62768
* io/io.h (gfc_unit): Store C string for the filename.
* io/close.c (st_close): Use gfc_unit.filename.
* io/inquire.c (inquire_via_unit): Likewise.
* io/open.c (new_unit): Likewise.
(already_open): Likewise, unlink file before freeing filename.
* io/unit.c (init_units): Likewise.
(close_unit_1): Likewise.
(filename_from_unit): Likewise.
* io/unix.c (compare_file_filename): Likewise.
(find_file0): Likewise.
(delete_file): Likewise.
2014-09-10 Janne Blomqvist <jb@gcc.gnu.org> 2014-09-10 Janne Blomqvist <jb@gcc.gnu.org>
* io/transfer.c (read_block_form): Fix pad status check (found by * io/transfer.c (read_block_form): Fix pad status check (found by
......
...@@ -72,7 +72,7 @@ st_close (st_parameter_close *clp) ...@@ -72,7 +72,7 @@ st_close (st_parameter_close *clp)
generate_error (&clp->common, LIBERROR_BAD_OPTION, generate_error (&clp->common, LIBERROR_BAD_OPTION,
"Can't KEEP a scratch file on CLOSE"); "Can't KEEP a scratch file on CLOSE");
#if !HAVE_UNLINK_OPEN_FILE #if !HAVE_UNLINK_OPEN_FILE
path = fc_strdup (u->file, u->file_len); path = strdup (u->filename);
#endif #endif
} }
else else
...@@ -82,7 +82,7 @@ st_close (st_parameter_close *clp) ...@@ -82,7 +82,7 @@ st_close (st_parameter_close *clp)
#if HAVE_UNLINK_OPEN_FILE #if HAVE_UNLINK_OPEN_FILE
delete_file (u); delete_file (u);
#else #else
path = fc_strdup (u->file, u->file_len); path = strdup (u->filename);
#endif #endif
} }
} }
......
...@@ -80,10 +80,10 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_unit * u) ...@@ -80,10 +80,10 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_unit * u)
memset (&iqp->name[tmplen], ' ', iqp->name_len - tmplen); memset (&iqp->name[tmplen], ' ', iqp->name_len - tmplen);
} }
else /* If ttyname does not work, go with the default. */ else /* If ttyname does not work, go with the default. */
fstrcpy (iqp->name, iqp->name_len, u->file, u->file_len); cf_strcpy (iqp->name, iqp->name_len, u->filename);
} }
else else
fstrcpy (iqp->name, iqp->name_len, u->file, u->file_len); cf_strcpy (iqp->name, iqp->name_len, u->filename);
#elif defined __MINGW32__ #elif defined __MINGW32__
if (u->unit_number == options.stdin_unit) if (u->unit_number == options.stdin_unit)
fstrcpy (iqp->name, iqp->name_len, "CONIN$", sizeof("CONIN$")); fstrcpy (iqp->name, iqp->name_len, "CONIN$", sizeof("CONIN$"));
......
...@@ -567,8 +567,9 @@ typedef struct gfc_unit ...@@ -567,8 +567,9 @@ typedef struct gfc_unit
array_loop_spec *ls; array_loop_spec *ls;
int rank; int rank;
int file_len; /* Name of the file at the time OPEN was executed, as a
char *file; null-terminated C string. */
char *filename;
/* The format hash table. */ /* The format hash table. */
struct format_hash_entry format_hash_table[FORMAT_HASH_SIZE]; struct format_hash_entry format_hash_table[FORMAT_HASH_SIZE];
......
...@@ -541,7 +541,6 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags) ...@@ -541,7 +541,6 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags)
/* Create the unit structure. */ /* Create the unit structure. */
u->file = xmalloc (opp->file_len);
if (u->unit_number != opp->common.unit) if (u->unit_number != opp->common.unit)
internal_error (&opp->common, "Unit number changed"); internal_error (&opp->common, "Unit number changed");
u->s = s; u->s = s;
...@@ -618,8 +617,7 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags) ...@@ -618,8 +617,7 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags)
u->strm_pos = stell (u->s) + 1; u->strm_pos = stell (u->s) + 1;
} }
memmove (u->file, opp->file, opp->file_len); u->filename = fc_strdup (opp->file, opp->file_len);
u->file_len = opp->file_len;
/* Curiously, the standard requires that the /* Curiously, the standard requires that the
position specifier be ignored for new files so a newly connected position specifier be ignored for new files so a newly connected
...@@ -685,20 +683,13 @@ already_open (st_parameter_open *opp, gfc_unit * u, unit_flags * flags) ...@@ -685,20 +683,13 @@ already_open (st_parameter_open *opp, gfc_unit * u, unit_flags * flags)
} }
u->s = NULL; u->s = NULL;
free (u->file);
u->file = NULL;
u->file_len = 0;
#if !HAVE_UNLINK_OPEN_FILE #if !HAVE_UNLINK_OPEN_FILE
char *path = NULL; if (u->filename && u->flags.status == STATUS_SCRATCH)
if (u->file && u->flags.status == STATUS_SCRATCH) unlink (u->filename);
path = fc_strdup (u->file, u->file_len);
if (path != NULL)
{
unlink (path);
free (path);
}
#endif #endif
free (u->filename);
u->filename = NULL;
u = new_unit (opp, u, flags); u = new_unit (opp, u, flags);
if (u != NULL) if (u != NULL)
......
...@@ -587,9 +587,7 @@ init_units (void) ...@@ -587,9 +587,7 @@ init_units (void)
u->recl = options.default_recl; u->recl = options.default_recl;
u->endfile = NO_ENDFILE; u->endfile = NO_ENDFILE;
u->file_len = strlen (stdin_name); u->filename = strdup (stdin_name);
u->file = xmalloc (u->file_len);
memmove (u->file, stdin_name, u->file_len);
fbuf_init (u, 0); fbuf_init (u, 0);
...@@ -618,9 +616,7 @@ init_units (void) ...@@ -618,9 +616,7 @@ init_units (void)
u->recl = options.default_recl; u->recl = options.default_recl;
u->endfile = AT_ENDFILE; u->endfile = AT_ENDFILE;
u->file_len = strlen (stdout_name); u->filename = strdup (stdout_name);
u->file = xmalloc (u->file_len);
memmove (u->file, stdout_name, u->file_len);
fbuf_init (u, 0); fbuf_init (u, 0);
...@@ -648,9 +644,7 @@ init_units (void) ...@@ -648,9 +644,7 @@ init_units (void)
u->recl = options.default_recl; u->recl = options.default_recl;
u->endfile = AT_ENDFILE; u->endfile = AT_ENDFILE;
u->file_len = strlen (stderr_name); u->filename = strdup (stderr_name);
u->file = xmalloc (u->file_len);
memmove (u->file, stderr_name, u->file_len);
fbuf_init (u, 256); /* 256 bytes should be enough, probably not doing fbuf_init (u, 256); /* 256 bytes should be enough, probably not doing
any kind of exotic formatting to stderr. */ any kind of exotic formatting to stderr. */
...@@ -689,9 +683,8 @@ close_unit_1 (gfc_unit *u, int locked) ...@@ -689,9 +683,8 @@ close_unit_1 (gfc_unit *u, int locked)
delete_unit (u); delete_unit (u);
free (u->file); free (u->filename);
u->file = NULL; u->filename = NULL;
u->file_len = 0;
free_format_hash_table (u); free_format_hash_table (u);
fbuf_destroy (u); fbuf_destroy (u);
...@@ -804,7 +797,7 @@ filename_from_unit (int n) ...@@ -804,7 +797,7 @@ filename_from_unit (int n)
/* Get the filename. */ /* Get the filename. */
if (u != NULL) if (u != NULL)
return fc_strdup (u->file, u->file_len); return strdup (u->filename);
else else
return (char *) NULL; return (char *) NULL;
} }
......
...@@ -1525,11 +1525,7 @@ compare_file_filename (gfc_unit *u, const char *name, int len) ...@@ -1525,11 +1525,7 @@ compare_file_filename (gfc_unit *u, const char *name, int len)
goto done; goto done;
} }
# endif # endif
ret = (strcmp(path, u->filename) == 0);
if (len != u->file_len)
ret = 0;
else
ret = (memcmp(path, u->file, len) == 0);
#endif #endif
done: done:
free (path); free (path);
...@@ -1541,8 +1537,8 @@ compare_file_filename (gfc_unit *u, const char *name, int len) ...@@ -1541,8 +1537,8 @@ compare_file_filename (gfc_unit *u, const char *name, int len)
# define FIND_FILE0_DECL struct stat *st # define FIND_FILE0_DECL struct stat *st
# define FIND_FILE0_ARGS st # define FIND_FILE0_ARGS st
#else #else
# define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len # define FIND_FILE0_DECL uint64_t id, const char *path
# define FIND_FILE0_ARGS id, file, file_len # define FIND_FILE0_ARGS id, path
#endif #endif
/* find_file0()-- Recursive work function for find_file() */ /* find_file0()-- Recursive work function for find_file() */
...@@ -1574,7 +1570,7 @@ find_file0 (gfc_unit *u, FIND_FILE0_DECL) ...@@ -1574,7 +1570,7 @@ find_file0 (gfc_unit *u, FIND_FILE0_DECL)
} }
else else
# endif # endif
if (compare_string (u->file_len, u->file, file_len, file) == 0) if (strcmp (u->filename, path) == 0)
return u; return u;
#endif #endif
...@@ -1718,10 +1714,7 @@ flush_all_units (void) ...@@ -1718,10 +1714,7 @@ flush_all_units (void)
int int
delete_file (gfc_unit * u) delete_file (gfc_unit * u)
{ {
char *path = fc_strdup (u->file, u->file_len); return unlink (u->filename);
int err = unlink (path);
free (path);
return err;
} }
......
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