Added support base64 support for non-UTF8 strings.

This commit is contained in:
Jari Sundell
2026-05-29 17:25:16 +02:00
committed by GitHub
parent 880510073a
commit add305f90c
10 changed files with 159 additions and 73 deletions
+22 -6
View File
@@ -281,18 +281,34 @@ AC_DEFUN([TORRENT_WITH_LUA], [
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
else else
AX_PROG_LUA AX_PROG_LUA
AX_LUA_LIBS
AX_LUA_HEADERS # 1. Override AX_LUA_LIBS default crash behavior
AC_DEFINE(HAVE_LUA, 1, Use LUA.) AX_LUA_LIBS([have_lua_libs=yes], [have_lua_libs=no])
AC_DEFINE(LUA_DATADIR, [PACKAGE_DATADIR "/lua"], [LUA data directory])
LIBS="$LIBS $LUA_LIB" # 2. Override AX_LUA_HEADERS default crash behavior
CXXFLAGS="$CXXFLAGS $LUA_INCLUDE" AX_LUA_HEADERS([have_lua_headers=yes], [have_lua_headers=no])
# 3. Only inject if both checks completely pass
if test "x$have_lua_libs" = "xyes" && test "x$have_lua_headers" = "xyes"; then
AC_DEFINE(HAVE_LUA, 1, Use LUA.)
AC_DEFINE(LUA_DATADIR, [PACKAGE_DATADIR "/lua"], [LUA data directory])
LIBS="$LIBS $LUA_LIB"
CXXFLAGS="$CXXFLAGS $LUA_INCLUDE"
else
# Throw fatal error ONLY if user strictly ran --with-lua=yes
if test "$withval" = "yes"; then
AC_MSG_ERROR([Lua support explicitly requested, but compatible Lua 5.3 libs/headers were not found.])
else
AC_MSG_WARN([Lua 5.3 libs or headers missing. Proceeding without Lua support.])
fi
fi
fi fi
],[ ],[
AC_MSG_RESULT(ignored) AC_MSG_RESULT(ignored)
]) ])
]) ])
AC_DEFUN([TORRENT_WITH_INOTIFY], [ AC_DEFUN([TORRENT_WITH_INOTIFY], [
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
+52 -47
View File
@@ -33,31 +33,34 @@
#include "control.h" #include "control.h"
#include "command_helpers.h" #include "command_helpers.h"
std::string torrent::string_utf8
retrieve_d_base_path(core::Download* download) { retrieve_d_base_path(core::Download* download) {
if (download->file_list()->is_multi_file()) if (download->file_list()->is_multi_file())
return download->file_list()->frozen_root_dir(); return download->file_list()->frozen_root_dir();
else
return download->file_list()->empty() ? std::string() : download->file_list()->at(0)->frozen_path(); if (download->file_list()->empty())
return {};
return download->file_list()->at(0)->frozen_path();
} }
std::string torrent::string_utf8
retrieve_d_base_filename(core::Download* download) { retrieve_d_base_filename(core::Download* download) {
const std::string* base; torrent::string_utf8 base_path;
if (download->file_list()->is_multi_file()) if (download->file_list()->is_multi_file())
base = &download->file_list()->frozen_root_dir(); base_path = download->file_list()->frozen_root_dir();
else if (download->file_list()->empty()) else if (!download->file_list()->empty())
return std::string(); base_path = download->file_list()->at(0)->frozen_path();
else else
base = &download->file_list()->at(0)->frozen_path(); return {};
std::string::size_type split = base->rfind('/'); auto split = base_path.str().rfind('/');
if (split == std::string::npos) if (split == std::string::npos)
return *base; return base_path;
else
return base->substr(split + 1); return torrent::string_utf8::from_string(base_path.str().substr(split + 1));
} }
torrent::Object torrent::Object
@@ -145,9 +148,9 @@ apply_d_directory(core::Download* download, const std::string& name) {
if (!download->file_list()->is_multi_file()) if (!download->file_list()->is_multi_file())
download->set_root_directory(name); download->set_root_directory(name);
else if (name.empty() || *name.rbegin() == '/') else if (name.empty() || *name.rbegin() == '/')
download->set_root_directory(name + download->info()->name()); download->set_root_directory(name + download->info()->name().str());
else else
download->set_root_directory(name + "/" + download->info()->name()); download->set_root_directory(name + "/" + download->info()->name().str());
} }
torrent::Object torrent::Object
@@ -272,16 +275,6 @@ retrieve_d_custom_map(core::Download* download, bool keys_only, const torrent::O
return result; return result;
} }
torrent::Object
retrieve_d_bitfield(core::Download* download) {
const torrent::Bitfield* bitField = download->download()->file_list()->bitfield();
if (bitField->empty())
return torrent::Object("");
return torrent::Object(torrent::utils::transform_to_hex_str(*bitField));
}
void void
apply_d_add_peer(core::Download* download, const std::string& arg) { apply_d_add_peer(core::Download* download, const std::string& arg) {
int port, ret; int port, ret;
@@ -651,30 +644,36 @@ void cg_d_group_set(core::Download* download, const torrent::Objec
void void
initialize_command_download() { initialize_command_download() {
CMD2_DL("d.hash", [](auto* download, auto) { return torrent::utils::transform_to_hex_str(download->info()->hash()); }); CMD2_DL("d.hash", [](auto* download, auto) { return torrent::utils::transform_to_hex_str(download->info()->hash()); });
CMD2_DL("d.local_id", [](auto* download, auto) { return torrent::utils::transform_to_hex_str(download->info()->local_id()); }); CMD2_DL("d.local_id", [](auto* download, auto) { return torrent::utils::transform_to_hex_str(download->info()->local_id()); });
CMD2_DL("d.local_id_html", [](auto* download, auto) { return torrent::utils::copy_escape_html_str(download->info()->local_id()); }); CMD2_DL("d.local_id_html", [](auto* download, auto) { return torrent::utils::copy_escape_html_str(download->info()->local_id()); });
CMD2_DL("d.bitfield", std::bind(&retrieve_d_bitfield, std::placeholders::_1)); CMD2_DL("d.bitfield", [](auto* download, auto) { return torrent::utils::transform_to_hex_str(*download->download()->file_list()->bitfield()); });
CMD2_DL("d.base_path", std::bind(&retrieve_d_base_path, std::placeholders::_1)); CMD2_DL("d.base_path", [](auto* download, auto) { return retrieve_d_base_path(download).str(); });
CMD2_DL("d.base_filename", std::bind(&retrieve_d_base_filename, std::placeholders::_1)); CMD2_DL("d.base_path.base64", [](auto* download, auto) { return retrieve_d_base_path(download).object_base64(); });
CMD2_DL("d.base_path.or_base64", [](auto* download, auto) { return retrieve_d_base_path(download).object_utf8_or_base64(); });
CMD2_DL("d.base_filename", [](auto* download, auto) { return retrieve_d_base_filename(download).str(); });
CMD2_DL("d.base_filename.base64", [](auto* download, auto) { return retrieve_d_base_filename(download).object_base64(); });
CMD2_DL("d.base_filename.or_base64", [](auto* download, auto) { return retrieve_d_base_filename(download).object_utf8_or_base64(); });
CMD2_DL("d.name", CMD2_ON_INFO(name)); CMD2_DL("d.name", [](auto* download, auto) { return download->info()->name().str(); });
CMD2_DL("d.creation_date", CMD2_ON_INFO(creation_date)); CMD2_DL("d.name.base64", [](auto* download, auto) { return download->info()->name().object_base64(); });
CMD2_DL("d.load_date", CMD2_ON_INFO(load_date)); CMD2_DL("d.name.or_base64", [](auto* download, auto) { return download->info()->name().object_utf8_or_base64(); });
CMD2_DL("d.creation_date", [](auto* download, auto) { return download->info()->creation_date(); });
CMD2_DL("d.load_date", [](auto* download, auto) { return download->info()->load_date(); });
// //
// Network related: // Network related:
// //
CMD2_DL ("d.up.rate", std::bind(&torrent::Rate::rate, CMD2_ON_INFO(up_rate))); CMD2_DL ("d.up.rate", [](auto* download, auto) { return download->info()->up_rate()->rate(); });
CMD2_DL ("d.up.total", std::bind(&torrent::Rate::total, CMD2_ON_INFO(up_rate))); CMD2_DL ("d.up.total", [](auto* download, auto) { return download->info()->up_rate()->total(); });
CMD2_DL ("d.down.rate", std::bind(&torrent::Rate::rate, CMD2_ON_INFO(down_rate))); CMD2_DL ("d.down.rate", [](auto* download, auto) { return download->info()->down_rate()->rate(); });
CMD2_DL ("d.down.total", std::bind(&torrent::Rate::total, CMD2_ON_INFO(down_rate))); CMD2_DL ("d.down.total", [](auto* download, auto) { return download->info()->down_rate()->total(); });
CMD2_DL ("d.skip.rate", std::bind(&torrent::Rate::rate, CMD2_ON_INFO(skip_rate))); CMD2_DL ("d.skip.rate", [](auto* download, auto) { return download->info()->skip_rate()->rate(); });
CMD2_DL ("d.skip.total", std::bind(&torrent::Rate::total, CMD2_ON_INFO(skip_rate))); CMD2_DL ("d.skip.total", [](auto* download, auto) { return download->info()->skip_rate()->total(); });
CMD2_DL ("d.peer_exchange", CMD2_ON_INFO(is_pex_enabled)); CMD2_DL ("d.peer_exchange", [](auto* download, auto) { return download->info()->is_pex_enabled(); });
CMD2_DL_VALUE_V ("d.peer_exchange.set", std::bind(&torrent::Download::set_pex_enabled, CMD2_BIND_DL, std::placeholders::_2)); CMD2_DL_VALUE_V ("d.peer_exchange.set", [](auto* download, auto value) { download->download()->set_pex_enabled(value); });
CMD2_DL_LIST ("d.create_link", std::bind(&apply_d_change_link, std::placeholders::_1, std::placeholders::_2, 0)); CMD2_DL_LIST ("d.create_link", std::bind(&apply_d_change_link, std::placeholders::_1, std::placeholders::_2, 0));
CMD2_DL_LIST ("d.delete_link", std::bind(&apply_d_change_link, std::placeholders::_1, std::placeholders::_2, 1)); CMD2_DL_LIST ("d.delete_link", std::bind(&apply_d_change_link, std::placeholders::_1, std::placeholders::_2, 1));
@@ -690,16 +689,16 @@ initialize_command_download() {
// Control functinos: // Control functinos:
// //
CMD2_DL ("d.is_open", CMD2_ON_INFO(is_open)); CMD2_DL ("d.is_open", [](auto* download, auto) { return download->info()->is_open(); });
CMD2_DL ("d.is_active", CMD2_ON_INFO(is_active)); CMD2_DL ("d.is_active", [](auto* download, auto) { return download->info()->is_active(); });
CMD2_DL ("d.is_hash_checked", std::bind(&torrent::Download::is_hash_checked, CMD2_BIND_DL)); CMD2_DL ("d.is_hash_checked", std::bind(&torrent::Download::is_hash_checked, CMD2_BIND_DL));
CMD2_DL ("d.is_hash_checking", std::bind(&torrent::Download::is_hash_checking, CMD2_BIND_DL)); CMD2_DL ("d.is_hash_checking", std::bind(&torrent::Download::is_hash_checking, CMD2_BIND_DL));
CMD2_DL ("d.is_multi_file", std::bind(&torrent::FileList::is_multi_file, CMD2_BIND_FL)); CMD2_DL ("d.is_multi_file", std::bind(&torrent::FileList::is_multi_file, CMD2_BIND_FL));
CMD2_DL ("d.is_private", CMD2_ON_INFO(is_private)); CMD2_DL ("d.is_private", [](auto* download, auto) { return download->info()->is_private(); });
CMD2_DL ("d.is_pex_active", CMD2_ON_INFO(is_pex_active)); CMD2_DL ("d.is_pex_active", [](auto* download, auto) { return download->info()->is_pex_active(); });
CMD2_DL ("d.is_partially_done", CMD2_ON_DATA(is_partially_done)); CMD2_DL ("d.is_partially_done", CMD2_ON_DATA(is_partially_done));
CMD2_DL ("d.is_not_partially_done", CMD2_ON_DATA(is_not_partially_done)); CMD2_DL ("d.is_not_partially_done", CMD2_ON_DATA(is_not_partially_done));
CMD2_DL ("d.is_meta", CMD2_ON_INFO(is_meta_download)); CMD2_DL ("d.is_meta", [](auto* download, auto) { return download->info()->is_meta_download(); });
CMD2_DL_V ("d.resume", std::bind(&core::DownloadList::resume_default, control->core()->download_list(), std::placeholders::_1)); CMD2_DL_V ("d.resume", std::bind(&core::DownloadList::resume_default, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.pause", std::bind(&core::DownloadList::pause_default, control->core()->download_list(), std::placeholders::_1)); CMD2_DL_V ("d.pause", std::bind(&core::DownloadList::pause_default, control->core()->download_list(), std::placeholders::_1));
@@ -901,8 +900,14 @@ initialize_command_download() {
rpc::rpc.mark_safe("d.local_id_html"); rpc::rpc.mark_safe("d.local_id_html");
rpc::rpc.mark_safe("d.bitfield"); rpc::rpc.mark_safe("d.bitfield");
rpc::rpc.mark_safe("d.base_path"); rpc::rpc.mark_safe("d.base_path");
rpc::rpc.mark_safe("d.base_path.base64");
rpc::rpc.mark_safe("d.base_path.or_base64");
rpc::rpc.mark_safe("d.base_filename"); rpc::rpc.mark_safe("d.base_filename");
rpc::rpc.mark_safe("d.base_filename.base64");
rpc::rpc.mark_safe("d.base_filename.or_base64");
rpc::rpc.mark_safe("d.name"); rpc::rpc.mark_safe("d.name");
rpc::rpc.mark_safe("d.name.base64");
rpc::rpc.mark_safe("d.name.or_base64");
rpc::rpc.mark_safe("d.directory"); rpc::rpc.mark_safe("d.directory");
rpc::rpc.mark_safe("d.directory_base"); rpc::rpc.mark_safe("d.directory_base");
rpc::rpc.mark_safe("d.creation_date"); rpc::rpc.mark_safe("d.creation_date");
+41 -13
View File
@@ -24,24 +24,46 @@ apply_f_path(torrent::File* file) {
if (file->path()->empty()) if (file->path()->empty())
return std::string(); return std::string();
torrent::Object resultRaw(*file->path()->begin()); torrent::Object result_raw(file->path()->begin()->str());
torrent::Object::string_type& result = resultRaw.as_string(); auto& result = result_raw.as_string();
for (torrent::Path::const_iterator itr = ++file->path()->begin(), last = file->path()->end(); itr != last; itr++) for (torrent::Path::const_iterator itr = ++file->path()->begin(), last = file->path()->end(); itr != last; itr++)
result += '/' + *itr; result += '/' + itr->str();
return resultRaw; return result_raw;
} }
torrent::Object torrent::Object
apply_f_path_components(torrent::File* file) { apply_f_path_components(torrent::File* file) {
torrent::Object resultRaw = torrent::Object::create_list(); auto result_raw = torrent::Object::create_list();
torrent::Object::list_type& result = resultRaw.as_list(); auto& result = result_raw.as_list();
for (const auto& itr : *file->path()) for (const auto& itr : *file->path())
result.push_back(itr); result.push_back(itr.str());
return resultRaw; return result_raw;
}
torrent::Object
apply_f_path_components_base64(torrent::File* file) {
auto result_raw = torrent::Object::create_list();
auto& result = result_raw.as_list();
for (const auto& itr : *file->path())
result.push_back(itr.object_base64());
return result_raw;
}
torrent::Object
apply_f_path_components_or_base64(torrent::File* file) {
auto result_raw = torrent::Object::create_list();
auto& result = result_raw.as_list();
for (const auto& itr : *file->path())
result.push_back(itr.object_utf8_or_base64());
return result_raw;
} }
torrent::Object torrent::Object
@@ -57,7 +79,7 @@ apply_fi_filename_last(torrent::FileListIterator* itr) {
if (itr->depth() >= itr->file()->path()->size()) if (itr->depth() >= itr->file()->path()->size())
return "ERROR"; return "ERROR";
return itr->file()->path()->at(itr->depth()); return itr->file()->path()->at(itr->depth()).str();
} }
void void
@@ -91,10 +113,14 @@ initialize_command_file() {
CMD2_FILE("f.priority", std::bind(&torrent::File::priority, std::placeholders::_1)); CMD2_FILE("f.priority", std::bind(&torrent::File::priority, std::placeholders::_1));
CMD2_FILE_VALUE_V("f.priority.set", std::bind(&apply_f_set_priority, std::placeholders::_1, std::placeholders::_2)); CMD2_FILE_VALUE_V("f.priority.set", std::bind(&apply_f_set_priority, std::placeholders::_1, std::placeholders::_2));
CMD2_FILE("f.path", std::bind(&apply_f_path, std::placeholders::_1)); CMD2_FILE("f.path", [](auto* file, auto) { return apply_f_path(file); });
CMD2_FILE("f.path_components", std::bind(&apply_f_path_components, std::placeholders::_1)); CMD2_FILE("f.path_components", [](auto* file, auto) { return apply_f_path_components(file); });
CMD2_FILE("f.path_depth", std::bind(&apply_f_path_depth, std::placeholders::_1)); CMD2_FILE("f.path_components.base64", [](auto* file, auto) { return apply_f_path_components_base64(file); });
CMD2_FILE("f.frozen_path", std::bind(&torrent::File::frozen_path, std::placeholders::_1)); CMD2_FILE("f.path_components.or_base64", [](auto* file, auto) { return apply_f_path_components_or_base64(file); });
CMD2_FILE("f.path_depth", [](auto* file, auto) { return apply_f_path_depth(file); });
CMD2_FILE("f.frozen_path", [](auto* file, auto) { return file->frozen_path().str(); });
CMD2_FILE("f.frozen_path.base64", [](auto* file, auto) { return file->frozen_path().object_base64(); });
CMD2_FILE("f.frozen_path.or_base64", [](auto* file, auto) { return file->frozen_path().object_utf8_or_base64(); });
CMD2_FILE("f.match_depth_prev", std::bind(&torrent::File::match_depth_prev, std::placeholders::_1)); CMD2_FILE("f.match_depth_prev", std::bind(&torrent::File::match_depth_prev, std::placeholders::_1));
CMD2_FILE("f.match_depth_next", std::bind(&torrent::File::match_depth_next, std::placeholders::_1)); CMD2_FILE("f.match_depth_next", std::bind(&torrent::File::match_depth_next, std::placeholders::_1));
@@ -108,6 +134,8 @@ initialize_command_file() {
rpc::rpc.mark_safe("f.path_components"); rpc::rpc.mark_safe("f.path_components");
rpc::rpc.mark_safe("f.path_depth"); rpc::rpc.mark_safe("f.path_depth");
rpc::rpc.mark_safe("f.frozen_path"); rpc::rpc.mark_safe("f.frozen_path");
rpc::rpc.mark_safe("f.frozen_path.base64");
rpc::rpc.mark_safe("f.frozen_path.or_base64");
rpc::rpc.mark_safe("f.offset"); rpc::rpc.mark_safe("f.offset");
rpc::rpc.mark_safe("f.size_bytes"); rpc::rpc.mark_safe("f.size_bytes");
rpc::rpc.mark_safe("f.size_chunks"); rpc::rpc.mark_safe("f.size_chunks");
+1 -1
View File
@@ -116,7 +116,7 @@ Download::set_root_directory(const std::string& path) {
(file_list->is_multi_file() ? (file_list->is_multi_file() ?
!file_list->is_root_dir_created() : !file_list->is_root_dir_created() :
!file_stat.update(file_list->front()->frozen_path()))) { !file_stat.update(file_list->front()->frozen_path().str()))) {
set_message("Cannot change the directory of an open download after the files have been moved."); set_message("Cannot change the directory of an open download after the files have been moved.");
rpc::call_command("d.state.set", (int64_t)0, rpc::make_target(this)); rpc::call_command("d.state.set", (int64_t)0, rpc::make_target(this));
+6 -1
View File
@@ -683,8 +683,10 @@ DownloadList::process_meta_download(Download* download) {
rpc::call_command("d.stop", torrent::Object(), rpc::make_target(download)); rpc::call_command("d.stop", torrent::Object(), rpc::make_target(download));
rpc::call_command("d.close", torrent::Object(), rpc::make_target(download)); rpc::call_command("d.close", torrent::Object(), rpc::make_target(download));
std::string metafile = (*download->file_list()->begin())->frozen_path(); std::string metafile = (*download->file_list()->begin())->frozen_path().str();
std::fstream file(metafile.c_str(), std::ios::in | std::ios::binary); std::fstream file(metafile.c_str(), std::ios::in | std::ios::binary);
if (!file.is_open()) { if (!file.is_open()) {
lt_log_print(torrent::LOG_TORRENT_ERROR, "Could not read download metadata."); lt_log_print(torrent::LOG_TORRENT_ERROR, "Could not read download metadata.");
return; return;
@@ -692,11 +694,13 @@ DownloadList::process_meta_download(Download* download) {
torrent::Object* bencode = new torrent::Object(torrent::Object::create_map()); torrent::Object* bencode = new torrent::Object(torrent::Object::create_map());
file >> bencode->insert_key("info", torrent::Object()); file >> bencode->insert_key("info", torrent::Object());
if (file.fail()) { if (file.fail()) {
delete bencode; delete bencode;
lt_log_print(torrent::LOG_TORRENT_ERROR, "Could not create download, the input is not a valid torrent."); lt_log_print(torrent::LOG_TORRENT_ERROR, "Could not create download, the input is not a valid torrent.");
return; return;
} }
file.close(); file.close();
// Steal the keys we still need. The old download has no use for them. // Steal the keys we still need. The old download has no use for them.
@@ -707,6 +711,7 @@ DownloadList::process_meta_download(Download* download) {
bencode->insert_key("announce-list", torrent::Object()).swap(download->bencode()->get_key("announce-list")); bencode->insert_key("announce-list", torrent::Object()).swap(download->bencode()->get_key("announce-list"));
erase_ptr(download); erase_ptr(download);
control->core()->try_create_download_from_meta_download(bencode, metafile); control->core()->try_create_download_from_meta_download(bencode, metafile);
} }
+11 -4
View File
@@ -135,8 +135,11 @@ WindowFileList::redraw() {
m_canvas->print(0, pos, "%*c%-*s", 16, ' ', filenameWidth, "EMPTY"); m_canvas->print(0, pos, "%*c%-*s", 16, ' ', filenameWidth, "EMPTY");
} else if (itr.is_entering()) { } else if (itr.is_entering()) {
m_canvas->print(0, pos, "%*c %ls", 16 + itr.depth(), '\\', if (itr.depth() < itr.file()->path()->size())
itr.depth() < itr.file()->path()->size() ? wstring_width(itr.file()->path()->at(itr.depth()), filenameWidth - itr.depth() - 1).c_str() : L"UNKNOWN"); m_canvas->print(0, pos, "%*c %ls", 16 + itr.depth(), '\\',
wstring_width(itr.file()->path()->at(itr.depth()).str(), filenameWidth - itr.depth() - 1).c_str());
else
m_canvas->print(0, pos, "%*c %ls", 16 + itr.depth(), '\\', L"UNKNOWN");
} else if (itr.is_leaving()) { } else if (itr.is_leaving()) {
m_canvas->print(0, pos, "%*c %-*s", 16 + (itr.depth() - 1), '/', filenameWidth - (itr.depth() - 1), ""); m_canvas->print(0, pos, "%*c %-*s", 16 + (itr.depth() - 1), '/', filenameWidth - (itr.depth() - 1), "");
@@ -166,8 +169,12 @@ WindowFileList::redraw() {
else else
m_canvas->print(8, pos, "%5.1f T", (double)val / (int64_t(1) << 40)); m_canvas->print(8, pos, "%5.1f T", (double)val / (int64_t(1) << 40));
m_canvas->print(15, pos, "%*c %ls", 1 + itr.depth(), '|', if (itr.depth() < itr.file()->path()->size())
itr.depth() < itr.file()->path()->size() ? wstring_width(itr.file()->path()->at(itr.depth()), filenameWidth - itr.depth() - 1).c_str() : L"UNKNOWN"); m_canvas->print(15, pos, "%*c %ls", 1 + itr.depth(), '|',
wstring_width(itr.file()->path()->at(itr.depth()).str(), filenameWidth - itr.depth() - 1).c_str());
else
m_canvas->print(15, pos, "%*c %ls", 1 + itr.depth(), '|', L"UNKNOWN");
} else { } else {
m_canvas->print(0, pos, "BORK BORK"); m_canvas->print(0, pos, "BORK BORK");
+14
View File
@@ -6,6 +6,7 @@
#include <string> #include <string>
#include <torrent/common.h> #include <torrent/common.h>
#include <torrent/torrent.h> #include <torrent/torrent.h>
#include <torrent/utils/string_manip.h>
#include "rpc/rpc_manager.h" #include "rpc/rpc_manager.h"
#include "rpc/command.h" #include "rpc/command.h"
@@ -66,12 +67,23 @@ object_to_json(const torrent::Object& object) noexcept {
switch (object.type()) { switch (object.type()) {
case torrent::Object::TYPE_VALUE: case torrent::Object::TYPE_VALUE:
return object.as_value(); return object.as_value();
case torrent::Object::TYPE_STRING: case torrent::Object::TYPE_STRING:
if (object.flags() & torrent::Object::flag_base64) {
std::vector<uint8_t> binary_data;
torrent::utils::transform_from_hex(object.as_string(), binary_data);
return json::binary(binary_data);
}
return object.as_string(); return object.as_string();
case torrent::Object::TYPE_LIST: { case torrent::Object::TYPE_LIST: {
json result = json::array(); json result = json::array();
for (const auto& obj : object.as_list()) for (const auto& obj : object.as_list())
result.push_back(object_to_json(obj)); result.push_back(object_to_json(obj));
return result; return result;
} }
case torrent::Object::TYPE_MAP: { case torrent::Object::TYPE_MAP: {
@@ -135,7 +147,9 @@ jsonrpc_call_command(const std::string& method, const json& params) {
try { try {
const auto& result = rpc::commands.call_command(itr, params_object, target); const auto& result = rpc::commands.call_command(itr, params_object, target);
return object_to_json(result); return object_to_json(result);
} catch (untrusted_error& e) { } catch (untrusted_error& e) {
throw rpc_error(JSONRPC_METHOD_NOT_FOUND_ERROR, e.what()); throw rpc_error(JSONRPC_METHOD_NOT_FOUND_ERROR, e.what());
} }
+3
View File
@@ -278,6 +278,9 @@ object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) {
case torrent::Object::TYPE_STRING: case torrent::Object::TYPE_STRING:
{ {
if (object.flags() & torrent::Object::flag_base64)
return xmlrpc_base64_new(env, object.as_string().c_str(), object.as_string().size());
#ifdef XMLRPC_HAVE_I8 #ifdef XMLRPC_HAVE_I8
// The versions that support I8 do implicit utf-8 validation. // The versions that support I8 do implicit utf-8 validation.
xmlrpc_value* result = xmlrpc_string_new(env, object.as_string().c_str()); xmlrpc_value* result = xmlrpc_string_new(env, object.as_string().c_str());
+8
View File
@@ -152,10 +152,18 @@ void
print_object_xml(const torrent::Object& obj, tinyxml2::XMLPrinter* printer) { print_object_xml(const torrent::Object& obj, tinyxml2::XMLPrinter* printer) {
switch (obj.type()) { switch (obj.type()) {
case torrent::Object::TYPE_STRING: case torrent::Object::TYPE_STRING:
if (obj.flags() & torrent::Object::flag_base64) {
printer->OpenElement("base64", true);
printer->PushText(obj.as_string().c_str());
printer->CloseElement(true);
break;
}
printer->OpenElement("string", true); printer->OpenElement("string", true);
printer->PushText(obj.as_string().c_str()); printer->PushText(obj.as_string().c_str());
printer->CloseElement(true); printer->CloseElement(true);
break; break;
case torrent::Object::TYPE_VALUE: case torrent::Object::TYPE_VALUE:
printer->OpenElement("i8", true); printer->OpenElement("i8", true);
printer->PushText(std::to_string(obj.as_value()).c_str()); printer->PushText(std::to_string(obj.as_value()).c_str());
+1 -1
View File
@@ -250,7 +250,7 @@ Download::activate_display(Display displayType, bool focusDisplay) {
// Set title. // Set title.
switch (displayType) { switch (displayType) {
case DISPLAY_MAX_SIZE: break; case DISPLAY_MAX_SIZE: break;
default: control->ui()->window_title()->set_title(m_download->info()->name()); break; default: control->ui()->window_title()->set_title(m_download->info()->name().str()); break;
} }
control->display()->adjust_layout(); control->display()->adjust_layout();