merged changes from RC_1_0
This commit is contained in:
parent
0b711f1280
commit
edfa38cd30
|
@ -173,6 +173,8 @@ if (build_tests)
|
|||
add_definitions(-DTORRENT_EXPORT_EXTRA)
|
||||
endif (build_tests)
|
||||
|
||||
include_directories(${includes})
|
||||
|
||||
if (encryption)
|
||||
list(APPEND sources pe_crypto asio_ssl)
|
||||
if(NOT DEFINED OPENSSL_INCLUDE_DIR OR NOT DEFINED OPENSSL_LIBRARIES)
|
||||
|
@ -313,8 +315,6 @@ if (tcmalloc)
|
|||
target_link_libraries(torrent-rasterbar tcmalloc)
|
||||
endif()
|
||||
|
||||
include_directories(${includes})
|
||||
|
||||
set_target_properties(torrent-rasterbar PROPERTIES
|
||||
SOVERSION ${SOVERSION})
|
||||
|
||||
|
@ -326,9 +326,7 @@ foreach (s ${COMPILETIME_OPTIONS_LIST})
|
|||
set (COMPILETIME_OPTIONS "${COMPILETIME_OPTIONS} -D${s}")
|
||||
endforeach (s)
|
||||
|
||||
if (MSVC)
|
||||
configure_file(libtorrent-rasterbar-cmake.pc.in libtorrent-rasterbar.pc)
|
||||
endif()
|
||||
configure_file(libtorrent-rasterbar-cmake.pc.in libtorrent-rasterbar.pc)
|
||||
|
||||
string (COMPARE EQUAL "${CMAKE_SIZEOF_VOID_P}" "8" IS64BITS)
|
||||
|
||||
|
@ -346,14 +344,13 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libtorrent-rasterbar.pc DESTINATION ${
|
|||
|
||||
# === build examples ===
|
||||
if(build_examples)
|
||||
FILE(GLOB examples RELATIVE "${PROJECT_SOURCE_DIR}" "examples/*.cpp")
|
||||
foreach(s ${examples})
|
||||
get_filename_component (sn ${s} NAME_WE)
|
||||
add_executable(${sn} ${s})
|
||||
target_link_libraries(${sn} torrent-rasterbar)
|
||||
endforeach(s)
|
||||
# this will make some internal functions available in the
|
||||
# DLL interface, for the examples to access
|
||||
add_definitions(-DTORRENT_EXPORT_EXTRA)
|
||||
|
||||
include_directories(${Boost_INCLUDE_DIR})
|
||||
# to build the examples, run cmake in this subdirectory
|
||||
# after libtorrent is built
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/examples)
|
||||
endif()
|
||||
|
||||
# === build tests ===
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
1.0.3 release
|
||||
|
||||
* handle overlong utf-8 sequences
|
||||
* fix link order bug in makefile for python binding
|
||||
* fix bug in interest calculation, causing premature disconnects
|
||||
* tweak flag_override_resume_data semantics to make more sense (breaks
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
project(libtorrent-examples)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
|
||||
# Add extra include and library search directories so examples can optionally
|
||||
# be built without a prior "make install" of libtorrent.
|
||||
list(APPEND CMAKE_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../include")
|
||||
list(APPEND CMAKE_LIBRARY_PATH "${CMAKE_CURRENT_BINARY_DIR}/..")
|
||||
|
||||
# Also use the generated pkg-config file prior to "make install".
|
||||
# In an independent project, these lines would simply not exist.
|
||||
set(PKG_CONFIG_CHANGED_PATH "${CMAKE_CURRENT_BINARY_DIR}/..;$ENV{PKG_CONFIG_PATH}")
|
||||
if(UNIX)
|
||||
string(REPLACE ";" ":" PKG_CONFIG_CHANGED_PATH "${PKG_CONFIG_CHANGED_PATH}")
|
||||
endif ()
|
||||
set(ENV{PKG_CONFIG_PATH} "${PKG_CONFIG_CHANGED_PATH}")
|
||||
|
||||
find_package(LibtorrentRasterbar REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS system)
|
||||
|
||||
include_directories(${LibtorrentRasterbar_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
|
||||
add_definitions(${LibtorrentRasterbar_DEFINITIONS})
|
||||
|
||||
FILE(GLOB examples RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.cpp")
|
||||
foreach(s ${examples})
|
||||
get_filename_component (sn ${s} NAME_WE)
|
||||
add_executable(${sn} ${s})
|
||||
target_link_libraries(${sn} ${LibtorrentRasterbar_LIBRARIES} ${Boost_LIBRARIES})
|
||||
endforeach(s)
|
|
@ -13,7 +13,7 @@ bin_PROGRAMS = $(example_programs)
|
|||
endif
|
||||
|
||||
EXTRA_PROGRAMS = $(example_programs)
|
||||
EXTRA_DIST = Jamfile
|
||||
EXTRA_DIST = Jamfile CMakeLists.txt cmake/FindLibtorrentRasterbar.cmake
|
||||
|
||||
client_test_SOURCES = client_test.cpp print.cpp session_view.cpp torrent_view.cpp
|
||||
#client_test_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||
|
|
|
@ -242,6 +242,41 @@ int load_file(std::string const& filename, std::vector<char>& v
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool is_absolute_path(std::string const& f)
|
||||
{
|
||||
if (f.empty()) return false;
|
||||
#if defined(TORRENT_WINDOWS) || defined(TORRENT_OS2)
|
||||
int i = 0;
|
||||
// match the xx:\ or xx:/ form
|
||||
while (f[i] && strchr("abcdefghijklmnopqrstuvxyz", f[i])) ++i;
|
||||
if (i < int(f.size()-1) && f[i] == ':' && (f[i+1] == '\\' || f[i+1] == '/'))
|
||||
return true;
|
||||
|
||||
// match the \\ form
|
||||
if (int(f.size()) >= 2 && f[0] == '\\' && f[1] == '\\')
|
||||
return true;
|
||||
return false;
|
||||
#else
|
||||
if (f[0] == '/') return true;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string path_append(std::string const& lhs, std::string const& rhs)
|
||||
{
|
||||
if (lhs.empty() || lhs == ".") return rhs;
|
||||
if (rhs.empty() || rhs == ".") return lhs;
|
||||
|
||||
#if defined(TORRENT_WINDOWS) || defined(TORRENT_OS2)
|
||||
#define TORRENT_SEPARATOR "\\"
|
||||
bool need_sep = lhs[lhs.size()-1] != '\\' && lhs[lhs.size()-1] != '/';
|
||||
#else
|
||||
#define TORRENT_SEPARATOR "/"
|
||||
bool need_sep = lhs[lhs.size()-1] != '/';
|
||||
#endif
|
||||
return lhs + (need_sep?TORRENT_SEPARATOR:"") + rhs;
|
||||
}
|
||||
|
||||
bool is_hex(char const *in, int len)
|
||||
{
|
||||
for (char const* end = in + len; in < end; ++in)
|
||||
|
@ -572,8 +607,7 @@ void add_torrent(libtorrent::session& ses
|
|||
if (share_mode) p.flags |= add_torrent_params::flag_share_mode;
|
||||
lazy_entry resume_data;
|
||||
|
||||
// TODO: implement combine_path in here, since it's internal to libtorrent
|
||||
std::string filename = combine_path(save_path, combine_path(".resume"
|
||||
std::string filename = path_append(save_path, path_append(".resume"
|
||||
, libtorrent::filename(torrent) + ".resume"));
|
||||
|
||||
error_code ec;
|
||||
|
@ -595,6 +629,67 @@ void add_torrent(libtorrent::session& ses
|
|||
files.insert(std::pair<const std::string, torrent_handle>(torrent, torrent_handle()));
|
||||
}
|
||||
|
||||
std::vector<std::string> list_dir(std::string path
|
||||
, bool (*filter_fun)(std::string const&))
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
#ifdef TORRENT_WINDOWS
|
||||
if (!f.empty() && f[f.size()-1] != '\\') f += "\\*";
|
||||
else f += "*";
|
||||
|
||||
std::wstring wpath;
|
||||
libtorrent::utf8_wchar(path, wpath);
|
||||
|
||||
WIN32_FIND_DATAW fd;
|
||||
HANDLE handle = FindFirstFileW(wpath.c_str(), &fd);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return ret;
|
||||
|
||||
do
|
||||
{
|
||||
std::string p;
|
||||
libtorrent::wchar_utf8(fd.cFileName, p);
|
||||
if (filter_fun(p))
|
||||
ret.push_back(p);
|
||||
|
||||
} while (FindNextFileW(handle, &fd));
|
||||
FindClose(handle);
|
||||
#else
|
||||
|
||||
if (!path.empty() && path[path.size()-1] == '/')
|
||||
path.resize(path.size()-1);
|
||||
|
||||
DIR* handle = opendir(path.c_str());
|
||||
if (handle == 0) return ret;
|
||||
|
||||
struct dirent de;
|
||||
dirent* dummy;
|
||||
while (readdir_r(handle, &de, &dummy) == 0)
|
||||
{
|
||||
if (dummy == 0) break;
|
||||
|
||||
std::string p = de.d_name;
|
||||
if (filter_fun(p))
|
||||
ret.push_back(p);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool filter_fun(std::string const& p)
|
||||
{
|
||||
for (int i = p.size() - 1; i >= 0; --i)
|
||||
{
|
||||
if (p[i] == '/') break;
|
||||
#ifdef TORRENT_WINDOWS
|
||||
if (p[i] == '\\') break;
|
||||
#endif
|
||||
if (p[i] != '.') continue;
|
||||
return p.compare(i, 8, ".torrent") == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void scan_dir(std::string const& dir_path
|
||||
, libtorrent::session& ses
|
||||
, handles_t& files
|
||||
|
@ -609,20 +704,12 @@ void scan_dir(std::string const& dir_path
|
|||
using namespace libtorrent;
|
||||
|
||||
error_code ec;
|
||||
std::vector<std::pair<boost::uint64_t, std::string> > ents;
|
||||
// TODO: don't use internal directory type
|
||||
for (directory i(dir_path, ec); !i.done(); i.next(ec))
|
||||
{
|
||||
if (extension(i.file()) != ".torrent") continue;
|
||||
ents.push_back(std::make_pair(i.inode(), i.file()));
|
||||
}
|
||||
std::vector<std::string> ents = list_dir(dir_path, filter_fun);
|
||||
|
||||
std::sort(ents.begin(), ents.end());
|
||||
|
||||
for (std::vector<std::pair<boost::uint64_t, std::string> >::iterator i = ents.begin()
|
||||
for (std::vector<std::string>::iterator i = ents.begin()
|
||||
, end(ents.end()); i != end; ++i)
|
||||
{
|
||||
std::string file = combine_path(dir_path, i->second);
|
||||
std::string file = path_append(dir_path, *i);
|
||||
|
||||
handles_t::iterator k = files.find(file);
|
||||
if (k != files.end())
|
||||
|
@ -737,7 +824,7 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
|||
torrent_handle h = p->handle;
|
||||
error_code ec;
|
||||
file_status st;
|
||||
std::string base_name = combine_path("certificates", to_hex(h.info_hash().to_string()));
|
||||
std::string base_name = path_append("certificates", to_hex(h.info_hash().to_string()));
|
||||
std::string cert = base_name + ".pem";
|
||||
std::string priv = base_name + "_key.pem";
|
||||
stat_file(cert, &st, ec);
|
||||
|
@ -781,7 +868,7 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
|||
bencode(std::back_inserter(buffer), te);
|
||||
sha1_hash hash = ti->info_hash();
|
||||
std::string filename = ti->name() + "." + to_hex(hash.to_string()) + ".torrent";
|
||||
filename = combine_path(monitor_dir, filename);
|
||||
filename = path_append(monitor_dir, filename);
|
||||
save_file(filename, buffer);
|
||||
|
||||
files.insert(std::pair<std::string, libtorrent::torrent_handle>(filename, h));
|
||||
|
@ -871,7 +958,7 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
|
|||
std::vector<char> out;
|
||||
bencode(std::back_inserter(out), *p->resume_data);
|
||||
torrent_status st = h.status(torrent_handle::query_save_path);
|
||||
save_file(combine_path(st.save_path, combine_path(".resume", libtorrent::filename(
|
||||
save_file(path_append(st.save_path, path_append(".resume", libtorrent::filename(
|
||||
hash_to_filename[st.info_hash]) + ".resume")), out);
|
||||
if (h.is_valid()
|
||||
&& non_files.find(h) == non_files.end()
|
||||
|
@ -1321,10 +1408,10 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
// create directory for resume files
|
||||
// TODO: don't use internal create_directory function
|
||||
create_directory(combine_path(save_path, ".resume"), ec);
|
||||
if (ec)
|
||||
fprintf(stderr, "failed to create resume file directory: %s\n", ec.message().c_str());
|
||||
int ret = mkdir(path_append(save_path, ".resume").c_str(), 0777);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "failed to create resume file directory: (%d) %s\n"
|
||||
, errno, strerror(errno));
|
||||
|
||||
if (bind_to_interface.empty()) bind_to_interface = "0.0.0.0";
|
||||
settings.set_str(settings_pack::listen_interfaces, bind_to_interface + ":" + to_string(listen_port).elems);
|
||||
|
@ -1382,7 +1469,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (ec) continue;
|
||||
|
||||
std::string filename = combine_path(save_path, combine_path(".resume"
|
||||
std::string filename = path_append(save_path, path_append(".resume"
|
||||
, to_hex(tmp.info_hash.to_string()) + ".resume"));
|
||||
|
||||
load_file(filename.c_str(), p.resume_data, ec);
|
||||
|
@ -1522,7 +1609,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (ec) continue;
|
||||
|
||||
std::string filename = combine_path(save_path, combine_path(".resume"
|
||||
std::string filename = path_append(save_path, path_append(".resume"
|
||||
, to_hex(tmp.info_hash.to_string()) + ".resume"));
|
||||
|
||||
load_file(filename.c_str(), p.resume_data, ec);
|
||||
|
@ -1550,10 +1637,10 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
error_code ec;
|
||||
std::string path;
|
||||
if (is_complete(i->first)) path = i->first;
|
||||
else path = combine_path(monitor_dir, i->first);
|
||||
remove(path, ec);
|
||||
if (ec) printf("failed to delete .torrent file: %s\n", ec.message().c_str());
|
||||
if (is_absolute_path(i->first)) path = i->first;
|
||||
else path = path_append(monitor_dir, i->first);
|
||||
if (::remove(path.c_str()) < 0)
|
||||
printf("failed to delete .torrent file: %s\n", ec.message().c_str());
|
||||
files.erase(i);
|
||||
}
|
||||
if (st.handle.is_valid())
|
||||
|
@ -2054,8 +2141,8 @@ int main(int argc, char* argv[])
|
|||
torrent_status st = h.status(torrent_handle::query_save_path);
|
||||
std::vector<char> out;
|
||||
bencode(std::back_inserter(out), *rd->resume_data);
|
||||
save_file(combine_path(st.save_path, combine_path(".resume", libtorrent::filename(
|
||||
hash_to_filename[st.info_hash]) + ".resume")), out);
|
||||
save_file(path_append(st.save_path, path_append(".resume"
|
||||
, libtorrent::filename(hash_to_filename[st.info_hash]) + ".resume")), out);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
# - Try to find libtorrent-rasterbar
|
||||
# Once done this will define
|
||||
# LibtorrentRasterbar_FOUND - System has libtorrent-rasterbar
|
||||
# LibtorrentRasterbar_INCLUDE_DIRS - The libtorrent-rasterbar include directories
|
||||
# LibtorrentRasterbar_LIBRARIES - The libraries needed to use libtorrent-rasterbar
|
||||
# LibtorrentRasterbar_DEFINITIONS - Compiler switches required for using libtorrent-rasterbar
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_LIBTORRENT_RASTERBAR libtorrent-rasterbar)
|
||||
|
||||
if (PC_LIBTORRENT_RASTERBAR_FOUND)
|
||||
set(LibtorrentRasterbar_DEFINITIONS ${PC_LIBTORRENT_RASTERBAR_CFLAGS})
|
||||
else ()
|
||||
# Without pkg-config, we can't possibly figure out the correct build flags.
|
||||
# libtorrent is very picky about those. Let's take a set of defaults and
|
||||
# hope that they apply. If not, you the user are on your own.
|
||||
set(LibtorrentRasterbar_DEFINITIONS -DTORRENT_USE_OPENSSL -DTORRENT_DISABLE_GEO_IP -DTORRENT_LINKING_SHARED -DBOOST_ASIO_DYN_LINK -DBOOST_ASIO_ENABLE_CANCELIO -DBOOST_EXCEPTION_DISABLE -DBOOST_DATE_TIME_DYN_LINK -DBOOST_THREAD_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_CHRONO_DYN_LINK -DUNICODE -D_UNICODE -D_FILE_OFFSET_BITS=64)
|
||||
endif ()
|
||||
|
||||
find_path(LibtorrentRasterbar_INCLUDE_DIR libtorrent
|
||||
HINTS ${PC_LIBTORRENT_RASTERBAR_INCLUDEDIR} ${PC_LIBTORRENT_RASTERBAR_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES libtorrent-rasterbar)
|
||||
|
||||
find_library(LibtorrentRasterbar_LIBRARY NAMES torrent-rasterbar
|
||||
HINTS ${PC_LIBTORRENT_RASTERBAR_LIBDIR} ${PC_LIBTORRENT_RASTERBAR_LIBRARY_DIRS})
|
||||
|
||||
set(LibtorrentRasterbar_LIBRARIES ${LibtorrentRasterbar_LIBRARY})
|
||||
set(LibtorrentRasterbar_INCLUDE_DIRS ${LibtorrentRasterbar_INCLUDE_DIR})
|
||||
|
||||
if (NOT Boost_SYSTEM_FOUND OR NOT Boost_THREAD_FOUND OR NOT Boost_DATE_TIME_FOUND OR NOT Boost_CHRONO_FOUND)
|
||||
find_package(Boost REQUIRED COMPONENTS system thread date_time chrono)
|
||||
set(LibtorrentRasterbar_LIBRARIES ${LibtorrentRasterbar_LIBRARIES} ${Boost_LIBRARIES})
|
||||
set(LibtorrentRasterbar_INCLUDE_DIRS ${LibtorrentRasterbar_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
|
||||
endif ()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LibtorrentRasterbar_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(LibtorrentRasterbar DEFAULT_MSG
|
||||
LibtorrentRasterbar_LIBRARY
|
||||
LibtorrentRasterbar_INCLUDE_DIR
|
||||
Boost_SYSTEM_FOUND
|
||||
Boost_THREAD_FOUND
|
||||
Boost_DATE_TIME_FOUND
|
||||
Boost_CHRONO_FOUND)
|
||||
|
||||
mark_as_advanced(LibtorrentRasterbar_INCLUDE_DIR LibtorrentRasterbar_LIBRARY)
|
|
@ -320,7 +320,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_USE_READV 0
|
||||
|
||||
#else
|
||||
#warning unknown OS, assuming BSD
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma message ( "unknown OS, assuming BSD" )
|
||||
#else
|
||||
#warning "unknown OS, assuming BSD"
|
||||
#endif
|
||||
|
||||
#define TORRENT_BSD
|
||||
#endif
|
||||
|
||||
|
@ -359,7 +365,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
// this is the maximum number of characters in a
|
||||
// path element / filename on windows
|
||||
#define TORRENT_MAX_PATH 255
|
||||
#warning unknown platform, assuming the longest path is 255
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma message ( "unknown platform, assuming the longest path is 255" )
|
||||
#else
|
||||
#warning "unknown platform, assuming the longest path is 255"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -643,7 +643,13 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#else
|
||||
#warning THIS OS IS NOT RECOGNIZED, enum_net_interfaces WILL PROBABLY NOT WORK
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma message ( "THIS OS IS NOT RECOGNIZED, enum_net_interfaces WILL PROBABLY NOT WORK" )
|
||||
#else
|
||||
#warning "THIS OS IS NOT RECOGNIZED, enum_net_interfaces WILL PROBABLY NOT WORK"
|
||||
#endif
|
||||
|
||||
// make a best guess of the interface we're using and its IP
|
||||
udp::resolver r(ios);
|
||||
udp::resolver::iterator i = r.resolve(udp::resolver::query(asio::ip::host_name(ec), "0"), ec);
|
||||
|
|
10
src/file.cpp
10
src/file.cpp
|
@ -293,10 +293,14 @@ BOOST_STATIC_ASSERT((libtorrent::file::rw_mask & libtorrent::file::attribute_mas
|
|||
BOOST_STATIC_ASSERT((libtorrent::file::sparse & libtorrent::file::attribute_mask) == 0);
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_WINDOWS
|
||||
#if defined UNICODE && !TORRENT_USE_WSTRING
|
||||
#warning wide character support not available. Files will be saved using narrow string names
|
||||
#if defined TORRENT_WINDOWS && defined UNICODE && !TORRENT_USE_WSTRING
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma message ( "wide character support not available. Files will be saved using narrow string names" )
|
||||
#else
|
||||
#warning "wide character support not available. Files will be saved using narrow string names"
|
||||
#endif
|
||||
|
||||
#endif // TORRENT_WINDOWS
|
||||
|
||||
namespace libtorrent
|
||||
|
|
|
@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/ConvertUTF.h"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/escape_string.hpp" // is_space
|
||||
#include "libtorrent/bencode.hpp"
|
||||
|
@ -95,85 +96,65 @@ namespace libtorrent
|
|||
std::string tmp_path;
|
||||
tmp_path.reserve(target.size()+5);
|
||||
bool valid_encoding = true;
|
||||
for (std::string::iterator i = target.begin()
|
||||
, end(target.end()); i != end; ++i)
|
||||
|
||||
UTF8 const* ptr = (UTF8 const*)&target[0];
|
||||
UTF8 const* end = (UTF8 const*)&target[0] + target.size();
|
||||
while (ptr < end)
|
||||
{
|
||||
// valid ascii-character
|
||||
if ((*i & 0x80) == 0)
|
||||
UTF32 codepoint;
|
||||
UTF32* cp = &codepoint;
|
||||
|
||||
// decode a single utf-8 character
|
||||
ConversionResult res = ConvertUTF8toUTF32(&ptr, end, &cp, cp + 1
|
||||
, lenientConversion);
|
||||
|
||||
// this was the last character, and nothing was
|
||||
// written to the destination buffer (i.e. the source character was
|
||||
// truncated)
|
||||
if (res == sourceExhausted
|
||||
|| res == sourceIllegal)
|
||||
{
|
||||
// replace invalid characters with '_'
|
||||
if (!fix_paths || valid_path_character(*i))
|
||||
if (cp == &codepoint)
|
||||
{
|
||||
tmp_path += *i;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_path += '_';
|
||||
if (res == sourceExhausted)
|
||||
ptr = end;
|
||||
else
|
||||
++ptr;
|
||||
|
||||
codepoint = '_';
|
||||
valid_encoding = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (end - i < 2)
|
||||
else if ((res != conversionOK && res != targetExhausted)
|
||||
|| codepoint == UNI_REPLACEMENT_CHAR)
|
||||
{
|
||||
tmp_path += "_";
|
||||
// we expect the conversion to fail with targetExhausted, since we
|
||||
// only pass in a single destination character slot. The last
|
||||
// character will succeed though. Also, if the character was replaced,
|
||||
// use our own replacement symbol (underscore).
|
||||
codepoint = '_';
|
||||
valid_encoding = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// valid 2-byte utf-8 character
|
||||
if ((i[0] & 0xe0) == 0xc0
|
||||
&& (i[1] & 0xc0) == 0x80)
|
||||
{
|
||||
tmp_path += i[0];
|
||||
tmp_path += i[1];
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (end - i < 3)
|
||||
// if fix paths is true, also replace characters that are invalid
|
||||
// in filenames
|
||||
if (fix_paths && codepoint < 0x7f && !valid_path_character(codepoint))
|
||||
{
|
||||
tmp_path += "_";
|
||||
codepoint = '_';
|
||||
valid_encoding = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// valid 3-byte utf-8 character
|
||||
if ((i[0] & 0xf0) == 0xe0
|
||||
&& (i[1] & 0xc0) == 0x80
|
||||
&& (i[2] & 0xc0) == 0x80)
|
||||
{
|
||||
tmp_path += i[0];
|
||||
tmp_path += i[1];
|
||||
tmp_path += i[2];
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
// encode codepoint into utf-8
|
||||
cp = &codepoint;
|
||||
UTF8 sequence[5];
|
||||
UTF8* start = sequence;
|
||||
res = ConvertUTF32toUTF8((const UTF32**)&cp, cp + 1, &start, start + 5, lenientConversion);
|
||||
TORRENT_ASSERT(res == conversionOK);
|
||||
|
||||
if (end - i < 4)
|
||||
{
|
||||
tmp_path += "_";
|
||||
valid_encoding = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// valid 4-byte utf-8 character
|
||||
if ((i[0] & 0xf8) == 0xf0
|
||||
&& (i[1] & 0xc0) == 0x80
|
||||
&& (i[2] & 0xc0) == 0x80
|
||||
&& (i[3] & 0xc0) == 0x80)
|
||||
{
|
||||
tmp_path += i[0];
|
||||
tmp_path += i[1];
|
||||
tmp_path += i[2];
|
||||
tmp_path += i[3];
|
||||
i += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp_path += "_";
|
||||
valid_encoding = false;
|
||||
for (int i = 0; i < start - sequence; ++i)
|
||||
tmp_path += (char)sequence[i];
|
||||
}
|
||||
|
||||
// the encoding was not valid utf-8
|
||||
// save the original encoding and replace the
|
||||
// commonly used path with the correctly
|
||||
|
@ -1229,7 +1210,7 @@ namespace libtorrent
|
|||
}
|
||||
m_multifile = true;
|
||||
}
|
||||
files.set_name(name);
|
||||
TORRENT_ASSERT(!files.name().empty());
|
||||
|
||||
// extract sha-1 hashes for all pieces
|
||||
// we want this division to round upwards, that's why we have the
|
||||
|
|
|
@ -54,6 +54,8 @@ test_torrent_t test_torrents[] =
|
|||
{ "hidden_parent_path.torrent" },
|
||||
{ "single_multi_file.torrent" },
|
||||
{ "slash_path.torrent" },
|
||||
{ "slash_path2.torrent" },
|
||||
{ "slash_path3.torrent" },
|
||||
{ "backslash_path.torrent" },
|
||||
{ "url_list.torrent" },
|
||||
{ "url_list2.torrent" },
|
||||
|
@ -259,11 +261,7 @@ int test_main()
|
|||
bencode(std::back_inserter(buf), torrent);
|
||||
torrent_info ti2(&buf[0], buf.size(), ec);
|
||||
std::cerr << ti2.name() << std::endl;
|
||||
#ifdef TORRENT_WINDOWS
|
||||
TEST_CHECK(ti2.name() == "ctest1test2test3");
|
||||
#else
|
||||
TEST_CHECK(ti2.name() == "test1test2test3");
|
||||
#endif
|
||||
TEST_EQUAL(ti2.name(), "test1test2test3");
|
||||
|
||||
info["name.utf-8"] = "test2/../test3/.././../../test4";
|
||||
torrent["info"] = info;
|
||||
|
@ -271,7 +269,7 @@ int test_main()
|
|||
bencode(std::back_inserter(buf), torrent);
|
||||
torrent_info ti3(&buf[0], buf.size(), ec);
|
||||
std::cerr << ti3.name() << std::endl;
|
||||
TEST_CHECK(ti3.name() == "test2..test3.......test4");
|
||||
TEST_EQUAL(ti3.name(), "test2..test3.......test4");
|
||||
|
||||
// verify_encoding
|
||||
std::string test = "\b?filename=4";
|
||||
|
@ -334,6 +332,27 @@ int test_main()
|
|||
fprintf(stderr, "%s\n", test.c_str());
|
||||
TEST_CHECK(test == "filename_____foobar");
|
||||
|
||||
// redundant (overlong) 2-byte sequence
|
||||
// ascii code 0x2e encoded with a leading 0
|
||||
test = "filename\xc0\xae";
|
||||
TEST_CHECK(!verify_encoding(test));
|
||||
fprintf(stderr, "%s\n", test.c_str());
|
||||
TEST_CHECK(test == "filename__");
|
||||
|
||||
// redundant (overlong) 3-byte sequence
|
||||
// ascii code 0x2e encoded with two leading 0s
|
||||
test = "filename\xe0\x80\xae";
|
||||
TEST_CHECK(!verify_encoding(test));
|
||||
fprintf(stderr, "%s\n", test.c_str());
|
||||
TEST_CHECK(test == "filename___");
|
||||
|
||||
// redundant (overlong) 4-byte sequence
|
||||
// ascii code 0x2e encoded with three leading 0s
|
||||
test = "filename\xf0\x80\x80\xae";
|
||||
TEST_CHECK(!verify_encoding(test));
|
||||
fprintf(stderr, "%s\n", test.c_str());
|
||||
TEST_CHECK(test == "filename____");
|
||||
|
||||
std::string root_dir = parent_path(current_working_directory());
|
||||
for (int i = 0; i < sizeof(test_torrents)/sizeof(test_torrents[0]); ++i)
|
||||
{
|
||||
|
@ -417,6 +436,21 @@ int test_main()
|
|||
{
|
||||
TEST_EQUAL(ti->name(), "foobar");
|
||||
}
|
||||
else if (std::string(test_torrents[i].file) == "slash_path.torrent")
|
||||
{
|
||||
TEST_EQUAL(ti->num_files(), 1);
|
||||
TEST_EQUAL(ti->file_at(0).path, "temp/bar");
|
||||
}
|
||||
else if (std::string(test_torrents[i].file) == "slash_path2.torrent")
|
||||
{
|
||||
TEST_EQUAL(ti->num_files(), 1);
|
||||
TEST_EQUAL(ti->file_at(0).path, "temp/abc....def/bar");
|
||||
}
|
||||
else if (std::string(test_torrents[i].file) == "slash_path3.torrent")
|
||||
{
|
||||
TEST_EQUAL(ti->num_files(), 1);
|
||||
TEST_EQUAL(ti->file_at(0).path, "temp....abc");
|
||||
}
|
||||
|
||||
file_storage const& fs = ti->files();
|
||||
for (int i = 0; i < fs.num_files(); ++i)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
d10:created by10:libtorrent13:creation datei1359599503e4:infod5:filesld6:lengthi425e4:pathl13:abc/../../def1:/3:bareee4:name4:temp12:piece lengthi16384e6:pieces20:‚ž¼Œ&¾ÇJW›}ÜA4u,·¼‘‡ee
|
|
@ -0,0 +1 @@
|
|||
d10:created by10:libtorrent13:creation datei1359599503e4:infod6:lengthi12432e4:name14:temp/../../abc12:piece lengthi16384e6:pieces20:‚ž¼Œ&¾ÇJW›}ÜA4u,·¼‘‡ee
|
Loading…
Reference in New Issue