diff options
author | Janne Blomqvist <jb@gcc.gnu.org> | 2014-09-17 00:40:28 +0300 |
---|---|---|
committer | Janne Blomqvist <jb@gcc.gnu.org> | 2014-09-17 00:40:28 +0300 |
commit | 0e05c303e5c3c7882d5e36a4d5b66f0563ae6478 (patch) | |
tree | 34b3e91356fc23c2feb76d92e78fad28bd83a126 | |
parent | 7425e424b5222704558591fc6cf26eaa57fb81de (diff) | |
download | gcc-0e05c303e5c3c7882d5e36a4d5b66f0563ae6478.zip gcc-0e05c303e5c3c7882d5e36a4d5b66f0563ae6478.tar.gz gcc-0e05c303e5c3c7882d5e36a4d5b66f0563ae6478.tar.bz2 |
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
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/filename_null.f90 | 17 | ||||
-rw-r--r-- | libgfortran/ChangeLog | 15 | ||||
-rw-r--r-- | libgfortran/io/close.c | 4 | ||||
-rw-r--r-- | libgfortran/io/inquire.c | 4 | ||||
-rw-r--r-- | libgfortran/io/io.h | 5 | ||||
-rw-r--r-- | libgfortran/io/open.c | 21 | ||||
-rw-r--r-- | libgfortran/io/unit.c | 19 | ||||
-rw-r--r-- | libgfortran/io/unix.c | 17 |
9 files changed, 61 insertions, 46 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 93e40b6..507022c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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> * gcc.dg/pg-override.c: Fix a typo. diff --git a/gcc/testsuite/gfortran.dg/filename_null.f90 b/gcc/testsuite/gfortran.dg/filename_null.f90 new file mode 100644 index 0000000..f24d243 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/filename_null.f90 @@ -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 diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 29c35fa..fde3965 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -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> * io/transfer.c (read_block_form): Fix pad status check (found by diff --git a/libgfortran/io/close.c b/libgfortran/io/close.c index 55f49da..d0d49f6 100644 --- a/libgfortran/io/close.c +++ b/libgfortran/io/close.c @@ -72,7 +72,7 @@ st_close (st_parameter_close *clp) generate_error (&clp->common, LIBERROR_BAD_OPTION, "Can't KEEP a scratch file on CLOSE"); #if !HAVE_UNLINK_OPEN_FILE - path = fc_strdup (u->file, u->file_len); + path = strdup (u->filename); #endif } else @@ -82,7 +82,7 @@ st_close (st_parameter_close *clp) #if HAVE_UNLINK_OPEN_FILE delete_file (u); #else - path = fc_strdup (u->file, u->file_len); + path = strdup (u->filename); #endif } } diff --git a/libgfortran/io/inquire.c b/libgfortran/io/inquire.c index c41237c..4d03161 100644 --- a/libgfortran/io/inquire.c +++ b/libgfortran/io/inquire.c @@ -80,10 +80,10 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_unit * u) memset (&iqp->name[tmplen], ' ', iqp->name_len - tmplen); } 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 - fstrcpy (iqp->name, iqp->name_len, u->file, u->file_len); + cf_strcpy (iqp->name, iqp->name_len, u->filename); #elif defined __MINGW32__ if (u->unit_number == options.stdin_unit) fstrcpy (iqp->name, iqp->name_len, "CONIN$", sizeof("CONIN$")); diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 4e71d49..1e0d092 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -567,8 +567,9 @@ typedef struct gfc_unit array_loop_spec *ls; int rank; - int file_len; - char *file; + /* Name of the file at the time OPEN was executed, as a + null-terminated C string. */ + char *filename; /* The format hash table. */ struct format_hash_entry format_hash_table[FORMAT_HASH_SIZE]; diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c index b803859..67fa9ac 100644 --- a/libgfortran/io/open.c +++ b/libgfortran/io/open.c @@ -541,7 +541,6 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags) /* Create the unit structure. */ - u->file = xmalloc (opp->file_len); if (u->unit_number != opp->common.unit) internal_error (&opp->common, "Unit number changed"); 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; } - memmove (u->file, opp->file, opp->file_len); - u->file_len = opp->file_len; + u->filename = fc_strdup (opp->file, opp->file_len); /* Curiously, the standard requires that the 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; - free (u->file); - u->file = NULL; - u->file_len = 0; - + #if !HAVE_UNLINK_OPEN_FILE - char *path = NULL; - if (u->file && u->flags.status == STATUS_SCRATCH) - path = fc_strdup (u->file, u->file_len); - if (path != NULL) - { - unlink (path); - free (path); - } + if (u->filename && u->flags.status == STATUS_SCRATCH) + unlink (u->filename); #endif + free (u->filename); + u->filename = NULL; u = new_unit (opp, u, flags); if (u != NULL) diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c index 22b315a..5cc51b5 100644 --- a/libgfortran/io/unit.c +++ b/libgfortran/io/unit.c @@ -587,9 +587,7 @@ init_units (void) u->recl = options.default_recl; u->endfile = NO_ENDFILE; - u->file_len = strlen (stdin_name); - u->file = xmalloc (u->file_len); - memmove (u->file, stdin_name, u->file_len); + u->filename = strdup (stdin_name); fbuf_init (u, 0); @@ -618,9 +616,7 @@ init_units (void) u->recl = options.default_recl; u->endfile = AT_ENDFILE; - u->file_len = strlen (stdout_name); - u->file = xmalloc (u->file_len); - memmove (u->file, stdout_name, u->file_len); + u->filename = strdup (stdout_name); fbuf_init (u, 0); @@ -648,9 +644,7 @@ init_units (void) u->recl = options.default_recl; u->endfile = AT_ENDFILE; - u->file_len = strlen (stderr_name); - u->file = xmalloc (u->file_len); - memmove (u->file, stderr_name, u->file_len); + u->filename = strdup (stderr_name); fbuf_init (u, 256); /* 256 bytes should be enough, probably not doing any kind of exotic formatting to stderr. */ @@ -689,9 +683,8 @@ close_unit_1 (gfc_unit *u, int locked) delete_unit (u); - free (u->file); - u->file = NULL; - u->file_len = 0; + free (u->filename); + u->filename = NULL; free_format_hash_table (u); fbuf_destroy (u); @@ -804,7 +797,7 @@ filename_from_unit (int n) /* Get the filename. */ if (u != NULL) - return fc_strdup (u->file, u->file_len); + return strdup (u->filename); else return (char *) NULL; } diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 9ad293b..d30c6e5 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -1525,11 +1525,7 @@ compare_file_filename (gfc_unit *u, const char *name, int len) goto done; } # endif - - if (len != u->file_len) - ret = 0; - else - ret = (memcmp(path, u->file, len) == 0); + ret = (strcmp(path, u->filename) == 0); #endif done: 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_ARGS st #else -# define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len -# define FIND_FILE0_ARGS id, file, file_len +# define FIND_FILE0_DECL uint64_t id, const char *path +# define FIND_FILE0_ARGS id, path #endif /* find_file0()-- Recursive work function for find_file() */ @@ -1574,7 +1570,7 @@ find_file0 (gfc_unit *u, FIND_FILE0_DECL) } else # endif - if (compare_string (u->file_len, u->file, file_len, file) == 0) + if (strcmp (u->filename, path) == 0) return u; #endif @@ -1718,10 +1714,7 @@ flush_all_units (void) int delete_file (gfc_unit * u) { - char *path = fc_strdup (u->file, u->file_len); - int err = unlink (path); - free (path); - return err; + return unlink (u->filename); } |