diff options
Diffstat (limited to 'chromium/third_party/webrtc/base/urlencode.cc')
-rw-r--r-- | chromium/third_party/webrtc/base/urlencode.cc | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/chromium/third_party/webrtc/base/urlencode.cc b/chromium/third_party/webrtc/base/urlencode.cc new file mode 100644 index 00000000000..b152829ae83 --- /dev/null +++ b/chromium/third_party/webrtc/base/urlencode.cc @@ -0,0 +1,183 @@ +/* + * Copyright 2008 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/base/urlencode.h" + +#include "webrtc/base/common.h" +#include "webrtc/base/stringutils.h" + +static int HexPairValue(const char * code) { + int value = 0; + const char * pch = code; + for (;;) { + int digit = *pch++; + if (digit >= '0' && digit <= '9') { + value += digit - '0'; + } + else if (digit >= 'A' && digit <= 'F') { + value += digit - 'A' + 10; + } + else if (digit >= 'a' && digit <= 'f') { + value += digit - 'a' + 10; + } + else { + return -1; + } + if (pch == code + 2) + return value; + value <<= 4; + } +} + +static int InternalUrlDecode(const char *source, char *dest, + bool encode_space_as_plus) { + char * start = dest; + + while (*source) { + switch (*source) { + case '+': + if (encode_space_as_plus) { + *(dest++) = ' '; + } else { + *dest++ = *source; + } + break; + case '%': + if (source[1] && source[2]) { + int value = HexPairValue(source + 1); + if (value >= 0) { + *(dest++) = value; + source += 2; + } + else { + *dest++ = '?'; + } + } + else { + *dest++ = '?'; + } + break; + default: + *dest++ = *source; + } + source++; + } + + *dest = 0; + return static_cast<int>(dest - start); +} + +static bool IsValidUrlChar(char ch, bool unsafe_only) { + if (unsafe_only) { + return !(ch <= ' ' || strchr("\\\"^&`<>[]{}", ch)); + } else { + return isalnum(ch) || strchr("-_.!~*'()", ch); + } +} + +namespace rtc { + +int UrlDecode(const char *source, char *dest) { + return InternalUrlDecode(source, dest, true); +} + +int UrlDecodeWithoutEncodingSpaceAsPlus(const char *source, char *dest) { + return InternalUrlDecode(source, dest, false); +} + +int InternalUrlEncode(const char *source, char *dest, unsigned int max, + bool encode_space_as_plus, bool unsafe_only) { + static const char *digits = "0123456789ABCDEF"; + if (max == 0) { + return 0; + } + + char *start = dest; + while (static_cast<unsigned>(dest - start) < max && *source) { + unsigned char ch = static_cast<unsigned char>(*source); + if (*source == ' ' && encode_space_as_plus && !unsafe_only) { + *dest++ = '+'; + } else if (IsValidUrlChar(ch, unsafe_only)) { + *dest++ = *source; + } else { + if (static_cast<unsigned>(dest - start) + 4 > max) { + break; + } + *dest++ = '%'; + *dest++ = digits[(ch >> 4) & 0x0F]; + *dest++ = digits[ ch & 0x0F]; + } + source++; + } + ASSERT(static_cast<unsigned int>(dest - start) < max); + *dest = 0; + + return static_cast<int>(dest - start); +} + +int UrlEncode(const char *source, char *dest, unsigned max) { + return InternalUrlEncode(source, dest, max, true, false); +} + +int UrlEncodeWithoutEncodingSpaceAsPlus(const char *source, char *dest, + unsigned max) { + return InternalUrlEncode(source, dest, max, false, false); +} + +int UrlEncodeOnlyUnsafeChars(const char *source, char *dest, unsigned max) { + return InternalUrlEncode(source, dest, max, false, true); +} + +std::string +InternalUrlDecodeString(const std::string & encoded, + bool encode_space_as_plus) { + size_t needed_length = encoded.length() + 1; + char* buf = STACK_ARRAY(char, needed_length); + InternalUrlDecode(encoded.c_str(), buf, encode_space_as_plus); + return buf; +} + +std::string +UrlDecodeString(const std::string & encoded) { + return InternalUrlDecodeString(encoded, true); +} + +std::string +UrlDecodeStringWithoutEncodingSpaceAsPlus(const std::string & encoded) { + return InternalUrlDecodeString(encoded, false); +} + +std::string +InternalUrlEncodeString(const std::string & decoded, + bool encode_space_as_plus, + bool unsafe_only) { + int needed_length = static_cast<int>(decoded.length()) * 3 + 1; + char* buf = STACK_ARRAY(char, needed_length); + InternalUrlEncode(decoded.c_str(), buf, needed_length, + encode_space_as_plus, unsafe_only); + return buf; +} + +std::string +UrlEncodeString(const std::string & decoded) { + return InternalUrlEncodeString(decoded, true, false); +} + +std::string +UrlEncodeStringWithoutEncodingSpaceAsPlus(const std::string & decoded) { + return InternalUrlEncodeString(decoded, false, false); +} + +std::string +UrlEncodeStringForOnlyUnsafeChars(const std::string & decoded) { + return InternalUrlEncodeString(decoded, false, true); +} + +} // namespace rtc |