fix: sonarcloud warnings (#2350)

* fix: use-init-statement sonarcloud warning

* fix: use-init-statement sonarcloud warning

* fix: conversion-loses-precision sonarcloud warning

* fix: use std::string_view::npos sonarcoud warning

* fix: refactor code to not nest more than 3x sonarcloud warning

* fix: conversion-loses-precision sonarcloud warning

* fix: use init-statement sonarcloud warning

* fix: global variables should be const sonarcloud warning

* fix: conversion-loses-precision sonarcloud warning

* refactor: reduce complexity in doScrape()
This commit is contained in:
Charles Kerr 2021-12-26 18:32:36 -06:00 committed by GitHub
parent 6149870540
commit 0b095dc258
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 114 additions and 149 deletions

View File

@ -2026,7 +2026,7 @@ static void sessionLoadTorrents(void* vdata)
tr_ctorSetSave(data->ctor, false); /* since we already have them */
tr_sys_path_info info;
char const* dirname = tr_getTorrentDir(data->session);
char const* const dirname = tr_getTorrentDir(data->session);
tr_sys_dir_t odir = (tr_sys_path_get_info(dirname, 0, &info, nullptr) && info.type == TR_SYS_PATH_IS_DIRECTORY) ?
tr_sys_dir_open(dirname, nullptr) :
TR_BAD_SYS_DIR;
@ -2034,20 +2034,22 @@ static void sessionLoadTorrents(void* vdata)
auto torrents = std::list<tr_torrent*>{};
if (odir != TR_BAD_SYS_DIR)
{
char const* name = nullptr;
auto const dirname_sv = std::string_view{ dirname };
auto path = std::string{};
char const* name = nullptr;
while ((name = tr_sys_dir_read_name(odir, nullptr)) != nullptr)
{
if (tr_str_has_suffix(name, ".torrent"))
if (!tr_str_has_suffix(name, ".torrent"))
{
tr_buildBuf(path, dirname_sv, "/", name);
tr_ctorSetMetainfoFromFile(data->ctor, path.c_str(), nullptr);
continue;
}
if (tr_torrent* const tor = tr_torrentNew(data->ctor, nullptr); tor != nullptr)
{
torrents.push_back(tor);
}
tr_buildBuf(path, dirname_sv, "/", name);
tr_ctorSetMetainfoFromFile(data->ctor, path.c_str(), nullptr);
if (tr_torrent* const tor = tr_torrentNew(data->ctor, nullptr); tor != nullptr)
{
torrents.push_back(tor);
}
}

View File

@ -313,7 +313,7 @@ static bool appendSanitizedComponent(std::string& out, std::string_view in, bool
auto constexpr ensure_legal_char = [](auto ch)
{
auto constexpr Banned = std::string_view{ "<>:\"/\\|?*" };
auto const banned = Banned.find(ch) != Banned.npos || (unsigned char)ch < 0x20;
auto const banned = Banned.find(ch) != std::string_view::npos || (unsigned char)ch < 0x20;
return banned ? '_' : ch;
};
auto const old_out_len = std::size(out);
@ -350,7 +350,7 @@ std::string tr_torrent_metainfo::parsePath(std::string_view root, tr_variant* pa
}
buf = root;
for (int i = 0, n = tr_variantListSize(path); i < n; i++)
for (size_t i = 0, n = tr_variantListSize(path); i < n; ++i)
{
auto raw = std::string_view{};
if (!tr_variantGetStrView(tr_variantListChild(path, i), &raw))
@ -470,8 +470,7 @@ std::string_view tr_torrent_metainfo::parseAnnounce(tr_torrent_metainfo& setme,
// announce-list
// example: d['announce-list'] = [ [tracker1], [backup1], [backup2] ]
tr_variant* tiers = nullptr;
if (tr_variantDictFindList(meta, TR_KEY_announce_list, &tiers))
if (tr_variant* tiers = nullptr; tr_variantDictFindList(meta, TR_KEY_announce_list, &tiers))
{
for (size_t i = 0, n_tiers = tr_variantListSize(tiers); i < n_tiers; ++i)
{
@ -561,88 +560,59 @@ std::string_view tr_torrent_metainfo::parseImpl(tr_torrent_metainfo& setme, tr_v
}
// comment (optional)
setme.comment_.clear();
if (tr_variantDictFindStrView(meta, TR_KEY_comment_utf_8, &sv) || tr_variantDictFindStrView(meta, TR_KEY_comment, &sv))
{
setme.comment_ = tr_strvUtf8Clean(sv);
}
else
{
setme.comment_.clear();
}
// created by (optional)
setme.creator_.clear();
if (tr_variantDictFindStrView(meta, TR_KEY_created_by_utf_8, &sv) ||
tr_variantDictFindStrView(meta, TR_KEY_created_by, &sv))
{
setme.creator_ = tr_strvUtf8Clean(sv);
}
else
{
setme.creator_.clear();
}
// creation date (optional)
if (tr_variantDictFindInt(meta, TR_KEY_creation_date, &i))
{
setme.date_created_ = i;
}
else
{
setme.date_created_ = 0;
}
setme.date_created_ = tr_variantDictFindInt(meta, TR_KEY_creation_date, &i) ? i : 0;
// private (optional)
if (tr_variantDictFindInt(info_dict, TR_KEY_private, &i) || tr_variantDictFindInt(meta, TR_KEY_private, &i))
{
setme.is_private_ = i != 0;
}
else
{
setme.is_private_ = false;
}
setme.is_private_ = (tr_variantDictFindInt(info_dict, TR_KEY_private, &i) ||
tr_variantDictFindInt(meta, TR_KEY_private, &i)) &&
(i != 0);
// source (optional)
setme.source_.clear();
if (tr_variantDictFindStrView(info_dict, TR_KEY_source, &sv) || tr_variantDictFindStrView(meta, TR_KEY_source, &sv))
{
setme.source_ = tr_strvUtf8Clean(sv);
}
else
{
setme.source_.clear();
}
// piece length
auto piece_size = uint64_t{};
if (tr_variantDictFindInt(info_dict, TR_KEY_piece_length, &i) && (i > 0))
{
piece_size = i;
}
else
if (!tr_variantDictFindInt(info_dict, TR_KEY_piece_length, &i) && (i <= 0))
{
return "'info' dict 'piece length' is missing or has an invalid value";
}
auto const piece_size = i;
// pieces
if (tr_variantDictFindStrView(info_dict, TR_KEY_pieces, &sv) && (std::size(sv) % sizeof(tr_sha1_digest_t) == 0))
{
auto const n = std::size(sv) / sizeof(tr_sha1_digest_t);
setme.pieces_.resize(n);
std::copy_n(std::data(sv), std::size(sv), reinterpret_cast<char*>(std::data(setme.pieces_)));
}
else
if (!tr_variantDictFindStrView(info_dict, TR_KEY_pieces, &sv) || (std::size(sv) % sizeof(tr_sha1_digest_t) != 0))
{
return "'info' dict 'pieces' is missing or has an invalid value";
}
auto const n = std::size(sv) / sizeof(tr_sha1_digest_t);
setme.pieces_.resize(n);
std::copy_n(std::data(sv), std::size(sv), reinterpret_cast<char*>(std::data(setme.pieces_)));
// files
auto total_size = uint64_t{ 0 };
auto const errstr = parseFiles(setme, info_dict, &total_size);
if (!std::empty(errstr))
if (auto const errstr = parseFiles(setme, info_dict, &total_size); !std::empty(errstr))
{
return errstr;
}
if (std::empty(setme.files_) || total_size == 0)
if (std::empty(setme.files_))
{
return "no files found"sv;
}

View File

@ -773,7 +773,7 @@ tr_torrent* tr_torrentNew(tr_ctor const* ctor, tr_torrent** setme_duplicate_of)
auto* const session = tr_ctorGetSession(ctor);
TR_ASSERT(tr_isSession(session));
// is the metainfo valid
// is the metainfo valid?
auto top = tr_variant{};
if (!tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC, tr_ctorGetContents(ctor), nullptr, nullptr))
{
@ -786,9 +786,8 @@ tr_torrent* tr_torrentNew(tr_ctor const* ctor, tr_torrent** setme_duplicate_of)
return nullptr;
}
// is it a duplicate
auto* const duplicate_of = session->getTorrent(parsed->info.hash);
if (duplicate_of != nullptr)
// is it a duplicate?
if (auto* const duplicate_of = session->getTorrent(parsed->info.hash); duplicate_of != nullptr)
{
if (setme_duplicate_of != nullptr)
{

View File

@ -25,13 +25,12 @@ namespace
QString getNameFromMetainfo(QByteArray const& benc)
{
auto metainfo = tr_torrent_metainfo{};
if (metainfo.parseBenc({ benc.constData(), size_t(benc.size()) }))
if (!metainfo.parseBenc({ benc.constData(), size_t(benc.size()) }))
{
auto const& mname = metainfo.name();
return QString::fromUtf8(std::data(mname), std::size(mname));
return {};
}
return {};
return QString::fromStdString(metainfo.name());
}
} // namespace

View File

@ -185,7 +185,7 @@ void OptionsDialog::reload()
if (metainfo_)
{
size_t i = 0;
int i = 0;
auto const n_files = std::size(metainfo_->files());
priorities_.assign(n_files, TR_PRI_NORMAL);
wanted_.assign(n_files, true);
@ -198,7 +198,7 @@ void OptionsDialog::reload()
f.wanted = wanted_[i];
f.size = file.length();
f.have = 0;
f.filename = QString::fromUtf8(std::data(file.path()), std::size(file.path()));
f.filename = QString::fromStdString(file.path());
files_.push_back(f);
++i;

View File

@ -50,13 +50,16 @@ auto options = std::array<tr_option, 5>{
{ 0, nullptr, nullptr, nullptr, false, nullptr } }
};
auto filename_opt = std::string_view{};
auto magnet_opt = bool{ false };
auto scrape_opt = bool{ false };
auto show_version_opt = bool{ false };
auto unsorted_opt = bool{ false };
struct app_opts
{
std::string_view filename;
bool scrape = false;
bool show_magnet = false;
bool show_version = false;
bool unsorted = false;
};
int parseCommandLine(int argc, char const* const* argv)
int parseCommandLine(app_opts& opts, int argc, char const* const* argv)
{
int c;
char const* optarg;
@ -66,23 +69,23 @@ int parseCommandLine(int argc, char const* const* argv)
switch (c)
{
case 'm':
magnet_opt = true;
opts.show_magnet = true;
break;
case 's':
scrape_opt = true;
opts.scrape = true;
break;
case 'u':
unsorted_opt = true;
opts.unsorted = true;
break;
case 'V':
show_version_opt = true;
opts.show_version = true;
break;
case TR_OPT_UNK:
filename_opt = optarg;
opts.filename = optarg;
break;
default:
@ -107,7 +110,7 @@ auto toString(time_t timestamp)
return std::string{ std::data(buf) };
}
void showInfo(tr_torrent_metainfo const& metainfo)
void showInfo(app_opts const& opts, tr_torrent_metainfo const& metainfo)
{
auto buf = std::array<char, 128>{};
@ -159,8 +162,7 @@ void showInfo(tr_torrent_metainfo const& metainfo)
***
**/
auto const& webseeds = metainfo.webseeds();
if (!std::empty(webseeds))
if (auto const& webseeds = metainfo.webseeds(); !std::empty(webseeds))
{
printf("\nWEBSEEDS\n\n");
@ -186,7 +188,7 @@ void showInfo(tr_torrent_metainfo const& metainfo)
filenames.emplace_back(filename);
}
if (!unsorted_opt)
if (!opts.unsorted)
{
std::sort(std::begin(filenames), std::end(filenames));
}
@ -219,6 +221,9 @@ CURL* tr_curl_easy_init(struct evbuffer* writebuf)
void doScrape(tr_torrent_metainfo const& metainfo)
{
auto* const buf = evbuffer_new();
auto* const curl = tr_curl_easy_init(buf);
for (auto const& tracker : metainfo.announceList())
{
if (std::empty(tracker.scrape_str))
@ -239,80 +244,69 @@ void doScrape(tr_torrent_metainfo const& metainfo)
printf("%" TR_PRIsv " ... ", TR_PRIsv_ARG(url));
fflush(stdout);
auto* const buf = evbuffer_new();
auto* const curl = tr_curl_easy_init(buf);
// execute the http scrape
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_TIMEOUT, TimeoutSecs);
auto const res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
printf("error: %s\n", curl_easy_strerror(res));
continue;
}
else
// check the response code
long response;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
if (response != 200 /*HTTP OK*/)
{
long response;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
printf("error: unexpected response %ld \"%s\"\n", response, tr_webGetResponseStr(response));
continue;
}
if (response != 200)
// print it out
tr_variant top;
char const* begin = (char const*)evbuffer_pullup(buf, -1);
auto sv = std::string_view{ begin, evbuffer_get_length(buf) };
if (!tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, sv))
{
printf("error parsing scrape response\n");
continue;
}
bool matched = false;
tr_variant* files = nullptr;
if (tr_variantDictFindDict(&top, TR_KEY_files, &files))
{
size_t child_pos = 0;
tr_quark key;
tr_variant* val;
auto hashsv = std::string_view{ reinterpret_cast<char const*>(std::data(metainfo.infoHash())),
std::size(metainfo.infoHash()) };
while (tr_variantDictChild(files, child_pos++, &key, &val))
{
printf("error: unexpected response %ld \"%s\"\n", response, tr_webGetResponseStr(response));
}
else /* HTTP OK */
{
tr_variant top;
tr_variant* files;
bool matched = false;
char const* begin = (char const*)evbuffer_pullup(buf, -1);
auto sv = std::string_view{ begin, evbuffer_get_length(buf) };
if (tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, sv))
if (hashsv == tr_quark_get_string_view(key))
{
if (tr_variantDictFindDict(&top, TR_KEY_files, &files))
{
size_t child_pos = 0;
tr_quark key;
tr_variant* val;
auto hashsv = std::string_view{ reinterpret_cast<char const*>(std::data(metainfo.infoHash())),
std::size(metainfo.infoHash()) };
while (tr_variantDictChild(files, child_pos, &key, &val))
{
if (hashsv == tr_quark_get_string_view(key))
{
int64_t seeders;
if (!tr_variantDictFindInt(val, TR_KEY_complete, &seeders))
{
seeders = -1;
}
int64_t leechers;
if (!tr_variantDictFindInt(val, TR_KEY_incomplete, &leechers))
{
leechers = -1;
}
printf("%d seeders, %d leechers\n", (int)seeders, (int)leechers);
matched = true;
}
++child_pos;
}
}
tr_variantFree(&top);
}
if (!matched)
{
printf("no match\n");
auto i = int64_t{};
auto const seeders = tr_variantDictFindInt(val, TR_KEY_complete, &i) ? int(i) : -1;
auto const leechers = tr_variantDictFindInt(val, TR_KEY_incomplete, &i) ? int(i) : -1;
printf("%d seeders, %d leechers\n", (int)seeders, (int)leechers);
matched = true;
}
}
}
curl_easy_cleanup(curl);
evbuffer_free(buf);
tr_variantFree(&top);
if (!matched)
{
printf("no match\n");
}
}
curl_easy_cleanup(curl);
evbuffer_free(buf);
}
} // namespace
@ -324,19 +318,20 @@ int tr_main(int argc, char* argv[])
tr_formatter_size_init(DISK_K, DISK_K_STR, DISK_M_STR, DISK_G_STR, DISK_T_STR);
tr_formatter_speed_init(SPEED_K, SPEED_K_STR, SPEED_M_STR, SPEED_G_STR, SPEED_T_STR);
if (parseCommandLine(argc, (char const* const*)argv) != 0)
auto opts = app_opts{};
if (parseCommandLine(opts, argc, (char const* const*)argv) != 0)
{
return EXIT_FAILURE;
}
if (show_version_opt)
if (opts.show_version)
{
fprintf(stderr, "%s %s\n", MyName, LONG_VERSION_STRING);
return EXIT_SUCCESS;
}
/* make sure the user specified a filename */
if (std::empty(filename_opt))
if (std::empty(opts.filename))
{
fprintf(stderr, "ERROR: No .torrent file specified.\n");
tr_getopt_usage(MyName, Usage, std::data(options));
@ -347,13 +342,13 @@ int tr_main(int argc, char* argv[])
/* try to parse the .torrent file */
auto metainfo = tr_torrent_metainfo{};
tr_error* error = nullptr;
auto const parsed = metainfo.parseTorrentFile(filename_opt, nullptr, &error);
auto const parsed = metainfo.parseTorrentFile(opts.filename, nullptr, &error);
if (error != nullptr)
{
fprintf(
stderr,
"Error parsing .torrent file \"%" TR_PRIsv "\": %s (%d)\n",
TR_PRIsv_ARG(filename_opt),
TR_PRIsv_ARG(opts.filename),
error->message,
error->code);
tr_error_clear(&error);
@ -363,24 +358,24 @@ int tr_main(int argc, char* argv[])
return EXIT_FAILURE;
}
if (magnet_opt)
if (opts.show_magnet)
{
printf("%s", metainfo.magnet().c_str());
}
else
{
printf("Name: %s\n", metainfo.name().c_str());
printf("File: %" TR_PRIsv "\n", TR_PRIsv_ARG(filename_opt));
printf("File: %" TR_PRIsv "\n", TR_PRIsv_ARG(opts.filename));
printf("\n");
fflush(stdout);
if (scrape_opt)
if (opts.scrape)
{
doScrape(metainfo);
}
else
{
showInfo(metainfo);
showInfo(opts, metainfo);
}
}