mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-13 04:36:16 +00:00
Moved base64 transform and validation functions.
This commit is contained in:
+10
-6
@@ -16,7 +16,6 @@
|
|||||||
#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 {
|
||||||
|
|
||||||
@@ -35,24 +34,29 @@ json_to_object(const json& value) {
|
|||||||
case json::value_t::number_unsigned:
|
case json::value_t::number_unsigned:
|
||||||
case json::value_t::number_integer:
|
case json::value_t::number_integer:
|
||||||
return torrent::Object(value.get<int64_t>());
|
return torrent::Object(value.get<int64_t>());
|
||||||
|
|
||||||
case json::value_t::boolean:
|
case json::value_t::boolean:
|
||||||
return value.get<bool>() ? torrent::Object(int64_t(1)) : torrent::Object(int64_t(0));
|
return value.get<bool>() ? torrent::Object(int64_t(1)) : torrent::Object(int64_t(0));
|
||||||
|
|
||||||
case json::value_t::string:
|
case json::value_t::string:
|
||||||
return torrent::Object(value.get<std::string>());
|
return torrent::Object(value.get<std::string>());
|
||||||
|
|
||||||
case json::value_t::array: {
|
case json::value_t::array: {
|
||||||
auto array_raw = torrent::Object::create_list();
|
auto array_raw = torrent::Object::create_list();
|
||||||
auto& array = array_raw.as_list();
|
auto& array = array_raw.as_list();
|
||||||
for (const auto& entry : value) {
|
|
||||||
|
for (const auto& entry : value)
|
||||||
array.push_back(json_to_object(entry));
|
array.push_back(json_to_object(entry));
|
||||||
}
|
|
||||||
return array_raw;
|
return array_raw;
|
||||||
}
|
}
|
||||||
case json::value_t::object: {
|
case json::value_t::object: {
|
||||||
auto map_raw = torrent::Object::create_map();
|
auto map_raw = torrent::Object::create_map();
|
||||||
auto& map = map_raw.as_map();
|
auto& map = map_raw.as_map();
|
||||||
for (const auto& entry : value.items()) {
|
|
||||||
|
for (const auto& entry : value.items())
|
||||||
map[entry.key()] = json_to_object(entry.value());
|
map[entry.key()] = json_to_object(entry.value());
|
||||||
}
|
|
||||||
return map_raw;
|
return map_raw;
|
||||||
}
|
}
|
||||||
case json::value_t::number_float:
|
case json::value_t::number_float:
|
||||||
@@ -76,7 +80,7 @@ object_to_json(const torrent::Object& object) {
|
|||||||
|
|
||||||
// We should optimize our imported json library to support copying base64 strings directly.
|
// We should optimize our imported json library to support copying base64 strings directly.
|
||||||
if (object.flags() & torrent::Object::flag_base64) {
|
if (object.flags() & torrent::Object::flag_base64) {
|
||||||
auto binary_data = utils::base64_to_vector_unsafe(object.as_string());
|
auto binary_data = torrent::utils::transform_from_base64_unsafe(object.as_string());
|
||||||
|
|
||||||
if (!binary_data.has_value())
|
if (!binary_data.has_value())
|
||||||
throw rpc_error(JSONRPC_INTERNAL_ERROR, "invalid base64 string in base64-as-binary object");
|
throw rpc_error(JSONRPC_INTERNAL_ERROR, "invalid base64 string in base64-as-binary object");
|
||||||
|
|||||||
+1
-1
@@ -282,7 +282,7 @@ object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) {
|
|||||||
|
|
||||||
// This causes decode-and-reencode for base64, as XMLRPC-C doesn't allow us to pass base64 strings.
|
// 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) {
|
if (object.flags() & torrent::Object::flag_base64) {
|
||||||
auto binary_data = utils::base64_to_vector_unsafe(object.as_string());
|
auto binary_data = torrent::utils::transform_from_base64_unsafe(object.as_string());
|
||||||
|
|
||||||
if (!binary_data.has_value())
|
if (!binary_data.has_value())
|
||||||
throw torrent::input_error("invalid base64 string in base64-as-binary object");
|
throw torrent::input_error("invalid base64 string in base64-as-binary object");
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <torrent/exceptions.h>
|
#include <torrent/exceptions.h>
|
||||||
#include <torrent/object.h>
|
#include <torrent/object.h>
|
||||||
|
#include <torrent/utils/string_manip.h>
|
||||||
|
|
||||||
#include "parse_commands.h"
|
#include "parse_commands.h"
|
||||||
#include "rpc/tinyxml2/tinyxml2.h"
|
#include "rpc/tinyxml2/tinyxml2.h"
|
||||||
@@ -162,7 +163,7 @@ print_object_xml(const torrent::Object& obj, tinyxml2::XMLPrinter* printer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printer->OpenElement("base64", true);
|
printer->OpenElement("base64", true);
|
||||||
printer->PushText(utils::openssl_base64_encode(obj.as_string()).c_str());
|
printer->PushText(torrent::utils::transform_to_base64(obj.as_string()).c_str());
|
||||||
printer->CloseElement(true);
|
printer->CloseElement(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <openssl/evp.h>
|
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
@@ -72,50 +71,4 @@ 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
|
||||||
|
|||||||
@@ -8,10 +8,6 @@
|
|||||||
|
|
||||||
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.
|
// 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