Index: lib/Fuzzer/FuzzerIOWindows.cpp =================================================================== --- lib/Fuzzer/FuzzerIOWindows.cpp +++ lib/Fuzzer/FuzzerIOWindows.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -141,10 +142,45 @@ } std::string DirName(const std::string &FileName) { - std::string Res = FileName; - PathRemoveFileSpecA(&Res[0]); - Res.resize(std::strlen(Res.c_str())); - return Res; +// Location, like: \\?\UNC\Server\Share\ \\?\C:\ \\Server\Share\ \ C:\ C: +// ((\\\\\?\\((UNC(\\[^\\]+){2})|(.:))\\)|(\\\\([^\\]+\\){2})|(\\)|(.:\\?))? +// Directories, like: SomeDir\AnotherDir\ +// (([^\\]+\\)*) +// File, like: SomeFile.txt +// ([^\\]+)? + static std::regex Reg( + R"(((\\\\\?\\((UNC(\\[^\\]+){2})|(.:))\\)|(\\\\([^\\]+\\){2})|(\\)|(.:\\?))?)" + R"((([^\\]+\\)*))" + R"(([^\\]+)?)"); + + std::smatch MatchRes; + if (!regex_match(FileName, MatchRes, Reg)) { + Printf("DirName() failed for \"%s\", invalid path.\n", FileName.c_str()); + exit(1); + } + + std::string Location(MatchRes[1]), Dir(MatchRes[11]), File(MatchRes[13]); + + if (!Dir.empty()) { + Dir.pop_back(); // Remove trailing '\'. + if (File.empty()) { // Path ended in '\'. + assert(!Dir.empty()); + // Remove file name from Dir. + size_t LastSep = Dir.find_last_of('\\'); + if (LastSep == std::string::npos) + LastSep = 0; + Dir.erase(LastSep); + } + } + + if (Location.empty()) { // Relative path. + if (Dir.empty()) + Location = "."; + else + Location = ".\\"; + } + + return Location.append(Dir); } } // namespace fuzzer