bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* getcwd: fix crash when invoked with size = 0 on MSVC
@ 2019-07-02 18:46 Bruno Haible
  0 siblings, 0 replies; only message in thread
From: Bruno Haible @ 2019-07-02 18:46 UTC (permalink / raw)
  To: bug-gnulib

On MSVC, I'm seeing this test failure:

FAIL: test-getcwd-lgpl
======================

FAIL test-getcwd-lgpl.exe (exit status: 127)

It's the getcwd-lgpl test, but it exercises the function rpl_getcwd defined
in lib/getcwd.c, not the one in lib/getcwd-lgpl.c.

The crash happens in the getcwd (buf, 0) call. The MSVC runtime signals an
invalid argument through an exception which, by default, crashes the program.

This patch fixes it (in the same manner as in the functions close(), dup2(),
etc.).


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.

diff --git a/lib/getcwd.c b/lib/getcwd.c
index 41eedb7..8f15f56 100644
--- a/lib/getcwd.c
+++ b/lib/getcwd.c
@@ -79,6 +79,10 @@
 # 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
@@ -100,6 +104,34 @@
 # 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);
     }
diff --git a/modules/getcwd b/modules/getcwd
index 628c4d1..90299a1 100644
--- a/modules/getcwd
+++ b/modules/getcwd
@@ -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]
diff --git a/doc/posix-functions/getcwd.texi b/doc/posix-functions/getcwd.texi
index 0702569..41e19c5 100644
--- a/doc/posix-functions/getcwd.texi
+++ b/doc/posix-functions/getcwd.texi
@@ -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}:



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2019-07-02 19:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-02 18:46 getcwd: fix crash when invoked with size = 0 on MSVC Bruno Haible

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).