From ca67be51d7e4c6f1a6514bf75feaa9edd165cac2 Mon Sep 17 00:00:00 2001 From: Gavin Hayes Date: Wed, 14 Aug 2024 21:51:13 -0400 Subject: [PATCH] mkntpath: fix relative parsing --- libc/calls/mkntpath.c | 13 +++++++++++++ test/libc/calls/mkntpath_test.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/libc/calls/mkntpath.c b/libc/calls/mkntpath.c index c3116d794..7c535de1a 100644 --- a/libc/calls/mkntpath.c +++ b/libc/calls/mkntpath.c @@ -55,6 +55,19 @@ textwindows size_t __normntpath(char16_t *p, size_t n) { // matched "/../" or "/..$" while (j && p[j - 1] == '\\') --j; + if (j && p[j - 1] == '.') { + // matched "." before + if (j >= 2 && p[j - 2] == '.' && // + (j == 2 || p[j - 3] == '\\')) { + // matched "^.." or "/.." before + p[++j] = '.'; + ++j; + continue; + } else if (j == 1 || p[j - 2] == '\\') { + // matched "^." or "/." before + continue; + } + } while (j && p[j - 1] != '\\') --j; } else { diff --git a/test/libc/calls/mkntpath_test.c b/test/libc/calls/mkntpath_test.c index 88f538e7c..f9e249fdd 100644 --- a/test/libc/calls/mkntpath_test.c +++ b/test/libc/calls/mkntpath_test.c @@ -51,4 +51,34 @@ TEST(mkntpath, testRemoveDoubleSlash) { EXPECT_STREQ(u"C:\\Users\\jart\\.config", p); } +TEST(mkntpath, testRelativeCurrentParent) { + EXPECT_EQ(3, __mkntpath("./../", p)); + EXPECT_STREQ(u"..\\", p); +} + +TEST(mkntpath, testRelativeParentParent) { + EXPECT_EQ(6, __mkntpath("../../", p)); + EXPECT_STREQ(u"..\\..\\", p); +} + +TEST(mkntpath, testRelativeParentParentParent) { + EXPECT_EQ(9, __mkntpath("../../../", p)); + EXPECT_STREQ(u"..\\..\\..\\", p); +} + +TEST(mkntpath, testRelativeDirParent) { + EXPECT_EQ(2, __mkntpath("abc/../", p)); + EXPECT_STREQ(u".\\", p); +} + +TEST(mkntpath, testRelativeDirCurrent) { + EXPECT_EQ(4, __mkntpath("abc/./", p)); + EXPECT_STREQ(u"abc\\", p); +} + +TEST(mkntpath, testRelativeDirDirParent) { + EXPECT_EQ(4, __mkntpath("abc/def/../", p)); + EXPECT_STREQ(u"abc\\", p); +} + #endif /* SupportsWindows() */