fix issue in UTF-8 encoding validation

This commit is contained in:
arvidn 2017-08-15 13:37:12 +02:00 committed by Arvid Norberg
parent b70d3efba9
commit b5fe0f95a2
4 changed files with 31 additions and 4 deletions

View File

@ -1,3 +1,4 @@
* fix utf-8 encoding check in torrent parser
* fix infinite loop when parsing maliciously crafted torrents
* fix invalid read in parse_int in bdecoder
* fix issue with very long tracker- and web seed URLs

View File

@ -300,7 +300,7 @@ Boolean isLegalUTF8(const UTF8 *source, int length) {
/* Everything else falls through when "true"... */
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 2: if ((a = (*--srcptr)) > 0xBF) return false;
case 2: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
switch (*source) {
/* no fall-through in this inner switch */

View File

@ -255,8 +255,7 @@ namespace libtorrent
continue;
}
if (code_point < 0
|| !valid_path_character(code_point))
if (code_point < 0 || !valid_path_character(code_point))
{
// invalid utf8 sequence, replace with "_"
path += '_';
@ -265,9 +264,14 @@ namespace libtorrent
continue;
}
TORRENT_ASSERT(isLegalUTF8(reinterpret_cast<UTF8 const*>(element + i), seq_len));
// validation passed, add it to the output string
for (int k = i; k < i + seq_len; ++k)
{
TORRENT_ASSERT(element[k] != 0);
path.push_back(element[k]);
}
if (code_point == '.') ++num_dots;
@ -618,7 +622,7 @@ namespace libtorrent
{
// as long as this file already exists
// increase the counter
boost::uint32_t h = m_files.file_path_hash(i, empty_str);
boost::uint32_t const h = m_files.file_path_hash(i, empty_str);
if (!files.insert(h).second)
{
// This filename appears to already exist!

View File

@ -326,6 +326,11 @@ TORRENT_TEST(sanitize_path_trailing_spaces)
TORRENT_TEST(sanitize_path)
{
std::string path;
sanitize_append_path_element(path, "\0\0\xed\0\x80", 5);
TEST_EQUAL(path, "_");
path.clear();
sanitize_append_path_element(path, "/a/", 3);
sanitize_append_path_element(path, "b", 1);
sanitize_append_path_element(path, "c", 1);
@ -506,6 +511,17 @@ TORRENT_TEST(sanitize_path)
TEST_EQUAL(path, "foobar");
}
TORRENT_TEST(sanitize_path_zeroes)
{
std::string path;
sanitize_append_path_element(path, "\0foo", 4);
TEST_EQUAL(path, "foo");
path.clear();
sanitize_append_path_element(path, "\0\0\0\0", 4);
TEST_EQUAL(path, "");
}
TORRENT_TEST(verify_encoding)
{
// verify_encoding
@ -585,6 +601,12 @@ TORRENT_TEST(verify_encoding)
TEST_CHECK(!verify_encoding(test));
fprintf(stdout, "%s\n", test.c_str());
TEST_CHECK(test == "filename____");
// missing byte header
test = "filename\xed\0\x80";
TEST_CHECK(!verify_encoding(test));
fprintf(stdout, "%s\n", test.c_str());
TEST_CHECK(test == "filename_");
}
TORRENT_TEST(parse_torrents)