diff --git a/Common/StringUtil.cpp b/Common/StringUtil.cpp index c573749c..0e7f2072 100644 --- a/Common/StringUtil.cpp +++ b/Common/StringUtil.cpp @@ -75,4 +75,20 @@ void EscapeRegExp(std::wstring& str) } } +/* +** Escapes reserved URL characters. +*/ +void EscapeUrl(std::wstring& str) +{ + size_t pos = 0; + while ((pos = str.find_first_of(L" !*'();:@&=+$,/?#[]", pos)) != std::wstring::npos) + { + WCHAR buffer[3]; + _snwprintf_s(buffer, _countof(buffer), L"%.2X", str[pos]); + str[pos] = L'%'; + str.insert(pos + 1, buffer); + pos += 3; + } +} + } // namespace StringUtil diff --git a/Common/StringUtil.h b/Common/StringUtil.h index 764063d0..b0178008 100644 --- a/Common/StringUtil.h +++ b/Common/StringUtil.h @@ -38,6 +38,8 @@ inline std::wstring WidenUTF8(const std::string& str) { return Widen(str.c_str() void EscapeRegExp(std::wstring& str); +void EscapeUrl(std::wstring& str); + } // namespace StringUtil #endif diff --git a/Common/StringUtil_Test.cpp b/Common/StringUtil_Test.cpp index 835b839c..16dcbee3 100644 --- a/Common/StringUtil_Test.cpp +++ b/Common/StringUtil_Test.cpp @@ -46,6 +46,13 @@ public: EscapeRegExp(str); Assert::AreEqual(L"\\\\\\^\\$\\|\\(test\\)\\[\\{\\. ing\\+\\*\\?", str.c_str()); } + + TEST_METHOD(TestEscapeUrl) + { + std::wstring str = L" !*'();:@test&=+$,/?#[ing]"; + EscapeUrl(str); + Assert::AreEqual(L"%20%21%2A%27%28%29%3B%3A%40test%26%3D%2B%24%2C%2F%3F%23%5Bing%5D", str.c_str()); + } }; } // namespace StringUtil diff --git a/Library/ConfigParser.cpp b/Library/ConfigParser.cpp index 961f62d5..819e42e2 100644 --- a/Library/ConfigParser.cpp +++ b/Library/ConfigParser.cpp @@ -237,7 +237,8 @@ bool ConfigParser::GetSectionVariable(std::wstring& strVariable, std::wstring& s Percentual, Max, Min, - EscapeRegExp + EscapeRegExp, + EscapeUrl } valueType = ValueType::Raw; if (isKeySelector) @@ -254,6 +255,10 @@ bool ConfigParser::GetSectionVariable(std::wstring& strVariable, std::wstring& s { valueType = ValueType::EscapeRegExp; } + else if (_wcsicmp(selectorSz, L"EscapeUrl") == 0) + { + valueType = ValueType::EscapeUrl; + } else { return false; @@ -299,6 +304,12 @@ bool ConfigParser::GetSectionVariable(std::wstring& strVariable, std::wstring& s StringUtil::EscapeRegExp(strValue); return true; } + else if (valueType == ValueType::EscapeUrl) + { + strValue = measure->GetStringValue(); + StringUtil::EscapeUrl(strValue); + return true; + } int scale = 1;