{"thread":{"id":"53190","subject":"[PATCH] mingw: do not treat `COM0` as a reserved file name","startedAt":"2020-04-08T18:06:54Z","lastAt":"2020-04-08T18:06:54Z","messageCount":1,"participants":["Johannes Schindelin via GitGitGadget"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"395077","messageId":"pull.754.git.git.1586369209374.gitgitgadget@gmail.com","threadId":"53190","inReplyTo":null,"subject":"[PATCH] mingw: do not treat `COM0` as a reserved file name","fromName":"Johannes Schindelin via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-04-08T18:06:49Z","receivedAt":"2020-04-08T18:06:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nIn 4dc42c6c186 (mingw: refuse paths containing reserved names,\n2019-12-21), we started disallowing file names that are reserved, e.g.\n`NUL`, `CONOUT$`, etc.\n\nThis included `COM<n>` where `<n>` is a digit. Unfortunately, this\nincludes `COM0` but only `COM1`, ..., `COM9` are reserved, according to\nthe official documentation, `COM0` is mentioned in the \"NT Namespaces\"\nsection but it is explicitly _omitted_ from the list of reserved names:\nhttps://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions\n\nTests corroborate this: it is totally possible to write a file called\n`com0.c` on Windows 10, but not `com1.c`.\n\nSo let's tighten the code to disallow only the reserved `COM<n>` file\nnames, but to allow `COM0` again.\n\nThis fixes https://github.com/git-for-windows/git/issues/2470.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n    mingw: handle COM0 correctly\n    \n    The code to prevent the reserved COM<n> file names erred on the side of\n    simple code, and sadly sacrificed correctness while at it. This fixes\n    it.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-754%2Fdscho%2Fcom0-is-not-a-reserved-name-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-754/dscho/com0-is-not-a-reserved-name-v1\nPull-Request: https://github.com/git/git/pull/754\n\n compat/mingw.c        | 8 +++++---\n t/t0060-path-utils.sh | 2 ++\n 2 files changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex d14065d60ec..835a340211e 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -2581,12 +2581,14 @@ int is_valid_win32_path(const char *path, int allow_literal_nul)\n \t\t\t\t\tcontinue;\n \t\t\t\t}\n \t\t\t\tbreak;\n-\t\t\tcase 'c': case 'C': /* COM<N>, CON, CONIN$, CONOUT$ */\n+\t\t\tcase 'c': case 'C':\n+\t\t\t\t/* COM1 ... COM9, CON, CONIN$, CONOUT$ */\n \t\t\t\tif ((c = path[++i]) != 'o' && c != 'O')\n \t\t\t\t\tgoto not_a_reserved_name;\n \t\t\t\tc = path[++i];\n-\t\t\t\tif (c == 'm' || c == 'M') { /* COM<N> */\n-\t\t\t\t\tif (!isdigit(path[++i]))\n+\t\t\t\tif (c == 'm' || c == 'M') { /* COM1 ... COM9 */\n+\t\t\t\t\tc = path[++i];\n+\t\t\t\t\tif (c < '1' || c > '9')\n \t\t\t\t\t\tgoto not_a_reserved_name;\n \t\t\t\t} else if (c == 'n' || c == 'N') { /* CON */\n \t\t\t\t\tc = path[i + 1];\ndiff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh\nindex 2ea2d00c39a..56db5c8abab 100755\n--- a/t/t0060-path-utils.sh\n+++ b/t/t0060-path-utils.sh\n@@ -476,6 +476,7 @@ test_expect_success MINGW 'is_valid_path() on Windows' '\n \t\tC:\\\\git \\\n \t\tcomm \\\n \t\tconout.c \\\n+\t\tcom0.c \\\n \t\tlptN \\\n \t\t\\\n \t\t--not \\\n@@ -488,6 +489,7 @@ test_expect_success MINGW 'is_valid_path() on Windows' '\n \t\t\"AUX.c\" \\\n \t\t\"abc/conOut\\$  .xyz/test\" \\\n \t\tlpt8 \\\n+\t\tcom9.c \\\n \t\t\"lpt*\" \\\n \t\tNul \\\n \t\t\"PRN./abc\"\n\nbase-commit: 9fadedd637b312089337d73c3ed8447e9f0aa775\n-- \ngitgitgadget\n"}]}