# HG changeset patch # User Sebastien Jodogne # Date 1358110211 -3600 # Node ID 3c291753231f634d5dba214288978b28f8fcdef8 # Parent daff912c9ffe377f5951f46b01ec94c703e56863 url decode diff -r daff912c9ffe -r 3c291753231f Core/HttpServer/HttpHandler.cpp --- a/Core/HttpServer/HttpHandler.cpp Fri Jan 11 14:54:39 2013 +0100 +++ b/Core/HttpServer/HttpHandler.cpp Sun Jan 13 21:50:11 2013 +0100 @@ -54,6 +54,9 @@ value = std::string(equal + 1, end); } + Toolbox::UrlDecode(name); + Toolbox::UrlDecode(value); + result.insert(std::make_pair(name, value)); } diff -r daff912c9ffe -r 3c291753231f Core/Toolbox.cpp --- a/Core/Toolbox.cpp Fri Jan 11 14:54:39 2013 +0100 +++ b/Core/Toolbox.cpp Sun Jan 13 21:50:11 2013 +0100 @@ -592,4 +592,51 @@ assert(first <= last); return source.substr(first, last - first); } + + + static uint8_t Hex2Dec(char c) + { + return ((c >= '0' && c <= '9') ? c - '0' : + ((c >= 'a' && c <= 'f') ? c - 'a' + 10 : c - 'A' + 10)); + } + + void Toolbox::UrlDecode(std::string& s) + { + // http://en.wikipedia.org/wiki/Percent-encoding + // http://www.w3schools.com/tags/ref_urlencode.asp + // http://stackoverflow.com/questions/154536/encode-decode-urls-in-c + + if (s.size() == 0) + { + return; + } + + size_t source = 0; + size_t target = 0; + + while (source < s.size()) + { + if (s[source] == '%' && + source + 2 < s.size() && + isalnum(s[source + 1]) && + isalnum(s[source + 2])) + { + s[target] = (Hex2Dec(s[source + 1]) << 4) | Hex2Dec(s[source + 2]); + source += 3; + target += 1; + } + else + { + if (s[source] == '+') + s[target] = ' '; + else + s[target] = s[source]; + + source++; + target++; + } + } + + s.resize(target); + } } diff -r daff912c9ffe -r 3c291753231f Core/Toolbox.h --- a/Core/Toolbox.h Fri Jan 11 14:54:39 2013 +0100 +++ b/Core/Toolbox.h Sun Jan 13 21:50:11 2013 +0100 @@ -94,5 +94,8 @@ std::string StripSpaces(const std::string& source); std::string GetNowIsoString(); + + // In-place percent-decoding for URL + void UrlDecode(std::string& s); } } diff -r daff912c9ffe -r 3c291753231f UnitTests/main.cpp --- a/UnitTests/main.cpp Fri Jan 11 14:54:39 2013 +0100 +++ b/UnitTests/main.cpp Sun Jan 13 21:50:11 2013 +0100 @@ -297,6 +297,23 @@ ASSERT_EQ(0x00, static_cast(utf8[14])); // Null-terminated string } +TEST(Toolbox, UrlDecode) +{ + std::string s; + + s = "Hello%20World"; + Toolbox::UrlDecode(s); + ASSERT_EQ("Hello World", s); + + s = "%21%23%24%26%27%28%29%2A%2B%2c%2f%3A%3b%3d%3f%40%5B%5D"; + Toolbox::UrlDecode(s); + ASSERT_EQ("!#$&'()*+,/:;=?@[]", s); + + s = "(2000%2C00A4)+Other"; + Toolbox::UrlDecode(s); + ASSERT_EQ("(2000,00A4) Other", s); +} + int main(int argc, char **argv) {