From 5d75ee63b6bb47ddd41673ec9d857aebcc401240 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Tue, 4 Aug 2015 18:54:35 -0700 Subject: [PATCH 1/2] Sanitize ProjectPath --- hecl/include/HECL/HECL.hpp | 17 ++++++++++++----- hecl/lib/HECL.cpp | 26 ++++++++++++++++++++++++++ hecl/lib/ProjectPath.cpp | 15 ++++++++++++--- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/hecl/include/HECL/HECL.hpp b/hecl/include/HECL/HECL.hpp index 1906f9d5e..c3d702d19 100644 --- a/hecl/include/HECL/HECL.hpp +++ b/hecl/include/HECL/HECL.hpp @@ -122,6 +122,10 @@ inline std::string operator+(const char* lhs, const SystemStringView& rhs) {retu typedef struct stat Sstat; #endif + +void SanitizePath(std::string& path); +void SanitizePath(std::wstring& path); + static inline void MakeDir(const SystemChar* dir) { #if _WIN32 @@ -386,8 +390,12 @@ protected: std::string m_utf8RelPath; #endif ProjectPath(const SystemString& projRoot) - : m_projRoot(projRoot), m_absPath(projRoot), m_relPath(_S(".")), m_hash(m_relPath) + : m_projRoot(projRoot), m_absPath(projRoot), m_relPath(_S(".")) { + SanitizePath(m_projRoot); + SanitizePath(m_relPath); + SanitizePath(m_absPath); + m_hash = Hash(m_relPath); #if HECL_UCS2 m_utf8AbsPath = WideToUTF8(m_absPath); m_utf8RelPath = "."; @@ -411,10 +419,10 @@ public: * @param parentPath previously constructed ProjectPath which ultimately connects to a ProjectRootPath * @param path valid filesystem-path (relative or absolute) to subpath */ - ProjectPath(const ProjectPath& parentPath, const SystemString& path) {assign(parentPath, path);} - void assign(const ProjectPath& parentPath, const SystemString& path); +/* ProjectPath(const ProjectPath& parentPath, const SystemString& path) {assign(parentPath, path);} + void assign(const ProjectPath& parentPath, const SystemString& path);*/ -#if HECL_UCS2 +#ifndef HECL_UCS2 ProjectPath(const ProjectPath& parentPath, const std::string& path) {assign(parentPath, path);} void assign(const ProjectPath& parentPath, const std::string& path); #endif @@ -532,7 +540,6 @@ public: relTarget += target.m_relPath; MakeLink(relTarget.c_str(), m_absPath.c_str()); } - /** * @brief HECL-specific blowfish hash * @return unique hash value diff --git a/hecl/lib/HECL.cpp b/hecl/lib/HECL.cpp index b15add036..5efa8915b 100644 --- a/hecl/lib/HECL.cpp +++ b/hecl/lib/HECL.cpp @@ -3,4 +3,30 @@ namespace HECL { LogVisor::LogModule LogModule("HECL"); + +template +inline void replaceAll(T& str, const T& from, const T& to) +{ + size_t start_pos = 0; + while((start_pos = str.find(from, start_pos)) != std::string::npos) + { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); // Handles case where 'to' is a substring of 'from' + } +} + +void SanitizePath(std::string& path) +{ + path.erase(std::remove(path.begin(), path.end(), '\n'), path.end()); + path.erase(std::remove(path.begin(), path.end(), '\r'), path.end()); + replaceAll(path, "<>:\"|?*", "_"); +} + +void SanitizePath(std::wstring& path) +{ + path.erase(std::remove(path.begin(), path.end(), L'\n'), path.end()); + path.erase(std::remove(path.begin(), path.end(), L'\r'), path.end()); + replaceAll(path, L"<>:\"|?*", L"_"); +} + } diff --git a/hecl/lib/ProjectPath.cpp b/hecl/lib/ProjectPath.cpp index 054fe091f..5c4d823e1 100644 --- a/hecl/lib/ProjectPath.cpp +++ b/hecl/lib/ProjectPath.cpp @@ -3,7 +3,6 @@ namespace HECL { - static const SystemRegex regGLOB(_S("\\*"), SystemRegex::ECMAScript|SystemRegex::optimize); static const SystemRegex regPATHCOMP(_S("[/\\\\]*([^/\\\\]+)"), SystemRegex::ECMAScript|SystemRegex::optimize); static const SystemRegex regDRIVELETTER(_S("^([^/]*)/"), SystemRegex::ECMAScript|SystemRegex::optimize); @@ -21,6 +20,7 @@ static SystemString canonRelPath(const SystemString& path) std::vector comps; HECL::SystemRegexMatch matches; SystemString in = path; + SanitizePath(in); for (; std::regex_search(in, matches, regPATHCOMP) ; in = matches.suffix()) { const SystemString& match = matches[1]; @@ -57,10 +57,15 @@ static SystemString canonRelPath(const SystemString& path) void ProjectPath::assign(const ProjectPath& parentPath, const SystemString& path) { + SystemString in = path; m_projRoot = parentPath.m_projRoot; - m_relPath = canonRelPath(parentPath.m_relPath + _S('/') + path); + m_relPath = canonRelPath(parentPath.m_relPath + _S('/') + in); m_absPath = parentPath.m_projRoot + _S('/') + m_relPath; + SanitizePath(m_projRoot); + SanitizePath(m_relPath); + SanitizePath(m_absPath); m_hash = Hash(m_relPath); + #if HECL_UCS2 m_utf8AbsPath = WideToUTF8(m_absPath); m_utf8RelPath = WideToUTF8(m_relPath); @@ -70,10 +75,14 @@ void ProjectPath::assign(const ProjectPath& parentPath, const SystemString& path #if HECL_UCS2 void ProjectPath::assign(const ProjectPath& parentPath, const std::string& path) { + std::string in = path; m_projRoot = parentPath.m_projRoot; - std::wstring wpath = UTF8ToWide(path); + std::wstring wpath = UTF8ToWide(in); m_relPath = canonRelPath(parentPath.m_relPath + _S('/') + wpath); m_absPath = parentPath.m_projRoot + _S('/') + m_relPath; + SanitizePath(m_projRoot); + SanitizePath(m_relPath); + SanitizePath(m_absPath); m_hash = Hash(m_relPath); m_utf8AbsPath = WideToUTF8(m_absPath); m_utf8RelPath = WideToUTF8(m_relPath); From 3cc0382a26de7e03d9e90c8164ed7efceec24d8e Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Tue, 4 Aug 2015 19:40:54 -0700 Subject: [PATCH 2/2] Fix path sanitization --- hecl/lib/HECL.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/hecl/lib/HECL.cpp b/hecl/lib/HECL.cpp index 5efa8915b..de0cf9379 100644 --- a/hecl/lib/HECL.cpp +++ b/hecl/lib/HECL.cpp @@ -4,29 +4,28 @@ namespace HECL { LogVisor::LogModule LogModule("HECL"); -template -inline void replaceAll(T& str, const T& from, const T& to) -{ - size_t start_pos = 0; - while((start_pos = str.find(from, start_pos)) != std::string::npos) - { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); // Handles case where 'to' is a substring of 'from' - } -} - void SanitizePath(std::string& path) { path.erase(std::remove(path.begin(), path.end(), '\n'), path.end()); path.erase(std::remove(path.begin(), path.end(), '\r'), path.end()); - replaceAll(path, "<>:\"|?*", "_"); + std::transform(path.begin(), path.end(), path.begin(), [](const char a) -> char { + static const std::string illegals {"<>?*\"|"}; + if (illegals.find_first_of(a) != std::string::npos) + return '_'; + return a; + }); } void SanitizePath(std::wstring& path) { path.erase(std::remove(path.begin(), path.end(), L'\n'), path.end()); path.erase(std::remove(path.begin(), path.end(), L'\r'), path.end()); - replaceAll(path, L"<>:\"|?*", L"_"); + std::transform(path.begin(), path.end(), path.begin(), [](const wchar_t a) -> wchar_t { + static const std::wstring illegals {L"<>?*\"|"}; + if (illegals.find_first_of(a) != std::wstring::npos) + return L'_'; + return a; + }); } }