From 361016f680abf830004ef726f816820a0c8c1950 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov Date: Thu, 18 Jan 2024 04:03:03 -0300 Subject: [PATCH] [Path] Fix off-by-one in finding filename for win style paths (#78055) This fixes a crash where `path::parent_path` causes an invalid access on a string upon receiving a path that consists of a single colon. On Windows machine, with runtime checks enabled build, upon `clang -I: test.cc` produces: ``` Assertion failed: Index < Length && "Invalid index!", file llvm\include\llvm/ADT/StringRef.h, line 232 ... #6 0x00007ff7816201eb `anonymous namespace'::parent_path_end llvm\lib\Support\Path.cpp:144:0 #7 0x00007ff781620135 llvm::sys::path::parent_path(class llvm::StringRef, enum llvm::sys::path::Style) llvm\lib\Support\Path.cpp:470:0 ``` Ideally, we can look for the last colon starting from the last character, but we can instead start from second to last, and handle empty paths by abusing `0 - 1 == npos`. --- llvm/lib/Support/Path.cpp | 2 +- llvm/unittests/Support/Path.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp index 9410252ba3319..c8de2c0625aa2 100644 --- a/llvm/lib/Support/Path.cpp +++ b/llvm/lib/Support/Path.cpp @@ -104,7 +104,7 @@ namespace { if (is_style_windows(style)) { if (pos == StringRef::npos) - pos = str.find_last_of(':', str.size() - 2); + pos = str.find_last_of(':', str.size() - 1); } if (pos == StringRef::npos || (pos == 1 && is_separator(str[0], style))) diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp index a7b7e6a0f5044..837ca03216f87 100644 --- a/llvm/unittests/Support/Path.cpp +++ b/llvm/unittests/Support/Path.cpp @@ -190,6 +190,7 @@ TEST(Support, Path) { paths.push_back("c:\\foo\\"); paths.push_back("c:\\foo/"); paths.push_back("c:/foo\\bar"); + paths.push_back(":"); for (SmallVector::const_iterator i = paths.begin(), e = paths.end();