mingw: short-circuit the conversion of /dev/null to UTF-16

In the next commit, we want to disallow accessing any path that contains
any segment that is equivalent to `NUL`. In particular, we want to
disallow accessing `NUL` (e.g. to prevent any repository from being
checked out that contains a file called `NUL`, as that is not a valid
file name on Windows).

However, there are legitimate use cases within Git itself to write to
the Null device. As Git is really a Linux project, it does not abstract
that idea, though, but instead uses `/dev/null` to describe this
intention.

So let's side-step the validation _specifically_ in the case that we
want to write to (or read from) `/dev/null`, via a dedicated short-cut
in the code that skips the call to `validate_win32_path()`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Johannes Schindelin 2019-12-21 22:05:00 +00:00 committed by Junio C Hamano
parent 53a06cf39b
commit 98d9b23e90

View File

@ -484,16 +484,16 @@ int mingw_open (const char *filename, int oflags, ...)
return -1; return -1;
} }
if (filename && !strcmp(filename, "/dev/null"))
filename = "nul";
if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename)) if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename))
open_fn = mingw_open_append; open_fn = mingw_open_append;
else else
open_fn = _wopen; open_fn = _wopen;
if (xutftowcs_path(wfilename, filename) < 0) if (filename && !strcmp(filename, "/dev/null"))
wcscpy(wfilename, L"nul");
else if (xutftowcs_path(wfilename, filename) < 0)
return -1; return -1;
fd = open_fn(wfilename, oflags, mode); fd = open_fn(wfilename, oflags, mode);
if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) { if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) {
@ -556,10 +556,13 @@ FILE *mingw_fopen (const char *filename, const char *otype)
return NULL; return NULL;
} }
if (filename && !strcmp(filename, "/dev/null")) if (filename && !strcmp(filename, "/dev/null"))
filename = "nul"; wcscpy(wfilename, L"nul");
if (xutftowcs_path(wfilename, filename) < 0 || else if (xutftowcs_path(wfilename, filename) < 0)
xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
return NULL; return NULL;
if (xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
return NULL;
if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) { if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) {
error("could not unhide %s", filename); error("could not unhide %s", filename);
return NULL; return NULL;
@ -583,10 +586,13 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
return NULL; return NULL;
} }
if (filename && !strcmp(filename, "/dev/null")) if (filename && !strcmp(filename, "/dev/null"))
filename = "nul"; wcscpy(wfilename, L"nul");
if (xutftowcs_path(wfilename, filename) < 0 || else if (xutftowcs_path(wfilename, filename) < 0)
xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
return NULL; return NULL;
if (xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
return NULL;
if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) { if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) {
error("could not unhide %s", filename); error("could not unhide %s", filename);
return NULL; return NULL;