handle torrents with duplicate filenames
This commit is contained in:
parent
356db54dce
commit
10eb3fa00f
|
@ -1,3 +1,4 @@
|
|||
* handle torrents with duplicate filenames
|
||||
* piece timeouts are adjusted to download rate limits
|
||||
* encodes urls in torrent files that needs to be encoded
|
||||
* fixed not passing &supportcrypto=1 when encryption is disabled
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace libtorrent
|
|||
char TORRENT_EXPORT to_lower(char c);
|
||||
|
||||
bool TORRENT_EXPORT string_begins_no_case(char const* s1, char const* s2);
|
||||
bool TORRENT_EXPORT string_equal_no_case(char const* s1, char const* s2);
|
||||
|
||||
std::string TORRENT_EXPORT unescape_string(std::string const& s, error_code& ec);
|
||||
// replaces all disallowed URL characters by their %-encoding
|
||||
|
|
|
@ -111,6 +111,17 @@ namespace libtorrent
|
|||
return true;
|
||||
}
|
||||
|
||||
bool string_equal_no_case(char const* s1, char const* s2)
|
||||
{
|
||||
while (to_lower(*s1) == to_lower(*s2))
|
||||
{
|
||||
if (*s1 == 0) return true;
|
||||
++s1;
|
||||
++s2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string unescape_string(std::string const& s, error_code& ec)
|
||||
{
|
||||
std::string ret;
|
||||
|
|
|
@ -264,7 +264,7 @@ namespace libtorrent
|
|||
case 'p': target.pad_file = true; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -278,6 +278,22 @@ namespace libtorrent
|
|||
file_entry e;
|
||||
if (!extract_single_file(*list.list_at(i), e, root_dir))
|
||||
return false;
|
||||
int cnt = 0;
|
||||
for (file_storage::iterator k = target.begin()
|
||||
, end(target.end()); k != end; ++k)
|
||||
{
|
||||
if (string_equal_no_case(e.path.string().c_str()
|
||||
, k->path.string().c_str())) ++cnt;
|
||||
}
|
||||
if (cnt)
|
||||
{
|
||||
char suffix[15];
|
||||
snprintf(suffix, sizeof(suffix), ".%d", cnt);
|
||||
e.path.replace_extension(suffix + e.path.extension());
|
||||
// TODO: we should really make sure that this new name
|
||||
// doesn't already exist as well, otherwise we might
|
||||
// just create another collision
|
||||
}
|
||||
target.add_file(e);
|
||||
}
|
||||
return true;
|
||||
|
|
17
src/upnp.cpp
17
src/upnp.cpp
|
@ -746,17 +746,6 @@ namespace
|
|||
dst.clear();
|
||||
while (*src) dst.push_back(to_lower(*src++));
|
||||
}
|
||||
|
||||
bool string_equal_nocase(char const* lhs, char const* rhs)
|
||||
{
|
||||
while (to_lower(*lhs) == to_lower(*rhs))
|
||||
{
|
||||
if (*lhs == 0) return true;
|
||||
++lhs;
|
||||
++rhs;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct parse_state
|
||||
|
@ -781,10 +770,10 @@ struct parse_state
|
|||
{
|
||||
std::list<std::string>::reverse_iterator i = tag_stack.rbegin();
|
||||
if (i == tag_stack.rend()) return false;
|
||||
if (!string_equal_nocase(i->c_str(), str2)) return false;
|
||||
if (!string_equal_no_case(i->c_str(), str2)) return false;
|
||||
++i;
|
||||
if (i == tag_stack.rend()) return false;
|
||||
if (!string_equal_nocase(i->c_str(), str1)) return false;
|
||||
if (!string_equal_no_case(i->c_str(), str1)) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -814,7 +803,7 @@ void find_control_url(int type, char const* string, parse_state& state)
|
|||
// std::cout << " " << string << std::endl;
|
||||
if (!state.in_service && state.top_tags("service", "servicetype"))
|
||||
{
|
||||
if (string_equal_nocase(string, state.service_type))
|
||||
if (string_equal_no_case(string, state.service_type))
|
||||
state.in_service = true;
|
||||
}
|
||||
else if (state.in_service && state.top_tags("service", "controlurl"))
|
||||
|
|
|
@ -423,6 +423,13 @@ int test_main()
|
|||
TEST_CHECK(to_lower('-') == '-');
|
||||
TEST_CHECK(to_lower('&') == '&');
|
||||
|
||||
// test string_equal_no_case
|
||||
|
||||
TEST_CHECK(string_equal_no_case("foobar", "FoobAR"));
|
||||
TEST_CHECK(string_equal_no_case("foobar", "foobar"));
|
||||
TEST_CHECK(!string_equal_no_case("foobar", "foobar "));
|
||||
TEST_CHECK(!string_equal_no_case("foobar", "F00"));
|
||||
|
||||
// test string_begins_no_case
|
||||
|
||||
TEST_CHECK(string_begins_no_case("foobar", "FoobAR --"));
|
||||
|
|
Loading…
Reference in New Issue