mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
7425e424b5
commit
0e05c303e5
|
|
@ -1,3 +1,8 @@
|
||||||
|
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.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
! { 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
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
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)
|
||||||
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)
|
||||||
#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)
|
||||||
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
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
# 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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue