Browse Source

Moved url_decode to utils and refactored it

Paul-Louis Ageneau 3 years ago
parent
commit
68ef078a52
3 changed files with 39 additions and 22 deletions
  1. 6 22
      src/configuration.cpp
  2. 29 0
      src/impl/utils.cpp
  3. 4 0
      src/impl/utils.hpp

+ 6 - 22
src/configuration.cpp

@@ -18,12 +18,11 @@
 
 
 #include "configuration.hpp"
 #include "configuration.hpp"
 
 
+#include "impl/utils.hpp"
+
 #include <cassert>
 #include <cassert>
 #include <regex>
 #include <regex>
 
 
-#include <iostream>
-#include <sstream>
-
 namespace {
 namespace {
 
 
 bool parse_url(const std::string &url, std::vector<std::optional<std::string>> &result) {
 bool parse_url(const std::string &url, std::vector<std::optional<std::string>> &result) {
@@ -45,27 +44,12 @@ bool parse_url(const std::string &url, std::vector<std::optional<std::string>> &
 	return true;
 	return true;
 }
 }
 
 
-std::string url_decode(const std::string &str) {
-	static const std::regex r(R"(%[0-9A-Fa-f]{2})", std::regex::extended);
-
-	std::stringstream ss;
-	std::smatch m;
-	for (size_t i = 0; i < str.length(); ++i) {
-		std::string substr = str.substr(i, 3);
-		if (std::regex_match(substr, m, r)) {
-			ss << static_cast<char>(std::stoi("0x" + substr.substr(1, 2), nullptr, 16));
-			i += 2;
-		} else {
-			ss << str[i];
-		}
-	}
-	return ss.str();
-}
-
 } // namespace
 } // namespace
 
 
 namespace rtc {
 namespace rtc {
 
 
+namespace utils = impl::utils;
+
 IceServer::IceServer(const string &url) {
 IceServer::IceServer(const string &url) {
 	std::vector<optional<string>> opt;
 	std::vector<optional<string>> opt;
 	if (!parse_url(url, opt))
 	if (!parse_url(url, opt))
@@ -92,8 +76,8 @@ IceServer::IceServer(const string &url) {
 			relayType = RelayType::TurnTls;
 			relayType = RelayType::TurnTls;
 	}
 	}
 
 
-	username = url_decode(opt[6].value_or(""));
-	password = url_decode(opt[8].value_or(""));
+	username = utils::url_decode(opt[6].value_or(""));
+	password = utils::url_decode(opt[8].value_or(""));
 
 
 	hostname = opt[10].value();
 	hostname = opt[10].value();
 	while (!hostname.empty() && hostname.front() == '[')
 	while (!hostname.empty() && hostname.front() == '[')

+ 29 - 0
src/impl/utils.cpp

@@ -18,6 +18,10 @@
 
 
 #include "utils.hpp"
 #include "utils.hpp"
 
 
+#include "impl/internals.hpp"
+
+#include <cctype>
+#include <functional>
 #include <iterator>
 #include <iterator>
 #include <sstream>
 #include <sstream>
 
 
@@ -44,4 +48,29 @@ string implode(const std::vector<string> &tokens, char delim) {
 	return result;
 	return result;
 }
 }
 
 
+string url_decode(const string &str) {
+	string result;
+	size_t i = 0;
+	while (i < str.size()) {
+		char c = str[i++];
+		if (c == '%') {
+			auto value = str.substr(i, 2);
+			try {
+				if (value.size() != 2 || !std::isxdigit(value[0]) || !std::isxdigit(value[1]))
+					throw std::exception();
+
+				c = static_cast<char>(std::stoi(value, nullptr, 16));
+				i += 2;
+
+			} catch (...) {
+				PLOG_WARNING << "Invalid percent-encoded character in URL: \"%" + value + "\"";
+			}
+		}
+
+		result.push_back(c);
+	}
+
+	return result;
+}
+
 } // namespace rtc::impl::utils
 } // namespace rtc::impl::utils

+ 4 - 0
src/impl/utils.hpp

@@ -28,6 +28,10 @@ namespace rtc::impl::utils {
 std::vector<string> explode(const string &str, char delim);
 std::vector<string> explode(const string &str, char delim);
 string implode(const std::vector<string> &tokens, char delim);
 string implode(const std::vector<string> &tokens, char delim);
 
 
+// Decode URL percent-encoding (RFC 3986)
+// See https://www.rfc-editor.org/rfc/rfc3986.html#section-2.1
+string url_decode(const string &str);
+
 } // namespace rtc::impl
 } // namespace rtc::impl
 
 
 #endif
 #endif