]> Savannah Git Hosting - gnulib.git/commitdiff
getcwd: Fix crash when invoked with size = 0 on MSVC.
authorBruno Haible <bruno@clisp.org>
Tue, 2 Jul 2019 18:43:00 +0000 (20:43 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 2 Jul 2019 18:43:00 +0000 (20:43 +0200)
* lib/getcwd.c: Include msvc-inval.h.
(getcwd_nothrow): New function/macro.
(getcwd_system): New macro.
(__getcwd): Use it instead of getcwd.
* modules/getcwd (Depends-on): Add msvc-inval.
* doc/posix-functions/getcwd.texi: Mention the MSVC issue.

ChangeLog
doc/posix-functions/getcwd.texi
lib/getcwd.c
modules/getcwd

index 706fe6a771896f2cf3b359b911aa7a0fbd9dae9e..7b3d3bdeb7a6df8ba3fcd9f1fb09c2f0e6735bde 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2019-07-02  Bruno Haible  <bruno@clisp.org>
+
+       getcwd: Fix crash when invoked with size = 0 on MSVC.
+       * lib/getcwd.c: Include msvc-inval.h.
+       (getcwd_nothrow): New function/macro.
+       (getcwd_system): New macro.
+       (__getcwd): Use it instead of getcwd.
+       * modules/getcwd (Depends-on): Add msvc-inval.
+       * doc/posix-functions/getcwd.texi: Mention the MSVC issue.
+
 2019-07-02  Bruno Haible  <bruno@clisp.org>
 
        nonblocking-pipe tests: Fix test failure on MSVC.
index 07025695d4e66179a381024b97039ec0ed3e8eef..41e19c58b923667a3537315787d787adf5dd0a51 100644 (file)
@@ -23,9 +23,12 @@ instead of @code{size_t} for the size argument when using non-standard
 headers, and the declaration is missing from @code{<unistd.h>}:
 mingw, MSVC 14.
 @item
+On some platforms, @code{getcwd (buf, 0)} crashes:
+MSVC 14.
+@item
 On some platforms, @code{getcwd (buf, 0)} fails with @code{ERANGE}
 instead of the required @code{EINVAL}:
-mingw, MSVC 14.
+mingw.
 @end itemize
 
 Portability problems fixed by Gnulib module @code{getcwd}:
index 41eedb7005aa8aada1325d62de97c492a8f75b38..8f15f560c28a83e7244e9a4483543a7029bf251c 100644 (file)
 # define MATCHING_INO(dp, ino) true
 #endif
 
+#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+# include "msvc-inval.h"
+#endif
+
 #if !_LIBC
 # define __getcwd rpl_getcwd
 # define __lstat lstat
 # undef closedir
 #endif
 \f
+#ifdef _MSC_VER
+# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+static char *
+getcwd_nothrow (char *buf, size_t size)
+{
+  char *result;
+
+  TRY_MSVC_INVAL
+    {
+      result = _getcwd (buf, size);
+    }
+  CATCH_MSVC_INVAL
+    {
+      result = NULL;
+      errno = ERANGE;
+    }
+  DONE_MSVC_INVAL;
+
+  return result;
+}
+# else
+#  define getcwd_nothrow _getcwd
+# endif
+# define getcwd_system getcwd_nothrow
+#else
+# define getcwd_system getcwd
+#endif
+
 /* Get the name of the current working directory, and put it in SIZE
    bytes of BUF.  Returns NULL if the directory couldn't be determined or
    SIZE was too small.  If successful, returns BUF.  In GNU, if BUF is
@@ -155,7 +187,7 @@ __getcwd (char *buf, size_t size)
      this wrong result with errno = 0.  */
 
 # undef getcwd
-  dir = getcwd (buf, size);
+  dir = getcwd_system (buf, size);
   if (dir || (size && errno == ERANGE))
     return dir;
 
@@ -166,7 +198,7 @@ __getcwd (char *buf, size_t size)
   if (errno == EINVAL && buf == NULL && size == 0)
     {
       char big_buffer[BIG_FILE_NAME_LENGTH + 1];
-      dir = getcwd (big_buffer, sizeof big_buffer);
+      dir = getcwd_system (big_buffer, sizeof big_buffer);
       if (dir)
         return strdup (dir);
     }
index 628c4d1f6fcdf47e62adea787466e728e8a16837..90299a1c7e2e1617a985713c354900201843c410 100644 (file)
@@ -13,6 +13,7 @@ Depends-on:
 unistd
 extensions
 pathmax         [test $REPLACE_GETCWD = 1]
+msvc-inval      [test $REPLACE_GETCWD = 1]
 mempcpy         [test $REPLACE_GETCWD = 1]
 d-ino           [test $REPLACE_GETCWD = 1]
 memmove         [test $REPLACE_GETCWD = 1]