PR libfortran/62768 Handle filenames with embedded null characters.
authorJanne Blomqvist <jb@gcc.gnu.org>
Tue, 16 Sep 2014 21:40:28 +0000 (00:40 +0300)
committerJanne Blomqvist <jb@gcc.gnu.org>
Tue, 16 Sep 2014 21:40:28 +0000 (00:40 +0300)
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

gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/filename_null.f90 [new file with mode: 0644]
libgfortran/ChangeLog
libgfortran/io/close.c
libgfortran/io/inquire.c
libgfortran/io/io.h
libgfortran/io/open.c
libgfortran/io/unit.c
libgfortran/io/unix.c

index 93e40b6e1173246613fe3c15563a671dc0bee7ec..507022cdfea7654ee67b11d563ca0f9c82e4ea2a 100644 (file)
@@ -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 (file)
index 0000000..f24d243
--- /dev/null
@@ -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
index 29c35fa627729a9592cef0f042e72c65cd16c191..fde3965e5eb064c9b84405ade9bc3d80d8341678 100644 (file)
@@ -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
index 55f49da831ecb07b4a687d62eeaad09f45cb3b56..d0d49f697c4f5bbb9945001b77c1520b7563c157 100644 (file)
@@ -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
             }
        }
index c41237c3ec79071a65de791dd0f41cfcf1b7eb2b..4d03161cbf89fb1b87ec20b813816337d7fed288 100644 (file)
@@ -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$"));
index 4e71d4953b1aa98cb9ec8de1a041700a8dc4a5e6..1e0d092976de3db723368fd51f556f20e86624f1 100644 (file)
@@ -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];
index b803859ac3d8f45318c149007e0d655163a38589..67fa9ac11aa79319aa44f9b1192088493515156b 100644 (file)
@@ -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)
index 22b315a4fd3d3e2144b99bc701b82c7e4d5ff591..5cc51b56766fe58c6fe3eae642a189ae589acabe 100644 (file)
@@ -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;
 }
index 9ad293b60a462e85af3f9e053e28a276f90aed39..d30c6e5e33a64d1d7735218d6066e1e3ff9d145a 100644 (file)
@@ -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);
 }