forked from premiere/premiere-libtorrent
refactor in escape_string and escape_path to use string_view (#1039)
This commit is contained in:
parent
9ac7475a90
commit
ebe53883b5
|
@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <string>
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
#include "libtorrent/string_view.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -56,9 +57,9 @@ namespace libtorrent
|
|||
// TODO: 3 this should probably take a string_ref
|
||||
TORRENT_EXTRA_EXPORT std::string unescape_string(std::string const& s, error_code& ec);
|
||||
// replaces all disallowed URL characters by their %-encoding
|
||||
TORRENT_EXTRA_EXPORT std::string escape_string(const char* str, int len);
|
||||
TORRENT_EXTRA_EXPORT std::string escape_string(string_view str);
|
||||
// same as escape_string but does not encode '/'
|
||||
TORRENT_EXTRA_EXPORT std::string escape_path(const char* str, int len);
|
||||
TORRENT_EXTRA_EXPORT std::string escape_path(string_view str);
|
||||
// if the url does not appear to be encoded, and it contains illegal url characters
|
||||
// it will be encoded
|
||||
TORRENT_EXTRA_EXPORT std::string maybe_url_encode(std::string const& url);
|
||||
|
@ -105,4 +106,3 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#endif // TORRENT_ESCAPE_STRING_HPP_INCLUDED
|
||||
|
||||
|
|
|
@ -37,8 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <cstring>
|
||||
#include <array>
|
||||
#include <tuple>
|
||||
|
||||
#ifdef TORRENT_WINDOWS
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
|
@ -54,7 +52,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "libtorrent/parse_url.hpp"
|
||||
#include "libtorrent/random.hpp"
|
||||
|
||||
#include "libtorrent/utf8.hpp"
|
||||
#include "libtorrent/aux_/escape_string.hpp"
|
||||
|
@ -146,12 +143,12 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(str != nullptr);
|
||||
TORRENT_ASSERT(len >= 0);
|
||||
TORRENT_ASSERT(offset >= 0);
|
||||
TORRENT_ASSERT(offset < int(sizeof(unreserved_chars))-1);
|
||||
TORRENT_ASSERT(offset < int(sizeof(unreserved_chars)) - 1);
|
||||
|
||||
std::string ret;
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
if (std::strchr(unreserved_chars+offset, *str) && *str != 0)
|
||||
if (std::strchr(unreserved_chars + offset, *str) && *str != 0)
|
||||
{
|
||||
ret += *str;
|
||||
}
|
||||
|
@ -168,14 +165,14 @@ namespace libtorrent
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
std::string escape_string(const char* str, int len)
|
||||
std::string escape_string(string_view str)
|
||||
{
|
||||
return escape_string_impl(str, len, 11);
|
||||
return escape_string_impl(str.data(), int(str.size()), 11);
|
||||
}
|
||||
|
||||
std::string escape_path(const char* str, int len)
|
||||
std::string escape_path(string_view str)
|
||||
{
|
||||
return escape_string_impl(str, len, 10);
|
||||
return escape_string_impl(str.data(), int(str.size()), 10);
|
||||
}
|
||||
|
||||
bool need_encoding(char const* str, int len)
|
||||
|
@ -238,7 +235,7 @@ namespace libtorrent
|
|||
, auth.empty()?"":"@", host.c_str()
|
||||
, port == -1 ? "" : ":"
|
||||
, port == -1 ? "" : to_string(port).data()
|
||||
, escape_path(path.c_str(), int(path.size())).c_str());
|
||||
, escape_path(path).c_str());
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
@ -619,4 +616,3 @@ namespace libtorrent
|
|||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ namespace libtorrent
|
|||
request += "GET ";
|
||||
request += using_proxy ? m_url : m_path;
|
||||
request += "?info_hash=";
|
||||
request += escape_string(reinterpret_cast<char const*>(&t->torrent_file().info_hash()[0]), 20);
|
||||
request += escape_string({t->torrent_file().info_hash().data(), 20});
|
||||
request += "&piece=";
|
||||
request += to_string(r.piece).data();
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ namespace libtorrent
|
|||
url += "?";
|
||||
|
||||
url += "info_hash=";
|
||||
url += escape_string(tracker_req().info_hash.data(), 20);
|
||||
url += escape_string({tracker_req().info_hash.data(), 20});
|
||||
|
||||
if (0 == (tracker_req().kind & tracker_request::scrape_request))
|
||||
{
|
||||
|
@ -129,7 +129,7 @@ namespace libtorrent
|
|||
"&numwant=%d"
|
||||
"&compact=1"
|
||||
"&no_peer_id=1"
|
||||
, escape_string(tracker_req().pid.data(), 20).c_str()
|
||||
, escape_string({tracker_req().pid.data(), 20}).c_str()
|
||||
// the i2p tracker seems to verify that the port is not 0,
|
||||
// even though it ignores it otherwise
|
||||
, i2p ? 1 : tracker_req().listen_port
|
||||
|
@ -154,9 +154,8 @@ namespace libtorrent
|
|||
}
|
||||
if (!tracker_req().trackerid.empty())
|
||||
{
|
||||
std::string id = tracker_req().trackerid;
|
||||
url += "&trackerid=";
|
||||
url += escape_string(id.c_str(), int(id.length()));
|
||||
url += escape_string(tracker_req().trackerid);
|
||||
}
|
||||
|
||||
#if TORRENT_USE_I2P
|
||||
|
@ -179,7 +178,7 @@ namespace libtorrent
|
|||
std::string announce_ip = settings.get_str(settings_pack::announce_ip);
|
||||
if (!announce_ip.empty())
|
||||
{
|
||||
url += "&ip=" + escape_string(announce_ip.c_str(), int(announce_ip.size()));
|
||||
url += "&ip=" + escape_string(announce_ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,22 +56,19 @@ namespace libtorrent
|
|||
if (!st.name.empty())
|
||||
{
|
||||
ret += "&dn=";
|
||||
ret += escape_string(st.name.c_str(), int(st.name.length()));
|
||||
ret += escape_string(st.name);
|
||||
}
|
||||
|
||||
std::vector<announce_entry> const& tr = handle.trackers();
|
||||
for (std::vector<announce_entry>::const_iterator i = tr.begin(), end(tr.end()); i != end; ++i)
|
||||
for (auto const& tr : handle.trackers())
|
||||
{
|
||||
ret += "&tr=";
|
||||
ret += escape_string(i->url.c_str(), int(i->url.length()));
|
||||
ret += escape_string(tr.url);
|
||||
}
|
||||
|
||||
std::set<std::string> seeds = handle.url_seeds();
|
||||
for (std::set<std::string>::iterator i = seeds.begin()
|
||||
, end(seeds.end()); i != end; ++i)
|
||||
for (auto const& s : handle.url_seeds())
|
||||
{
|
||||
ret += "&ws=";
|
||||
ret += escape_string(i->c_str(), int(i->length()));
|
||||
ret += escape_string(s);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -89,25 +86,21 @@ namespace libtorrent
|
|||
if (!name.empty())
|
||||
{
|
||||
ret += "&dn=";
|
||||
ret += escape_string(name.c_str(), int(name.length()));
|
||||
ret += escape_string(name);
|
||||
}
|
||||
|
||||
std::vector<announce_entry> const& tr = info.trackers();
|
||||
|
||||
for (std::vector<announce_entry>::const_iterator i = tr.begin(), end(tr.end()); i != end; ++i)
|
||||
for (auto const& tr : info.trackers())
|
||||
{
|
||||
ret += "&tr=";
|
||||
ret += escape_string(i->url.c_str(), int(i->url.length()));
|
||||
ret += escape_string(tr.url);
|
||||
}
|
||||
|
||||
std::vector<web_seed_entry> const& seeds = info.web_seeds();
|
||||
for (std::vector<web_seed_entry>::const_iterator i = seeds.begin()
|
||||
, end(seeds.end()); i != end; ++i)
|
||||
for (auto const& s : info.web_seeds())
|
||||
{
|
||||
if (i->type != web_seed_entry::url_seed) continue;
|
||||
if (s.type != web_seed_entry::url_seed) continue;
|
||||
|
||||
ret += "&ws=";
|
||||
ret += escape_string(i->url.c_str(), int(i->url.length()));
|
||||
ret += escape_string(s.url);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -115,8 +115,7 @@ web_peer_connection::web_peer_connection(peer_connection_args const& pack
|
|||
if (m_path.empty()) m_path += '/';
|
||||
if (m_path[m_path.size()-1] == '/')
|
||||
{
|
||||
std::string const& name = t->torrent_file().name();
|
||||
m_path += escape_string(name.c_str(), int(name.size()));
|
||||
m_path += escape_string(t->torrent_file().name());
|
||||
}
|
||||
|
||||
if (!m_url.empty() && m_url[m_url.size() - 1] == '/')
|
||||
|
@ -125,8 +124,7 @@ web_peer_connection::web_peer_connection(peer_connection_args const& pack
|
|||
#ifdef TORRENT_WINDOWS
|
||||
convert_path_to_posix(tmp);
|
||||
#endif
|
||||
tmp = escape_path(tmp.c_str(), int(tmp.size()));
|
||||
m_url += tmp;
|
||||
m_url += escape_path(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,7 +388,7 @@ void web_peer_connection::write_request(peer_request const& r)
|
|||
#ifdef TORRENT_WINDOWS
|
||||
convert_path_to_posix(path);
|
||||
#endif
|
||||
request += escape_path(path.c_str(), int(path.length()));
|
||||
request += escape_path(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -402,7 +400,7 @@ void web_peer_connection::write_request(peer_request const& r)
|
|||
#ifdef TORRENT_WINDOWS
|
||||
convert_path_to_posix(path);
|
||||
#endif
|
||||
request += escape_path(path.c_str(), int(path.length()));
|
||||
request += escape_path(path);
|
||||
}
|
||||
request += " HTTP/1.1\r\n";
|
||||
add_headers(request, m_settings, using_proxy);
|
||||
|
@ -609,7 +607,7 @@ void web_peer_connection::handle_redirect(int bytes_left)
|
|||
#ifdef TORRENT_WINDOWS
|
||||
convert_path_to_posix(path);
|
||||
#endif
|
||||
path = escape_path(path.c_str(), int(path.length()));
|
||||
path = escape_path(path);
|
||||
size_t i = location.rfind(path);
|
||||
if (i == std::string::npos)
|
||||
{
|
||||
|
|
|
@ -187,15 +187,15 @@ TORRENT_TEST(escape_string)
|
|||
{
|
||||
// escape_string
|
||||
char const* test_string = "!@#$%^&*()-_=+/,. %?";
|
||||
TEST_EQUAL(escape_string(test_string, int(strlen(test_string)))
|
||||
TEST_EQUAL(escape_string(test_string)
|
||||
, "!%40%23%24%25%5e%26*()-_%3d%2b%2f%2c.%20%25%3f");
|
||||
|
||||
// escape_path
|
||||
TEST_EQUAL(escape_path(test_string, int(strlen(test_string)))
|
||||
TEST_EQUAL(escape_path(test_string)
|
||||
, "!%40%23%24%25%5e%26*()-_%3d%2b/%2c.%20%25%3f");
|
||||
|
||||
error_code ec;
|
||||
TEST_CHECK(unescape_string(escape_path(test_string, int(strlen(test_string))), ec) == test_string);
|
||||
TEST_CHECK(unescape_string(escape_path(test_string), ec) == test_string);
|
||||
TEST_CHECK(!ec);
|
||||
if (ec) std::fprintf(stderr, "%s\n", ec.message().c_str());
|
||||
|
||||
|
@ -212,9 +212,9 @@ TORRENT_TEST(escape_string)
|
|||
TEST_EQUAL(maybe_url_encode("?&"), "?&");
|
||||
|
||||
// unescape_string
|
||||
TEST_CHECK(unescape_string(escape_string(test_string, int(strlen(test_string))), ec)
|
||||
TEST_CHECK(unescape_string(escape_string(test_string), ec)
|
||||
== test_string);
|
||||
std::cerr << unescape_string(escape_string(test_string, int(strlen(test_string))), ec) << std::endl;
|
||||
std::cerr << unescape_string(escape_string(test_string), ec) << std::endl;
|
||||
// prematurely terminated string
|
||||
unescape_string("%", ec);
|
||||
TEST_CHECK(ec == error_code(errors::invalid_escaped_string));
|
||||
|
|
Loading…
Reference in New Issue