fix load_file(), used to load files in the torrent_info constructor and the posix part file, to support non-ascii characters on windows

This commit is contained in:
Arvid Norberg
2021-01-22 14:19:41 +01:00
committed by Arvid Norberg
parent 38738795c0
commit d8bbad389d
5 changed files with 46 additions and 11 deletions

View File

@ -1,3 +1,4 @@
* fix loading non-ascii filenames on windows with torrent_info constructor (2.0 regression)
* add std::hash<> specialization for info_hash_t
* fix integer overflow in hash_picker and properly restrict max file sizes in torrents
* strengthen SSRF mitigation for web seeds

View File

@ -363,6 +363,16 @@ class TestAddPiece(unittest.TestCase):
class test_torrent_info(unittest.TestCase):
def test_non_ascii_file(self):
try:
shutil.copy('base.torrent', 'base-\u745E\u5177.torrent')
except shutil.SameFileError:
pass
ti = lt.torrent_info('base-\u745E\u5177.torrent')
self.assertTrue(len(ti.info_section()) != 0)
self.assertTrue(len(ti.hash_for_piece(0)) != 0)
def test_bencoded_constructor(self):
info = lt.torrent_info({'info': {
'name': 'test_torrent', 'length': 1234,
@ -842,10 +852,19 @@ class test_peer_info(unittest.TestCase):
if __name__ == '__main__':
print(lt.__version__)
shutil.copy(os.path.join('..', '..', 'test', 'test_torrents',
'url_seed_multi.torrent'), '.')
shutil.copy(os.path.join('..', '..', 'test', 'test_torrents',
'base.torrent'), '.')
shutil.copy(os.path.join('..', '..', 'test', 'test_torrents',
'unordered.torrent'), '.')
try:
shutil.copy(os.path.join('..', '..', 'test', 'test_torrents',
'url_seed_multi.torrent'), '.')
except shutil.SameFileError:
pass
try:
shutil.copy(os.path.join('..', '..', 'test', 'test_torrents',
'base.torrent'), '.')
except shutil.SameFileError:
pass
try:
shutil.copy(os.path.join('..', '..', 'test', 'test_torrents',
'unordered.torrent'), '.')
except shutil.SameFileError:
pass
unittest.main()

View File

@ -308,8 +308,15 @@ namespace aux {
file_pointer posix_part_file::open_file(open_mode const mode, error_code& ec)
{
std::string const fn = combine_path(m_path, m_name);
#ifdef TORRENT_WINDOWS
wchar_t const* mode_str[] = {L"rb", L"rb+"};
file_pointer ret(::_wfopen(convert_to_native_path_string(fn).c_str()
, mode_str[static_cast<std::uint8_t>(mode)]));
#else
char const* mode_str[] = {"rb", "rb+"};
file_pointer ret(::fopen(fn.c_str(), mode_str[static_cast<std::uint8_t>(mode)]));
file_pointer ret(::fopen(fn.c_str()
, mode_str[static_cast<std::uint8_t>(mode)]));
#endif
if (ret.file() == nullptr)
ec.assign(errno, generic_category());
@ -323,7 +330,11 @@ namespace aux {
if (ec) return {};
#ifdef TORRENT_WINDOWS
ret = file_pointer(::_wfopen(convert_to_native_path_string(fn).c_str(), L"wb+"));
#else
ret = file_pointer(::fopen(fn.c_str(), "wb+"));
#endif
if (ret.file() == nullptr)
ec.assign(errno, generic_category());
}

View File

@ -525,9 +525,9 @@ namespace aux {
#endif
#ifdef TORRENT_WINDOWS
FILE* f = _wfopen(convert_to_native_path_string(fn).c_str(), mode_str);
FILE* f = ::_wfopen(convert_to_native_path_string(fn).c_str(), mode_str);
#else
FILE* f = fopen(fn.c_str(), mode_str);
FILE* f = std::fopen(fn.c_str(), mode_str);
#endif
if (f == nullptr)
{
@ -556,9 +556,9 @@ namespace aux {
// reading and writing, but doesn't create the file. "w+" creates
// the file and truncates it
#ifdef TORRENT_WINDOWS
f = _wfopen(convert_to_native_path_string(fn).c_str(), L"wb+");
f = ::_wfopen(convert_to_native_path_string(fn).c_str(), L"wb+");
#else
f = fopen(fn.c_str(), "wb+");
f = std::fopen(fn.c_str(), "wb+");
#endif
if (f == nullptr)
{

View File

@ -667,7 +667,11 @@ namespace {
, error_code& ec, int const max_buffer_size = 80000000)
{
ec.clear();
#ifdef TORRENT_WINDOWS
aux::file_pointer f(::_wfopen(convert_to_native_path_string(filename).c_str(), L"rb"));
#else
aux::file_pointer f(std::fopen(filename.c_str(), "rb"));
#endif
if (f.file() == nullptr)
{
ec.assign(errno, generic_category());