From 0a903e69fbd9b19d8d8da0593f31dec5807af566 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 29 Aug 2013 05:56:48 +0200 Subject: Implement urlencode and urldecode --- src/util/string.cpp | 43 ++++++++++++++++++++++++++++++++++++++----- src/util/string.h | 3 ++- 2 files changed, 40 insertions(+), 6 deletions(-) (limited to 'src/util') diff --git a/src/util/string.cpp b/src/util/string.cpp index 39a14598b..925d0ea35 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -21,8 +21,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "pointer.h" #include "numeric.h" +#include +#include + #include "../sha1.h" #include "../base64.h" +#include "../hex.h" #include "../porting.h" std::wstring narrow_to_wide(const std::string& mbs) @@ -68,11 +72,40 @@ std::string translatePassword(std::string playername, std::wstring password) return pwd; } -size_t curl_write_data(char *ptr, size_t size, size_t nmemb, void *userdata) { - std::ostringstream *stream = (std::ostringstream*)userdata; - size_t count = size * nmemb; - stream->write(ptr, count); - return count; +std::string urlencode(std::string str) +{ + // Encodes non-unreserved URI characters by a percent sign + // followed by two hex digits. See RFC 3986, section 2.3. + static const char url_hex_chars[] = "0123456789ABCDEF"; + std::ostringstream oss(std::ios::binary); + for (u32 i = 0; i < str.size(); i++) { + unsigned char c = str[i]; + if (isalnum(c) || c == '-' || c == '.' || c == '_' || c == '~') + oss << c; + else + oss << "%" + << url_hex_chars[(c & 0xf0) >> 4] + << url_hex_chars[c & 0x0f]; + } + return oss.str(); +} + +std::string urldecode(std::string str) +{ + // Inverse of urlencode + std::ostringstream oss(std::ios::binary); + for (u32 i = 0; i < str.size(); i++) { + unsigned char highvalue, lowvalue; + if (str[i] == '%' && + hex_digit_decode(str[i+1], highvalue) && + hex_digit_decode(str[i+2], lowvalue)) { + oss << (char) ((highvalue << 4) | lowvalue); + i += 2; + } + else + oss << str[i]; + } + return oss.str(); } u32 readFlagString(std::string str, FlagDesc *flagdesc) { diff --git a/src/util/string.h b/src/util/string.h index 81855962f..e5a60bc47 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -317,7 +317,8 @@ inline std::string unescape_string(std::string &s) } std::string translatePassword(std::string playername, std::wstring password); -size_t curl_write_data(char *ptr, size_t size, size_t nmemb, void *userdata); +std::string urlencode(std::string str); +std::string urldecode(std::string str); u32 readFlagString(std::string str, FlagDesc *flagdesc); std::string writeFlagString(u32 flags, FlagDesc *flagdesc); char *mystrtok_r(char *s, const char *sep, char **lasts); -- cgit v1.2.3