diff options
-rw-r--r-- | Source/kwsys/SystemTools.cxx | 38 | ||||
-rw-r--r-- | Source/kwsys/SystemTools.hxx.in | 14 | ||||
-rw-r--r-- | Source/kwsys/Terminal.c | 1 | ||||
-rw-r--r-- | Source/kwsys/testSystemTools.cxx | 30 |
4 files changed, 77 insertions, 6 deletions
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index d27081b..f11eff7 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -123,9 +123,9 @@ extern char** environ; #define VTK_URL_PROTOCOL_REGEX "([a-zA-Z0-9]*)://(.*)" #define VTK_URL_REGEX \ - "([a-zA-Z0-9]*)://(([A-Za-z0-9]+)(:([^:@]+))?@)?([^:@/]+)(:([0-9]+))?/" \ + "([a-zA-Z0-9]*)://(([A-Za-z0-9]+)(:([^:@]+))?@)?([^:@/]*)(:([0-9]+))?/" \ "(.+)?" - +#define VTK_URL_BYTE_REGEX "%[0-9a-fA-F][0-9a-fA-F]" #ifdef _MSC_VER # include <sys/utime.h> #else @@ -4516,7 +4516,7 @@ std::string SystemTools::GetOperatingSystemNameAndVersion() bool SystemTools::ParseURLProtocol(const std::string& URL, std::string& protocol, - std::string& dataglom) + std::string& dataglom, bool decode) { // match 0 entire url // match 1 protocol @@ -4529,13 +4529,17 @@ bool SystemTools::ParseURLProtocol(const std::string& URL, protocol = urlRe.match(1); dataglom = urlRe.match(2); + if (decode) { + dataglom = DecodeURL(dataglom); + } + return true; } bool SystemTools::ParseURL(const std::string& URL, std::string& protocol, std::string& username, std::string& password, std::string& hostname, std::string& dataport, - std::string& database) + std::string& database, bool decode) { kwsys::RegularExpression urlRe(VTK_URL_REGEX); if (!urlRe.find(URL)) @@ -4559,9 +4563,35 @@ bool SystemTools::ParseURL(const std::string& URL, std::string& protocol, dataport = urlRe.match(8); database = urlRe.match(9); + if (decode) { + username = DecodeURL(username); + password = DecodeURL(password); + hostname = DecodeURL(hostname); + dataport = DecodeURL(dataport); + database = DecodeURL(database); + } + return true; } +// ---------------------------------------------------------------------- +std::string SystemTools::DecodeURL(const std::string& url) +{ + kwsys::RegularExpression urlByteRe(VTK_URL_BYTE_REGEX); + std::string ret; + for (size_t i = 0; i < url.length(); i++) { + if (urlByteRe.find(url.substr(i, 3))) { + ret += + static_cast<char>(strtoul(url.substr(i + 1, 2).c_str(), nullptr, 16)); + i += 2; + } else { + ret += url[i]; + } + } + return ret; +} + +// ---------------------------------------------------------------------- // These must NOT be initialized. Default initialization to zero is // necessary. static unsigned int SystemToolsManagerCount; diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index c4ab9d4..d4a93fa 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -935,22 +935,32 @@ public: * Parse a character string : * protocol://dataglom * and fill protocol as appropriate. + * decode the dataglom using DecodeURL if set to true. * Return false if the URL does not have the required form, true otherwise. */ static bool ParseURLProtocol(const std::string& URL, std::string& protocol, - std::string& dataglom); + std::string& dataglom, bool decode = false); /** * Parse a string (a URL without protocol prefix) with the form: * protocol://[[username[':'password]'@']hostname[':'dataport]]'/'[datapath] * and fill protocol, username, password, hostname, dataport, and datapath * when values are found. + * decode all string except the protocol using DecodeUrl if set to true. * Return true if the string matches the format; false otherwise. */ static bool ParseURL(const std::string& URL, std::string& protocol, std::string& username, std::string& password, std::string& hostname, std::string& dataport, - std::string& datapath); + std::string& datapath, bool decode = false); + + /** + * Decode the percent-encoded string from an URL or an URI + * into their correct char values. + * Does not perform any other sort of validation. + * Return the decoded string + */ + static std::string DecodeURL(const std::string& url); private: /** diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c index c9515ee..4d1b46c 100644 --- a/Source/kwsys/Terminal.c +++ b/Source/kwsys/Terminal.c @@ -146,6 +146,7 @@ static const char* kwsysTerminalVT100Names[] = { "Eterm", "screen-bce", "screen-w", "screen.linux", + "st-256color", "tmux", "tmux-256color", "vt100", diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index 3f6eeb8..6afc326 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -1086,6 +1086,34 @@ static bool CheckCopyFileIfDifferent() return ret; } +static bool CheckURLParsing() +{ + bool ret = true; + std::string url = "http://user:pw@hostname:42/full/url.com"; + + std::string protocol, username, password, hostname, dataport, database; + kwsys::SystemTools::ParseURL(url, protocol, username, password, hostname, + dataport, database); + if (protocol != "http" || username != "user" || password != "pw" || + hostname != "hostname" || dataport != "42" || + database != "full/url.com") { + std::cerr << "Incorrect URL parsing" << std::endl; + ret = false; + } + + std::string uri = + "file://hostname/path/to/" + "a%20file%20with%20str%C3%A0ng%C3%A8%20ch%40r%20and%20s%C2%B5aces"; + kwsys::SystemTools::ParseURL(uri, protocol, username, password, hostname, + dataport, database, true); + if (protocol != "file" || hostname != "hostname" || + database != "path/to/a file with stràngè ch@r and sµaces") { + std::cerr << "Incorrect URL parsing or decoding" << std::endl; + ret = false; + } + return ret; +} + int testSystemTools(int, char* []) { bool res = true; @@ -1133,5 +1161,7 @@ int testSystemTools(int, char* []) res &= CheckCopyFileIfDifferent(); + res &= CheckURLParsing(); + return res ? 0 : 1; } |