mirror of
https://github.com/transmission/transmission.git
synced 2025-12-24 12:28:52 +00:00
Refactor/tr variant from buf (#3592)
* refactor: use std::string in tr_watchdir_inotify_on_event() * refactor: add template tr_variantFromBuf() variant if it has .data() and .size() it is good
This commit is contained in:
@@ -1346,14 +1346,15 @@ static void parseUtMetadata(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuf
|
|||||||
int64_t msg_type = -1;
|
int64_t msg_type = -1;
|
||||||
int64_t piece = -1;
|
int64_t piece = -1;
|
||||||
int64_t total_size = 0;
|
int64_t total_size = 0;
|
||||||
auto* const tmp = tr_new(char, msglen);
|
|
||||||
|
|
||||||
tr_peerIoReadBytes(msgs->io, inbuf, tmp, msglen);
|
auto tmp = std::vector<char>{};
|
||||||
char const* const msg_end = (char const*)tmp + msglen;
|
tmp.resize(msglen);
|
||||||
|
tr_peerIoReadBytes(msgs->io, inbuf, std::data(tmp), std::size(tmp));
|
||||||
|
char const* const msg_end = std::data(tmp) + std::size(tmp);
|
||||||
|
|
||||||
auto dict = tr_variant{};
|
auto dict = tr_variant{};
|
||||||
char const* benc_end = nullptr;
|
char const* benc_end = nullptr;
|
||||||
if (tr_variantFromBuf(&dict, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, { tmp, msglen }, &benc_end))
|
if (tr_variantFromBuf(&dict, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, tmp, &benc_end))
|
||||||
{
|
{
|
||||||
(void)tr_variantDictFindInt(&dict, TR_KEY_msg_type, &msg_type);
|
(void)tr_variantDictFindInt(&dict, TR_KEY_msg_type, &msg_type);
|
||||||
(void)tr_variantDictFindInt(&dict, TR_KEY_piece, &piece);
|
(void)tr_variantDictFindInt(&dict, TR_KEY_piece, &piece);
|
||||||
@@ -1408,8 +1409,6 @@ static void parseUtMetadata(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuf
|
|||||||
tr_variantFree(&v);
|
tr_variantFree(&v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_free(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parseUtPex(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuffer* inbuf)
|
static void parseUtPex(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuffer* inbuf)
|
||||||
@@ -1420,10 +1419,11 @@ static void parseUtPex(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuffer*
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* tmp = tr_new(char, msglen);
|
auto tmp = std::vector<char>{};
|
||||||
tr_peerIoReadBytes(msgs->io, inbuf, tmp, msglen);
|
tmp.resize(msglen);
|
||||||
|
tr_peerIoReadBytes(msgs->io, inbuf, std::data(tmp), std::size(tmp));
|
||||||
|
|
||||||
if (tr_variant val; tr_variantFromBuf(&val, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, { tmp, msglen }))
|
if (tr_variant val; tr_variantFromBuf(&val, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, tmp))
|
||||||
{
|
{
|
||||||
uint8_t const* added = nullptr;
|
uint8_t const* added = nullptr;
|
||||||
auto added_len = size_t{};
|
auto added_len = size_t{};
|
||||||
@@ -1459,8 +1459,6 @@ static void parseUtPex(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuffer*
|
|||||||
|
|
||||||
tr_variantFree(&val);
|
tr_variantFree(&val);
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_free(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sendPex(tr_peerMsgsImpl* msgs);
|
static void sendPex(tr_peerMsgsImpl* msgs);
|
||||||
|
|||||||
@@ -669,12 +669,7 @@ static auto loadFromFile(tr_torrent* tor, tr_resume::fields_t fieldsToLoad, bool
|
|||||||
tr_error* error = nullptr;
|
tr_error* error = nullptr;
|
||||||
auto top = tr_variant{};
|
auto top = tr_variant{};
|
||||||
if (!tr_loadFile(filename, buf, &error) ||
|
if (!tr_loadFile(filename, buf, &error) ||
|
||||||
!tr_variantFromBuf(
|
!tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, buf, nullptr, &error))
|
||||||
&top,
|
|
||||||
TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE,
|
|
||||||
{ std::data(buf), std::size(buf) },
|
|
||||||
nullptr,
|
|
||||||
&error))
|
|
||||||
{
|
{
|
||||||
tr_logAddDebugTor(tor, fmt::format("Couldn't read '{}': {}", filename, error->message));
|
tr_logAddDebugTor(tor, fmt::format("Couldn't read '{}': {}", filename, error->message));
|
||||||
tr_error_clear(&error);
|
tr_error_clear(&error);
|
||||||
|
|||||||
@@ -262,12 +262,7 @@ static bool useNewMetainfo(tr_torrent* tor, tr_incomplete_metadata const* m, tr_
|
|||||||
|
|
||||||
// checksum passed; now try to parse it as benc
|
// checksum passed; now try to parse it as benc
|
||||||
auto info_dict_v = tr_variant{};
|
auto info_dict_v = tr_variant{};
|
||||||
if (!tr_variantFromBuf(
|
if (!tr_variantFromBuf(&info_dict_v, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, m->metadata, nullptr, error))
|
||||||
&info_dict_v,
|
|
||||||
TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE,
|
|
||||||
{ std::data(m->metadata), std::size(m->metadata) },
|
|
||||||
nullptr,
|
|
||||||
error))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1174,12 +1174,10 @@ bool tr_variantFromFile(tr_variant* setme, tr_variant_parse_opts opts, std::stri
|
|||||||
// can't do inplace when this function is allocating & freeing the memory...
|
// can't do inplace when this function is allocating & freeing the memory...
|
||||||
TR_ASSERT((opts & TR_VARIANT_PARSE_INPLACE) == 0);
|
TR_ASSERT((opts & TR_VARIANT_PARSE_INPLACE) == 0);
|
||||||
|
|
||||||
auto buf = std::vector<char>{};
|
if (auto buf = std::vector<char>{}; tr_loadFile(filename, buf, error))
|
||||||
if (!tr_loadFile(filename, buf, error))
|
|
||||||
{
|
{
|
||||||
return false;
|
return tr_variantFromBuf(setme, opts, buf, nullptr, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const sv = std::string_view{ std::data(buf), std::size(buf) };
|
return false;
|
||||||
return tr_variantFromBuf(setme, opts, sv, nullptr, error);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,6 +130,22 @@ bool tr_variantFromBuf(
|
|||||||
char const** setme_end = nullptr,
|
char const** setme_end = nullptr,
|
||||||
tr_error** error = nullptr);
|
tr_error** error = nullptr);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool tr_variantFromBuf(
|
||||||
|
tr_variant* setme,
|
||||||
|
int variant_parse_opts,
|
||||||
|
T const& buf,
|
||||||
|
char const** setme_end = nullptr,
|
||||||
|
tr_error** error = nullptr)
|
||||||
|
{
|
||||||
|
return tr_variantFromBuf(
|
||||||
|
setme,
|
||||||
|
variant_parse_opts,
|
||||||
|
std::string_view{ std::data(buf), static_cast<size_t>(std::size(buf)) },
|
||||||
|
setme_end,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
constexpr bool tr_variantIsType(tr_variant const* b, int type)
|
constexpr bool tr_variantIsType(tr_variant const* b, int type)
|
||||||
{
|
{
|
||||||
return b != nullptr && b->type == type;
|
return b != nullptr && b->type == type;
|
||||||
|
|||||||
@@ -61,8 +61,7 @@ static void tr_watchdir_inotify_on_event(struct bufferevent* event, void* contex
|
|||||||
tr_watchdir_inotify const* const backend = BACKEND_UPCAST(tr_watchdir_get_backend(handle));
|
tr_watchdir_inotify const* const backend = BACKEND_UPCAST(tr_watchdir_get_backend(handle));
|
||||||
#endif
|
#endif
|
||||||
struct inotify_event ev;
|
struct inotify_event ev;
|
||||||
size_t name_size = NAME_MAX + 1;
|
auto name = std::string{};
|
||||||
auto* name = tr_new(char, name_size);
|
|
||||||
|
|
||||||
/* Read the size of the struct excluding name into buf. Guaranteed to have at
|
/* Read the size of the struct excluding name into buf. Guaranteed to have at
|
||||||
least sizeof(ev) available */
|
least sizeof(ev) available */
|
||||||
@@ -92,14 +91,9 @@ static void tr_watchdir_inotify_on_event(struct bufferevent* event, void* contex
|
|||||||
TR_ASSERT((ev.mask & INOTIFY_WATCH_MASK) != 0);
|
TR_ASSERT((ev.mask & INOTIFY_WATCH_MASK) != 0);
|
||||||
TR_ASSERT(ev.len > 0);
|
TR_ASSERT(ev.len > 0);
|
||||||
|
|
||||||
if (ev.len > name_size)
|
|
||||||
{
|
|
||||||
name_size = ev.len;
|
|
||||||
name = tr_renew(char, name, name_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Consume entire name into buffer */
|
/* Consume entire name into buffer */
|
||||||
nread = bufferevent_read(event, name, ev.len);
|
name.resize(ev.len);
|
||||||
|
nread = bufferevent_read(event, std::data(name), ev.len);
|
||||||
if (nread == static_cast<size_t>(-1))
|
if (nread == static_cast<size_t>(-1))
|
||||||
{
|
{
|
||||||
auto const error_code = errno;
|
auto const error_code = errno;
|
||||||
@@ -119,10 +113,8 @@ static void tr_watchdir_inotify_on_event(struct bufferevent* event, void* contex
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_watchdir_process(handle, name);
|
tr_watchdir_process(handle, name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_free(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tr_watchdir_inotify_free(tr_watchdir_backend* backend_base)
|
static void tr_watchdir_inotify_free(tr_watchdir_backend* backend_base)
|
||||||
|
|||||||
@@ -263,12 +263,10 @@ void RpcClient::networkRequestFinished(QNetworkReply* reply)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QByteArray const json_data = reply->readAll().trimmed();
|
auto const json_data = reply->readAll().trimmed();
|
||||||
auto const json_sv = std::string_view{ std::data(json_data), size_t(std::size(json_data)) };
|
auto const json = createVariant();
|
||||||
|
|
||||||
TrVariantPtr const json = createVariant();
|
|
||||||
RpcResponse result;
|
RpcResponse result;
|
||||||
if (tr_variantFromBuf(json.get(), TR_VARIANT_PARSE_JSON, json_sv))
|
if (tr_variantFromBuf(json.get(), TR_VARIANT_PARSE_JSON, json_data))
|
||||||
{
|
{
|
||||||
result = parseResponseData(*json);
|
result = parseResponseData(*json);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -545,17 +545,16 @@ TEST_F(VariantTest, variantFromBufFuzz)
|
|||||||
{
|
{
|
||||||
buf.resize(tr_rand_int(4096));
|
buf.resize(tr_rand_int(4096));
|
||||||
tr_rand_buffer(std::data(buf), std::size(buf));
|
tr_rand_buffer(std::data(buf), std::size(buf));
|
||||||
auto const sv = std::string_view{ std::data(buf), std::size(buf) };
|
|
||||||
// std::cerr << '[' << tr_base64_encode({ std::data(buf), std::size(buf) }) << ']' << std::endl;
|
// std::cerr << '[' << tr_base64_encode({ std::data(buf), std::size(buf) }) << ']' << std::endl;
|
||||||
|
|
||||||
if (auto top = tr_variant{};
|
if (auto top = tr_variant{};
|
||||||
tr_variantFromBuf(&top, TR_VARIANT_PARSE_JSON | TR_VARIANT_PARSE_INPLACE, sv, nullptr, nullptr))
|
tr_variantFromBuf(&top, TR_VARIANT_PARSE_JSON | TR_VARIANT_PARSE_INPLACE, buf, nullptr, nullptr))
|
||||||
{
|
{
|
||||||
tr_variantFree(&top);
|
tr_variantFree(&top);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto top = tr_variant{};
|
if (auto top = tr_variant{};
|
||||||
tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, sv, nullptr, nullptr))
|
tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, buf, nullptr, nullptr))
|
||||||
{
|
{
|
||||||
tr_variantFree(&top);
|
tr_variantFree(&top);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user