From c047d7a581ab090177d92c631a7615c27e0ab265 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 19 Apr 2015 22:12:05 +0300 Subject: [PATCH] Replace url parser with one less strict --- code/nel/include/nel/gui/url_parser.h | 63 ++++++++ code/nel/src/gui/group_html.cpp | 17 +- code/nel/src/gui/url_parser.cpp | 222 ++++++++++++++++++++++++++ 3 files changed, 290 insertions(+), 12 deletions(-) create mode 100644 code/nel/include/nel/gui/url_parser.h create mode 100644 code/nel/src/gui/url_parser.cpp diff --git a/code/nel/include/nel/gui/url_parser.h b/code/nel/include/nel/gui/url_parser.h new file mode 100644 index 000000000..b47e67b37 --- /dev/null +++ b/code/nel/include/nel/gui/url_parser.h @@ -0,0 +1,63 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CL_URL_PARSER_H +#define CL_URL_PARSER_H + +#include + +namespace NLGUI +{ + /** + * Simple URL parser + * \author Meelis Mägi + * \date 2015 + */ + class CUrlParser + { + public: + CUrlParser(){} + + // parse uri to components + CUrlParser(const std::string &url); + + // parse uri to components + void parse(std::string uri); + + // serialize URL back to string + std::string toString() const; + + // inherit scheme, domain, path from given url + void inherit(const std::string &url); + + // if current parts can compose absolute url or not + bool isAbsolute() const; + + // resolve relative path like './a/../b' to absolute path '/a/b' + static void resolveRelativePath(std::string &path); + + public: + std::string scheme; + std::string domain; + std::string path; + std::string query; + std::string hash; + }; + +}// namespace + +#endif // CL_URL_PARSER_H + diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index ae1975789..0ec026a1a 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -43,7 +43,7 @@ #include "nel/misc/md5.h" #include "nel/3d/texture_file.h" #include "nel/misc/big_file.h" -#include +#include "nel/gui/url_parser.h" using namespace std; using namespace NLMISC; @@ -4777,20 +4777,13 @@ namespace NLGUI // *************************************************************************** std::string CGroupHTML::getAbsoluteUrl(const std::string &url) { - if (_URL.size() == 0 || url.find("http://") != std::string::npos || url.find("https://") != std::string::npos) + CUrlParser uri(url); + if (uri.isAbsolute()) return url; - xmlChar * uri; - uri = xmlBuildURI(reinterpret_cast(url.c_str()), reinterpret_cast(_URL.c_str())); - if (uri) - { - std::string ret(reinterpret_cast(uri)); - xmlFree(uri); + uri.inherit(_URL); - return ret; - } - - return url; + return uri.toString(); } // *************************************************************************** diff --git a/code/nel/src/gui/url_parser.cpp b/code/nel/src/gui/url_parser.cpp new file mode 100644 index 000000000..68d4f8496 --- /dev/null +++ b/code/nel/src/gui/url_parser.cpp @@ -0,0 +1,222 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include "nel/misc/types_nl.h" +#include "nel/gui/url_parser.h" + +using namespace std; + + +namespace NLGUI +{ + // *************************************************************************** + CUrlParser::CUrlParser(const std::string &uri) + { + parse(uri); + } + + // *************************************************************************** + void CUrlParser::parse(std::string uri) + { + const size_t npos = std::string::npos; + size_t pos; + size_t offset = 0; + + // strip fragment if present + pos = uri.find("#"); + if (pos != npos) + { + hash = uri.substr(pos + 1); + uri = uri.substr(0, pos); + } + + // scan for scheme + pos = uri.find(":"); + if (pos != npos && pos >= 1) + { + for (uint i=0; i 0) + { + // full or last segment + sub = path.substr(pos-1, 4); + if (sub == "/../" || sub == "/..") + { + if (pos > 1) + lhp = path.find_last_of("/", pos - 2); + else + lhp = 0; + + // pos points to first dot in .. + // lhp points to start slash (/) of last segment + pos += sub.size() - 1; + path.replace(lhp, pos - lhp, "/"); + pos = lhp; + } + } + }// sub == ".." + } // path[pos] == '.' + pos++; + }// while + } + + bool CUrlParser::isAbsolute() const + { + return !scheme.empty() && !domain.empty(); + } + + // serialize URL back to string + std::string CUrlParser::toString() const + { + std::string result; + if (!scheme.empty()) + result += scheme + ":"; + + if (!domain.empty()) + { + result += domain; + } + + // path already has leading slash + if (!path.empty()) + result += path; + + if (!query.empty()) + result += "?" + query; + + if (!hash.empty()) + result += "#" + hash; + + return result; + } + +}// namespace +