mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-20 16:16:17 +00:00
Added hex to Object and string_utf8.
This commit is contained in:
+45
-21
@@ -644,33 +644,45 @@ 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", [](auto* download, auto) { return torrent::utils::transform_to_hex_str(*download->download()->file_list()->bitfield()); });
|
CMD2_DL("d.bitfield", [](auto* download, auto) { return torrent::utils::transform_to_hex_str(*download->download()->file_list()->bitfield()); });
|
||||||
CMD2_DL("d.base_path", [](auto* download, auto) { return retrieve_d_base_path(download).str(); });
|
CMD2_DL("d.base_path", [](auto* download, auto) { return retrieve_d_base_path(download).str(); });
|
||||||
CMD2_DL("d.base_path.base64", [](auto* download, auto) { return retrieve_d_base_path(download).object_base64(); });
|
CMD2_DL("d.base_path.hex", [](auto* download, auto) { return retrieve_d_base_path(download).object_hex(); });
|
||||||
CMD2_DL("d.base_path.or_base64", [](auto* download, auto) { return retrieve_d_base_path(download).object_utf8_or_base64(); });
|
CMD2_DL("d.base_path.base64", [](auto* download, auto) { return retrieve_d_base_path(download).object_base64(); });
|
||||||
CMD2_DL("d.base_filename", [](auto* download, auto) { return retrieve_d_base_filename(download).str(); });
|
CMD2_DL("d.base_path.base64_as_binary", [](auto* download, auto) { return retrieve_d_base_path(download).object_base64_as_binary(); });
|
||||||
CMD2_DL("d.base_filename.base64", [](auto* download, auto) { return retrieve_d_base_filename(download).object_base64(); });
|
CMD2_DL("d.base_path.as_binary", [](auto* download, auto) { return retrieve_d_base_path(download).object_as_binary(); });
|
||||||
CMD2_DL("d.base_filename.or_base64", [](auto* download, auto) { return retrieve_d_base_filename(download).object_utf8_or_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_path.or_as_binary", [](auto* download, auto) { return retrieve_d_base_path(download).object_utf8_or_as_binary(); });
|
||||||
|
CMD2_DL("d.base_filename", [](auto* download, auto) { return retrieve_d_base_filename(download).str(); });
|
||||||
|
CMD2_DL("d.base_filename.hex", [](auto* download, auto) { return retrieve_d_base_filename(download).object_hex(); });
|
||||||
|
CMD2_DL("d.base_filename.base64", [](auto* download, auto) { return retrieve_d_base_filename(download).object_base64(); });
|
||||||
|
CMD2_DL("d.base_filename.base64_as_binary", [](auto* download, auto) { return retrieve_d_base_filename(download).object_base64_as_binary(); });
|
||||||
|
CMD2_DL("d.base_filename.as_binary", [](auto* download, auto) { return retrieve_d_base_filename(download).object_as_binary(); });
|
||||||
|
CMD2_DL("d.base_filename.or_base64", [](auto* download, auto) { return retrieve_d_base_filename(download).object_utf8_or_base64(); });
|
||||||
|
CMD2_DL("d.base_filename.or_as_binary", [](auto* download, auto) { return retrieve_d_base_filename(download).object_utf8_or_as_binary(); });
|
||||||
|
|
||||||
CMD2_DL("d.name", [](auto* download, auto) { return download->info()->name().str(); });
|
CMD2_DL("d.name", [](auto* download, auto) { return download->info()->name().str(); });
|
||||||
CMD2_DL("d.name.base64", [](auto* download, auto) { return download->info()->name().object_base64(); });
|
CMD2_DL("d.name.hex", [](auto* download, auto) { return download->info()->name().object_hex(); });
|
||||||
CMD2_DL("d.name.or_base64", [](auto* download, auto) { return download->info()->name().object_utf8_or_base64(); });
|
CMD2_DL("d.name.base64", [](auto* download, auto) { return download->info()->name().object_base64(); });
|
||||||
CMD2_DL("d.creation_date", [](auto* download, auto) { return download->info()->creation_date(); });
|
CMD2_DL("d.name.base64_as_binary", [](auto* download, auto) { return download->info()->name().object_base64_as_binary(); });
|
||||||
CMD2_DL("d.load_date", [](auto* download, auto) { return download->info()->load_date(); });
|
CMD2_DL("d.name.as_binary", [](auto* download, auto) { return download->info()->name().object_as_binary(); });
|
||||||
|
CMD2_DL("d.name.or_base64", [](auto* download, auto) { return download->info()->name().object_utf8_or_base64(); });
|
||||||
|
CMD2_DL("d.name.or_as_binary", [](auto* download, auto) { return download->info()->name().object_utf8_or_as_binary(); });
|
||||||
|
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", [](auto* download, auto) { return download->info()->up_rate()->rate(); });
|
CMD2_DL ("d.up.rate", [](auto* download, auto) { return download->info()->up_rate()->rate(); });
|
||||||
CMD2_DL ("d.up.total", [](auto* download, auto) { return download->info()->up_rate()->total(); });
|
CMD2_DL ("d.up.total", [](auto* download, auto) { return download->info()->up_rate()->total(); });
|
||||||
CMD2_DL ("d.down.rate", [](auto* download, auto) { return download->info()->down_rate()->rate(); });
|
CMD2_DL ("d.down.rate", [](auto* download, auto) { return download->info()->down_rate()->rate(); });
|
||||||
CMD2_DL ("d.down.total", [](auto* download, auto) { return download->info()->down_rate()->total(); });
|
CMD2_DL ("d.down.total", [](auto* download, auto) { return download->info()->down_rate()->total(); });
|
||||||
CMD2_DL ("d.skip.rate", [](auto* download, auto) { return download->info()->skip_rate()->rate(); });
|
CMD2_DL ("d.skip.rate", [](auto* download, auto) { return download->info()->skip_rate()->rate(); });
|
||||||
CMD2_DL ("d.skip.total", [](auto* download, auto) { return download->info()->skip_rate()->total(); });
|
CMD2_DL ("d.skip.total", [](auto* download, auto) { return download->info()->skip_rate()->total(); });
|
||||||
|
|
||||||
CMD2_DL ("d.peer_exchange", [](auto* download, auto) { return download->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", [](auto* download, auto value) { download->download()->set_pex_enabled(value); });
|
CMD2_DL_VALUE_V ("d.peer_exchange.set", [](auto* download, auto value) { download->download()->set_pex_enabled(value); });
|
||||||
@@ -900,14 +912,26 @@ 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.hex");
|
||||||
rpc::rpc.mark_safe("d.base_path.base64");
|
rpc::rpc.mark_safe("d.base_path.base64");
|
||||||
|
rpc::rpc.mark_safe("d.base_path.base64_as_binary");
|
||||||
|
rpc::rpc.mark_safe("d.base_path.as_binary");
|
||||||
rpc::rpc.mark_safe("d.base_path.or_base64");
|
rpc::rpc.mark_safe("d.base_path.or_base64");
|
||||||
|
rpc::rpc.mark_safe("d.base_path.or_as_binary");
|
||||||
rpc::rpc.mark_safe("d.base_filename");
|
rpc::rpc.mark_safe("d.base_filename");
|
||||||
|
rpc::rpc.mark_safe("d.base_filename.hex");
|
||||||
rpc::rpc.mark_safe("d.base_filename.base64");
|
rpc::rpc.mark_safe("d.base_filename.base64");
|
||||||
|
rpc::rpc.mark_safe("d.base_filename.base64_as_binary");
|
||||||
|
rpc::rpc.mark_safe("d.base_filename.as_binary");
|
||||||
rpc::rpc.mark_safe("d.base_filename.or_base64");
|
rpc::rpc.mark_safe("d.base_filename.or_base64");
|
||||||
|
rpc::rpc.mark_safe("d.base_filename.or_as_binary");
|
||||||
rpc::rpc.mark_safe("d.name");
|
rpc::rpc.mark_safe("d.name");
|
||||||
|
rpc::rpc.mark_safe("d.name.hex");
|
||||||
rpc::rpc.mark_safe("d.name.base64");
|
rpc::rpc.mark_safe("d.name.base64");
|
||||||
|
rpc::rpc.mark_safe("d.name.base64_as_binary");
|
||||||
|
rpc::rpc.mark_safe("d.name.as_binary");
|
||||||
rpc::rpc.mark_safe("d.name.or_base64");
|
rpc::rpc.mark_safe("d.name.or_base64");
|
||||||
|
rpc::rpc.mark_safe("d.name.or_as_binary");
|
||||||
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");
|
||||||
|
|||||||
+40
-41
@@ -34,34 +34,22 @@ apply_f_path(torrent::File* file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
apply_f_path_components(torrent::File* file) {
|
apply_f_path_components(torrent::File* file, int output_type) {
|
||||||
auto result_raw = torrent::Object::create_list();
|
auto result_raw = torrent::Object::create_list();
|
||||||
auto& result = result_raw.as_list();
|
auto& result = result_raw.as_list();
|
||||||
|
|
||||||
for (const auto& itr : *file->path())
|
for (const auto& itr : *file->path()) {
|
||||||
result.push_back(itr.str());
|
switch (output_type) {
|
||||||
|
case 0: result.push_back(itr.str()); break;
|
||||||
return result_raw;
|
case 1: result.push_back(itr.object_hex()); break;
|
||||||
}
|
case 2: result.push_back(itr.object_base64()); break;
|
||||||
|
case 3: result.push_back(itr.object_base64_as_binary()); break;
|
||||||
torrent::Object
|
case 4: result.push_back(itr.object_as_binary()); break;
|
||||||
apply_f_path_components_base64(torrent::File* file) {
|
case 5: result.push_back(itr.object_utf8_or_base64()); break;
|
||||||
auto result_raw = torrent::Object::create_list();
|
case 6: result.push_back(itr.object_utf8_or_as_binary()); break;
|
||||||
auto& result = result_raw.as_list();
|
default: throw torrent::input_error("apply_f_path_components(): invalid output type");
|
||||||
|
};
|
||||||
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;
|
return result_raw;
|
||||||
}
|
}
|
||||||
@@ -102,25 +90,32 @@ initialize_command_file() {
|
|||||||
CMD2_FILE_V("f.prioritize_last.enable", std::bind(&torrent::File::set_flags, std::placeholders::_1, torrent::File::flag_prioritize_last));
|
CMD2_FILE_V("f.prioritize_last.enable", std::bind(&torrent::File::set_flags, std::placeholders::_1, torrent::File::flag_prioritize_last));
|
||||||
CMD2_FILE_V("f.prioritize_last.disable", std::bind(&torrent::File::unset_flags, std::placeholders::_1, torrent::File::flag_prioritize_last));
|
CMD2_FILE_V("f.prioritize_last.disable", std::bind(&torrent::File::unset_flags, std::placeholders::_1, torrent::File::flag_prioritize_last));
|
||||||
|
|
||||||
CMD2_FILE("f.size_bytes", std::bind(&torrent::File::size_bytes, std::placeholders::_1));
|
CMD2_FILE("f.size_bytes", [](auto* file, auto) { return file->size_bytes(); });
|
||||||
CMD2_FILE("f.size_chunks", std::bind(&torrent::File::size_chunks, std::placeholders::_1));
|
CMD2_FILE("f.size_chunks", [](auto* file, auto) { return file->size_chunks(); });
|
||||||
CMD2_FILE("f.completed_chunks", std::bind(&torrent::File::completed_chunks, std::placeholders::_1));
|
CMD2_FILE("f.completed_chunks", [](auto* file, auto) { return file->completed_chunks(); });
|
||||||
|
|
||||||
CMD2_FILE("f.offset", std::bind(&torrent::File::offset, std::placeholders::_1));
|
CMD2_FILE("f.offset", [](auto* file, auto) { return file->offset(); });
|
||||||
CMD2_FILE("f.range_first", std::bind(&torrent::File::range_first, std::placeholders::_1));
|
CMD2_FILE("f.range_first", [](auto* file, auto) { return file->range_first(); });
|
||||||
CMD2_FILE("f.range_second", std::bind(&torrent::File::range_second, std::placeholders::_1));
|
CMD2_FILE("f.range_second", [](auto* file, auto) { return file->range_second(); });
|
||||||
|
|
||||||
CMD2_FILE("f.priority", std::bind(&torrent::File::priority, std::placeholders::_1));
|
CMD2_FILE("f.priority", [](auto* file, auto) { return file->priority(); });
|
||||||
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", [](auto* file, auto v) { apply_f_set_priority(file, v); });
|
||||||
|
|
||||||
CMD2_FILE("f.path", [](auto* file, auto) { return apply_f_path(file); });
|
CMD2_FILE("f.path", [](auto* file, auto) { return apply_f_path(file); });
|
||||||
CMD2_FILE("f.path_components", [](auto* file, auto) { return apply_f_path_components(file); });
|
CMD2_FILE("f.path_components", [](auto* file, auto) { return apply_f_path_components(file, 0); });
|
||||||
CMD2_FILE("f.path_components.base64", [](auto* file, auto) { return apply_f_path_components_base64(file); });
|
CMD2_FILE("f.path_components.hex", [](auto* file, auto) { return apply_f_path_components(file, 1); });
|
||||||
CMD2_FILE("f.path_components.or_base64", [](auto* file, auto) { return apply_f_path_components_or_base64(file); });
|
CMD2_FILE("f.path_components.base64", [](auto* file, auto) { return apply_f_path_components(file, 2); });
|
||||||
CMD2_FILE("f.path_depth", [](auto* file, auto) { return apply_f_path_depth(file); });
|
CMD2_FILE("f.path_components.base64_as_binary", [](auto* file, auto) { return apply_f_path_components(file, 3); });
|
||||||
CMD2_FILE("f.frozen_path", [](auto* file, auto) { return file->frozen_path().str(); });
|
CMD2_FILE("f.path_components.as_binary", [](auto* file, auto) { return apply_f_path_components(file, 4); });
|
||||||
CMD2_FILE("f.frozen_path.base64", [](auto* file, auto) { return file->frozen_path().object_base64(); });
|
CMD2_FILE("f.path_components.or_base64", [](auto* file, auto) { return apply_f_path_components(file, 5); });
|
||||||
CMD2_FILE("f.frozen_path.or_base64", [](auto* file, auto) { return file->frozen_path().object_utf8_or_base64(); });
|
CMD2_FILE("f.path_components.or_as_binary", [](auto* file, auto) { return apply_f_path_components(file, 6); });
|
||||||
|
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.hex", [](auto* file, auto) { return file->frozen_path().object_hex(); });
|
||||||
|
CMD2_FILE("f.frozen_path.base64", [](auto* file, auto) { return file->frozen_path().object_base64(); });
|
||||||
|
CMD2_FILE("f.frozen_path.as_binary", [](auto* file, auto) { return file->frozen_path().object_as_binary(); });
|
||||||
|
CMD2_FILE("f.frozen_path.or_base64", [](auto* file, auto) { return file->frozen_path().object_utf8_or_base64(); });
|
||||||
|
CMD2_FILE("f.frozen_path.or_as_binary", [](auto* file, auto) { return file->frozen_path().object_utf8_or_as_binary(); });
|
||||||
|
|
||||||
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));
|
||||||
@@ -134,8 +129,12 @@ 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.hex");
|
||||||
rpc::rpc.mark_safe("f.frozen_path.base64");
|
rpc::rpc.mark_safe("f.frozen_path.base64");
|
||||||
|
rpc::rpc.mark_safe("f.frozen_path.base64_as_binary");
|
||||||
|
rpc::rpc.mark_safe("f.frozen_path.as_binary");
|
||||||
rpc::rpc.mark_safe("f.frozen_path.or_base64");
|
rpc::rpc.mark_safe("f.frozen_path.or_base64");
|
||||||
|
rpc::rpc.mark_safe("f.frozen_path.or_as_binary");
|
||||||
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");
|
||||||
|
|||||||
+16
-5
@@ -16,6 +16,7 @@
|
|||||||
#include "torrent/exceptions.h"
|
#include "torrent/exceptions.h"
|
||||||
#include "torrent/object.h"
|
#include "torrent/object.h"
|
||||||
#include "utils/functional.h"
|
#include "utils/functional.h"
|
||||||
|
#include "utils/base64.h"
|
||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
|
|
||||||
@@ -62,18 +63,28 @@ json_to_object(const json& value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: Only throw rpc_errors here.
|
||||||
|
|
||||||
json
|
json
|
||||||
object_to_json(const torrent::Object& object) noexcept {
|
object_to_json(const torrent::Object& object) {
|
||||||
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) {
|
if (object.flags() & torrent::Object::flag_as_binary) {
|
||||||
std::vector<uint8_t> binary_data;
|
|
||||||
torrent::utils::transform_from_hex(object.as_string(), binary_data);
|
|
||||||
|
|
||||||
return json::binary(binary_data);
|
// We should optimize our imported json library to support copying base64 strings directly.
|
||||||
|
if (object.flags() & torrent::Object::flag_base64) {
|
||||||
|
auto binary_data = utils::base64_to_vector_unsafe(object.as_string());
|
||||||
|
|
||||||
|
if (!binary_data.has_value())
|
||||||
|
throw rpc_error(JSONRPC_INTERNAL_ERROR, "invalid base64 string in base64-as-binary object");
|
||||||
|
|
||||||
|
return json::binary(*binary_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json::binary({object.as_string().begin(), object.as_string().end()});
|
||||||
}
|
}
|
||||||
|
|
||||||
return object.as_string();
|
return object.as_string();
|
||||||
|
|||||||
+13
-1
@@ -278,8 +278,20 @@ 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)
|
if (object.flags() & torrent::Object::flag_binary) {
|
||||||
|
|
||||||
|
// This causes decode-and-reencode for base64, as XMLRPC-C doesn't allow us to pass base64 strings.
|
||||||
|
if (object.flags() & torrent::Object::flag_base64) {
|
||||||
|
auto binary_data = utils::base64_to_vector_unsafe(object.as_string());
|
||||||
|
|
||||||
|
if (!binary_data.has_value())
|
||||||
|
throw torrent::input_error("invalid base64 string in base64-as-binary object");
|
||||||
|
|
||||||
|
return xmlrpc_base64_new(env, (const char*)binary_data->data(), binary_data->size());
|
||||||
|
}
|
||||||
|
|
||||||
return xmlrpc_base64_new(env, object.as_string().c_str(), object.as_string().size());
|
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.
|
||||||
|
|||||||
@@ -152,9 +152,17 @@ 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) {
|
if (obj.flags() & torrent::Object::flag_as_binary) {
|
||||||
|
// It is optimal for tinyxml2 to pass base64 strings directly from torrent::string_utf8 sources.
|
||||||
|
if (obj.flags() & torrent::Object::flag_base64) {
|
||||||
|
printer->OpenElement("base64", true);
|
||||||
|
printer->PushText(obj.as_string().c_str());
|
||||||
|
printer->CloseElement(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
printer->OpenElement("base64", true);
|
printer->OpenElement("base64", true);
|
||||||
printer->PushText(obj.as_string().c_str());
|
printer->PushText(utils::openssl_base64_encode(obj.as_string()).c_str());
|
||||||
printer->CloseElement(true);
|
printer->CloseElement(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -169,6 +177,7 @@ print_object_xml(const torrent::Object& obj, tinyxml2::XMLPrinter* printer) {
|
|||||||
printer->PushText(std::to_string(obj.as_value()).c_str());
|
printer->PushText(std::to_string(obj.as_value()).c_str());
|
||||||
printer->CloseElement(true);
|
printer->CloseElement(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case torrent::Object::TYPE_LIST:
|
case torrent::Object::TYPE_LIST:
|
||||||
printer->OpenElement("array", true);
|
printer->OpenElement("array", true);
|
||||||
printer->OpenElement("data", true);
|
printer->OpenElement("data", true);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
@@ -70,4 +71,51 @@ decode_base64(const std::string& input) {
|
|||||||
}
|
}
|
||||||
return decodedBytes;
|
return decodedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move to torrent::utils.
|
||||||
|
|
||||||
|
std::optional<std::vector<uint8_t>>
|
||||||
|
base64_to_vector_unsafe(const std::string& src) {
|
||||||
|
if (src.empty())
|
||||||
|
return std::vector<uint8_t>{};
|
||||||
|
|
||||||
|
if (src.length() % 4)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
std::vector<uint8_t> bytes((src.length() * 3) / 4);
|
||||||
|
|
||||||
|
int decoded_len = EVP_DecodeBlock(bytes.data(), reinterpret_cast<const uint8_t*>(src.data()), src.length());
|
||||||
|
|
||||||
|
if (decoded_len <= 0)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
if (src.back() == '=')
|
||||||
|
decoded_len--;
|
||||||
|
|
||||||
|
if (src.length() > 1 && src[src.length() - 2] == '=')
|
||||||
|
decoded_len--;
|
||||||
|
|
||||||
|
// If the input contains extra padding characters, this could cause negative decoded_len.
|
||||||
|
if (decoded_len < 0)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
bytes.resize(decoded_len);
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
openssl_base64_encode(const std::string& src) {
|
||||||
|
if (src.empty()) return {};
|
||||||
|
|
||||||
|
std::string result((4 * ((src.size() + 2) / 3)), '\0');
|
||||||
|
|
||||||
|
int actual_length = EVP_EncodeBlock(reinterpret_cast<unsigned char*>(result.data()),
|
||||||
|
reinterpret_cast<const unsigned char*>(src.data()),
|
||||||
|
src.size());
|
||||||
|
|
||||||
|
result.resize(actual_length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|||||||
+7
-1
@@ -1,12 +1,18 @@
|
|||||||
#ifndef RTORRENT_UTILS_BASE64_H
|
#ifndef RTORRENT_UTILS_BASE64_H
|
||||||
#define RTORRENT_UTILS_BASE64_H
|
#define RTORRENT_UTILS_BASE64_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <torrent/exceptions.h>
|
#include <torrent/exceptions.h>
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
|
// TODO: Refactor and move to torrent/string_manip.h.
|
||||||
|
std::optional<std::vector<uint8_t>> base64_to_vector_unsafe(const std::string& src);
|
||||||
|
std::string openssl_base64_encode(const std::string& src);
|
||||||
|
|
||||||
|
// TODO: Deprecate.
|
||||||
std::string remove_newlines(const std::string& str);
|
std::string remove_newlines(const std::string& str);
|
||||||
std::string decode_base64(const std::string& input);
|
std::string decode_base64(const std::string& input);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user