Fix path handling
authorJanne Blomqvist <jb@gcc.gnu.org>
Fri, 29 Apr 2011 16:09:45 +0000 (19:09 +0300)
committerJanne Blomqvist <jb@gcc.gnu.org>
Fri, 29 Apr 2011 16:09:45 +0000 (19:09 +0300)
From-SVN: r173172

libgfortran/ChangeLog
libgfortran/io/unix.c

index 89ae12565ed7b1736454f01c50f243c6c13b63c2..79a1b7f99dce494b4028ee3ef8ad011dccbac5cd 100644 (file)
@@ -1,3 +1,18 @@
+2011-04-29  Janne Blomqvist  <jb@gcc.gnu.org>
+
+       * io/unix.c (min): New macro.
+       (unpack_filename): Return errno number for errors.
+       (regular_file): Use appropriately sized buffer for path.
+       (compare_file_filename): Likewise.
+       (find_file): Likewise.
+       (delete_file): Likewise.
+       (file_exists): Likewise.
+       (file_size): Likewise.
+       (inquire_sequential): Likewise.
+       (inquire_direct): Likewise.
+       (inquire_formatted): Likewise.
+       (inquire_access): Likewise.
+
 2011-04-29  Janne Blomqvist  <jb@gcc.gnu.org>
 
        PR libfortran/48488
index ee2fd172517837ebee40757ae0740d345409ea25..4e4bc3b1ee5fa26a492db5b3b52bc2d240416be6 100644 (file)
@@ -41,6 +41,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include <errno.h>
 
 
+/* min macro that evaluates its arguments only once.  */
+#define min(a,b)               \
+  ({ typeof (a) _a = (a);      \
+    typeof (b) _b = (b);       \
+    _a < _b ? _a : _b; })
+
+
 /* For mingw, we don't identify files by their inode number, but by a
    64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
 #ifdef __MINGW32__
@@ -996,10 +1003,10 @@ int
 unpack_filename (char *cstring, const char *fstring, int len)
 {
   if (fstring == NULL)
-    return 1;
+    return EFAULT;
   len = fstrlen (fstring, len);
   if (len >= PATH_MAX)
-    return 1;
+    return ENAMETOOLONG;
 
   memmove (cstring, fstring, len);
   cstring[len] = '\0';
@@ -1124,15 +1131,17 @@ tempfile (st_parameter_open *opp)
 static int
 regular_file (st_parameter_open *opp, unit_flags *flags)
 {
-  char path[PATH_MAX + 1];
+  char path[min(PATH_MAX, opp->file_len + 1)];
   int mode;
   int rwflag;
   int crflag;
   int fd;
+  int err;
 
-  if (unpack_filename (path, opp->file, opp->file_len))
+  err = unpack_filename (path, opp->file, opp->file_len);
+  if (err)
     {
-      errno = ENOENT;          /* Fake an OS error */
+      errno = err;             /* Fake an OS error */
       return -1;
     }
 
@@ -1406,7 +1415,7 @@ st_printf (const char *format, ...)
 int
 compare_file_filename (gfc_unit *u, const char *name, int len)
 {
-  char path[PATH_MAX + 1];
+  char path[min(PATH_MAX, len + 1)];
   struct stat st;
 #ifdef HAVE_WORKING_STAT
   unix_stream *s;
@@ -1506,7 +1515,7 @@ find_file0 (gfc_unit *u, FIND_FILE0_DECL)
 gfc_unit *
 find_file (const char *file, gfc_charlen_type file_len)
 {
-  char path[PATH_MAX + 1];
+  char path[min(PATH_MAX, file_len + 1)];
   struct stat st[1];
   gfc_unit *u;
 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
@@ -1625,11 +1634,12 @@ flush_all_units (void)
 int
 delete_file (gfc_unit * u)
 {
-  char path[PATH_MAX + 1];
+  char path[min(PATH_MAX, u->file_len + 1)];
+  int err = unpack_filename (path, u->file, u->file_len);
 
-  if (unpack_filename (path, u->file, u->file_len))
+  if (err)
     {                          /* Shouldn't be possible */
-      errno = ENOENT;
+      errno = err;
       return 1;
     }
 
@@ -1643,7 +1653,7 @@ delete_file (gfc_unit * u)
 int
 file_exists (const char *file, gfc_charlen_type file_len)
 {
-  char path[PATH_MAX + 1];
+  char path[min(PATH_MAX, file_len + 1)];
 
   if (unpack_filename (path, file, file_len))
     return 0;
@@ -1657,7 +1667,7 @@ file_exists (const char *file, gfc_charlen_type file_len)
 GFC_IO_INT
 file_size (const char *file, gfc_charlen_type file_len)
 {
-  char path[PATH_MAX + 1];
+  char path[min(PATH_MAX, file_len + 1)];
   struct stat statbuf;
 
   if (unpack_filename (path, file, file_len))
@@ -1678,7 +1688,7 @@ static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
 const char *
 inquire_sequential (const char *string, int len)
 {
-  char path[PATH_MAX + 1];
+  char path[min(PATH_MAX, len + 1)];
   struct stat statbuf;
 
   if (string == NULL ||
@@ -1702,7 +1712,7 @@ inquire_sequential (const char *string, int len)
 const char *
 inquire_direct (const char *string, int len)
 {
-  char path[PATH_MAX + 1];
+  char path[min(PATH_MAX, len + 1)];
   struct stat statbuf;
 
   if (string == NULL ||
@@ -1726,7 +1736,7 @@ inquire_direct (const char *string, int len)
 const char *
 inquire_formatted (const char *string, int len)
 {
-  char path[PATH_MAX + 1];
+  char path[min(PATH_MAX, len + 1)];
   struct stat statbuf;
 
   if (string == NULL ||
@@ -1761,7 +1771,7 @@ inquire_unformatted (const char *string, int len)
 static const char *
 inquire_access (const char *string, int len, int mode)
 {
-  char path[PATH_MAX + 1];
+  char path[min(PATH_MAX, len + 1)];
 
   if (string == NULL || unpack_filename (path, string, len) ||
       access (path, mode) < 0)