diff --git a/libtransmission/peer-msgs.cc b/libtransmission/peer-msgs.cc index 4e67f9f3a..7350afa03 100644 --- a/libtransmission/peer-msgs.cc +++ b/libtransmission/peer-msgs.cc @@ -1346,14 +1346,15 @@ static void parseUtMetadata(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuf int64_t msg_type = -1; int64_t piece = -1; int64_t total_size = 0; - auto* const tmp = tr_new(char, msglen); - tr_peerIoReadBytes(msgs->io, inbuf, tmp, msglen); - char const* const msg_end = (char const*)tmp + msglen; + auto tmp = std::vector{}; + 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{}; 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_piece, &piece); @@ -1408,8 +1409,6 @@ static void parseUtMetadata(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuf tr_variantFree(&v); } } - - tr_free(tmp); } 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; } - auto* tmp = tr_new(char, msglen); - tr_peerIoReadBytes(msgs->io, inbuf, tmp, msglen); + auto tmp = std::vector{}; + 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; auto added_len = size_t{}; @@ -1459,8 +1459,6 @@ static void parseUtPex(tr_peerMsgsImpl* msgs, uint32_t msglen, struct evbuffer* tr_variantFree(&val); } - - tr_free(tmp); } static void sendPex(tr_peerMsgsImpl* msgs); diff --git a/libtransmission/resume.cc b/libtransmission/resume.cc index c4e531e69..3278197cd 100644 --- a/libtransmission/resume.cc +++ b/libtransmission/resume.cc @@ -669,12 +669,7 @@ static auto loadFromFile(tr_torrent* tor, tr_resume::fields_t fieldsToLoad, bool tr_error* error = nullptr; auto top = tr_variant{}; if (!tr_loadFile(filename, buf, &error) || - !tr_variantFromBuf( - &top, - TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, - { std::data(buf), std::size(buf) }, - nullptr, - &error)) + !tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, buf, nullptr, &error)) { tr_logAddDebugTor(tor, fmt::format("Couldn't read '{}': {}", filename, error->message)); tr_error_clear(&error); diff --git a/libtransmission/torrent-magnet.cc b/libtransmission/torrent-magnet.cc index 90fbda18b..1d0322fc6 100644 --- a/libtransmission/torrent-magnet.cc +++ b/libtransmission/torrent-magnet.cc @@ -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 auto info_dict_v = tr_variant{}; - if (!tr_variantFromBuf( - &info_dict_v, - TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, - { std::data(m->metadata), std::size(m->metadata) }, - nullptr, - error)) + if (!tr_variantFromBuf(&info_dict_v, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, m->metadata, nullptr, error)) { return false; } diff --git a/libtransmission/variant.cc b/libtransmission/variant.cc index b37450aa7..6941bf836 100644 --- a/libtransmission/variant.cc +++ b/libtransmission/variant.cc @@ -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... TR_ASSERT((opts & TR_VARIANT_PARSE_INPLACE) == 0); - auto buf = std::vector{}; - if (!tr_loadFile(filename, buf, error)) + if (auto buf = std::vector{}; 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 tr_variantFromBuf(setme, opts, sv, nullptr, error); + return false; } diff --git a/libtransmission/variant.h b/libtransmission/variant.h index 46d427c70..c76d4f068 100644 --- a/libtransmission/variant.h +++ b/libtransmission/variant.h @@ -130,6 +130,22 @@ bool tr_variantFromBuf( char const** setme_end = nullptr, tr_error** error = nullptr); +template +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(std::size(buf)) }, + setme_end, + error); +} + constexpr bool tr_variantIsType(tr_variant const* b, int type) { return b != nullptr && b->type == type; diff --git a/libtransmission/watchdir-inotify.cc b/libtransmission/watchdir-inotify.cc index 30e29a3cd..2070bb519 100644 --- a/libtransmission/watchdir-inotify.cc +++ b/libtransmission/watchdir-inotify.cc @@ -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)); #endif struct inotify_event ev; - size_t name_size = NAME_MAX + 1; - auto* name = tr_new(char, name_size); + auto name = std::string{}; /* Read the size of the struct excluding name into buf. Guaranteed to have at 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.len > 0); - if (ev.len > name_size) - { - name_size = ev.len; - name = tr_renew(char, name, name_size); - } - /* 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(-1)) { auto const error_code = errno; @@ -119,10 +113,8 @@ static void tr_watchdir_inotify_on_event(struct bufferevent* event, void* contex 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) diff --git a/qt/RpcClient.cc b/qt/RpcClient.cc index a22c1a4c0..1b5ca27db 100644 --- a/qt/RpcClient.cc +++ b/qt/RpcClient.cc @@ -263,12 +263,10 @@ void RpcClient::networkRequestFinished(QNetworkReply* reply) } else { - QByteArray const json_data = reply->readAll().trimmed(); - auto const json_sv = std::string_view{ std::data(json_data), size_t(std::size(json_data)) }; - - TrVariantPtr const json = createVariant(); + auto const json_data = reply->readAll().trimmed(); + auto const json = createVariant(); 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); } diff --git a/tests/libtransmission/variant-test.cc b/tests/libtransmission/variant-test.cc index 32b959827..09c237cf2 100644 --- a/tests/libtransmission/variant-test.cc +++ b/tests/libtransmission/variant-test.cc @@ -545,17 +545,16 @@ TEST_F(VariantTest, variantFromBufFuzz) { buf.resize(tr_rand_int(4096)); 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; 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); } 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); }