summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2019-09-05 22:09:10 (GMT)
committerJohannes Schindelin <johannes.schindelin@gmx.de>2019-12-05 14:37:07 (GMT)
commitf82a97eb9197c1e3768e72648f37ce0ca3233734 (patch)
tree1625e0241be5d0ffefe15b39133c8bc5068a021d /compat
parent817ddd64c20b29b2d86b3a0589f7ff88d1279109 (diff)
downloadgit-f82a97eb9197c1e3768e72648f37ce0ca3233734.zip
git-f82a97eb9197c1e3768e72648f37ce0ca3233734.tar.gz
git-f82a97eb9197c1e3768e72648f37ce0ca3233734.tar.bz2
mingw: handle `subst`-ed "DOS drives"
Over a decade ago, in 25fe217b86c (Windows: Treat Windows style path names., 2008-03-05), Git was taught to handle absolute Windows paths, i.e. paths that start with a drive letter and a colon. Unbeknownst to us, while drive letters of physical drives are limited to letters of the English alphabet, there is a way to assign virtual drive letters to arbitrary directories, via the `subst` command, which is _not_ limited to English letters. It is therefore possible to have absolute Windows paths of the form `1:\what\the\hex.txt`. Even "better": pretty much arbitrary Unicode letters can also be used, e.g. `ä:\tschibät.sch`. While it can be sensibly argued that users who set up such funny drive letters really seek adverse consequences, the Windows Operating System is known to be a platform where many users are at the mercy of administrators who have their very own idea of what constitutes a reasonable setup. Therefore, let's just make sure that such funny paths are still considered absolute paths by Git, on Windows. In addition to Unicode characters, pretty much any character is a valid drive letter, as far as `subst` is concerned, even `:` and `"` or even a space character. While it is probably the opposite of smart to use them, let's safeguard `is_dos_drive_prefix()` against all of them. Note: `[::1]:repo` is a valid URL, but not a valid path on Windows. As `[` is now considered a valid drive letter, we need to be very careful to avoid misinterpreting such a string as valid local path in `url_is_local_not_ssh()`. To do that, we use the just-introduced function `is_valid_path()` (which will label the string as invalid file name because of the colon characters). This fixes CVE-2019-1351. Reported-by: Nicolas Joly <Nicolas.Joly@microsoft.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Diffstat (limited to 'compat')
-rw-r--r--compat/mingw.c24
-rw-r--r--compat/mingw.h4
2 files changed, 26 insertions, 2 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index 3aea269..27d6f4a 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1986,6 +1986,30 @@ pid_t waitpid(pid_t pid, int *status, int options)
return -1;
}
+int mingw_has_dos_drive_prefix(const char *path)
+{
+ int i;
+
+ /*
+ * Does it start with an ASCII letter (i.e. highest bit not set),
+ * followed by a colon?
+ */
+ if (!(0x80 & (unsigned char)*path))
+ return *path && path[1] == ':' ? 2 : 0;
+
+ /*
+ * While drive letters must be letters of the English alphabet, it is
+ * possible to assign virtually _any_ Unicode character via `subst` as
+ * a drive letter to "virtual drives". Even `1`, or `ä`. Or fun stuff
+ * like this:
+ *
+ * subst ֍: %USERPROFILE%\Desktop
+ */
+ for (i = 1; i < 4 && (0x80 & (unsigned char)path[i]); i++)
+ ; /* skip first UTF-8 character */
+ return path[i] == ':' ? i + 1 : 0;
+}
+
int mingw_skip_dos_drive_prefix(char **path)
{
int ret = has_dos_drive_prefix(*path);
diff --git a/compat/mingw.h b/compat/mingw.h
index 7482f19..1706466 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -394,8 +394,8 @@ HANDLE winansi_get_osfhandle(int fd);
* git specific compatibility
*/
-#define has_dos_drive_prefix(path) \
- (isalpha(*(path)) && (path)[1] == ':' ? 2 : 0)
+int mingw_has_dos_drive_prefix(const char *path);
+#define has_dos_drive_prefix mingw_has_dos_drive_prefix
int mingw_skip_dos_drive_prefix(char **path);
#define skip_dos_drive_prefix mingw_skip_dos_drive_prefix
static inline int mingw_is_dir_sep(int c)