1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-06 11:38:21 +00:00

fix: sonarcloud getopt warnings (#1871)

* fix: sonarcloud out-of-bound memory access warning

* fix: sonarcloud out-of-bound memory access warning

* fix: sonarcloud 64-to-32 narrowing warning
This commit is contained in:
Charles Kerr 2021-10-01 12:47:23 -05:00 committed by GitHub
parent c87d22d53f
commit b546fd423f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -11,6 +11,7 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> /* exit() */ #include <cstdlib> /* exit() */
#include <cstring> #include <cstring>
#include <string_view>
#include "transmission.h" #include "transmission.h"
#include "tr-getopt.h" #include "tr-getopt.h"
@ -39,36 +40,27 @@ static char const* getArgName(tr_option const* opt)
return arg; return arg;
} }
static int get_next_line_len(char const* description, int maxlen) static size_t get_next_line_len(std::string_view description, size_t maxlen)
{ {
int end; auto len = std::size(description);
int len = strlen(description); if (len > maxlen)
if (len < maxlen)
{ {
description.remove_suffix(len - maxlen);
auto const pos = description.rfind(' ');
len = pos != std::string_view::npos ? pos : maxlen;
}
return len; return len;
} }
end = maxlen < len ? maxlen : len;
while (end > 0 && !isspace(description[end]))
{
--end;
}
return end != 0 ? end : len;
}
static void getopts_usage_line(tr_option const* opt, int longWidth, int shortWidth, int argWidth) static void getopts_usage_line(tr_option const* opt, int longWidth, int shortWidth, int argWidth)
{ {
int len;
char const* longName = opt->longName != nullptr ? opt->longName : ""; char const* longName = opt->longName != nullptr ? opt->longName : "";
char const* shortName = opt->shortName != nullptr ? opt->shortName : ""; char const* shortName = opt->shortName != nullptr ? opt->shortName : "";
char const* arg = getArgName(opt); char const* arg = getArgName(opt);
int const d_indent = shortWidth + longWidth + argWidth + 7; int const d_indent = shortWidth + longWidth + argWidth + 7;
int const d_width = 80 - d_indent; int const d_width = 80 - d_indent;
char const* d = opt->description; auto d = std::string_view{ opt->description };
printf( printf(
" %s%-*s %s%-*s %-*s ", " %s%-*s %s%-*s %-*s ",
@ -77,68 +69,63 @@ static void getopts_usage_line(tr_option const* opt, int longWidth, int shortWid
tr_str_is_empty(longName) ? " " : "--", tr_str_is_empty(longName) ? " " : "--",
TR_ARG_TUPLE(longWidth, longName), TR_ARG_TUPLE(longWidth, longName),
TR_ARG_TUPLE(argWidth, arg)); TR_ARG_TUPLE(argWidth, arg));
len = get_next_line_len(d, d_width);
printf("%*.*s\n", TR_ARG_TUPLE(len, len, d));
d += len; auto const strip_leading_whitespace = [](std::string_view text)
while (isspace(*d))
{ {
++d; auto pos = text.find_first_not_of(' ');
if (pos != std::string_view::npos)
{
text.remove_prefix(pos);
} }
return text;
};
int len = get_next_line_len(d, d_width);
printf("%*.*s\n", TR_ARG_TUPLE(len, len, std::data(d)));
d.remove_prefix(len);
d = strip_leading_whitespace(d);
while ((len = get_next_line_len(d, d_width)) != 0) while ((len = get_next_line_len(d, d_width)) != 0)
{ {
printf("%*.*s%*.*s\n", TR_ARG_TUPLE(d_indent, d_indent, ""), TR_ARG_TUPLE(len, len, d)); printf("%*.*s%*.*s\n", TR_ARG_TUPLE(d_indent, d_indent, ""), TR_ARG_TUPLE(len, len, std::data(d)));
d += len; d.remove_prefix(len);
d = strip_leading_whitespace(d);
while (isspace(*d))
{
++d;
}
} }
} }
static void maxWidth(struct tr_option const* o, int* longWidth, int* shortWidth, int* argWidth) static void maxWidth(struct tr_option const* o, size_t& longWidth, size_t& shortWidth, size_t& argWidth)
{ {
// FIXME: in this function sign bits from int* are lost, then 64-bit result is truncated to 32-bit int
// Convert arguments to size_t*
char const* arg; char const* arg;
if (o->longName != nullptr) if (o->longName != nullptr)
{ {
*longWidth = std::max((size_t)*longWidth, strlen(o->longName)); longWidth = std::max(longWidth, strlen(o->longName));
} }
if (o->shortName != nullptr) if (o->shortName != nullptr)
{ {
*shortWidth = std::max((size_t)*shortWidth, strlen(o->shortName)); shortWidth = std::max(shortWidth, strlen(o->shortName));
} }
if ((arg = getArgName(o)) != nullptr) if ((arg = getArgName(o)) != nullptr)
{ {
*argWidth = std::max((size_t)*argWidth, strlen(arg)); argWidth = std::max(argWidth, strlen(arg));
} }
} }
void tr_getopt_usage(char const* progName, char const* description, struct tr_option const opts[]) void tr_getopt_usage(char const* progName, char const* description, struct tr_option const opts[])
{ {
int longWidth = 0; auto longWidth = size_t{ 0 };
int shortWidth = 0; auto shortWidth = size_t{ 0 };
int argWidth = 0; auto argWidth = size_t{ 0 };
struct tr_option help;
for (tr_option const* o = opts; o->val != 0; ++o) for (tr_option const* o = opts; o->val != 0; ++o)
{ {
maxWidth(o, &longWidth, &shortWidth, &argWidth); maxWidth(o, longWidth, shortWidth, argWidth);
} }
help.val = -1; auto const help = tr_option{ -1, "help", "Display this help page and exit", "h", false, nullptr };
help.longName = "help"; maxWidth(&help, longWidth, shortWidth, argWidth);
help.description = "Display this help page and exit";
help.shortName = "h";
help.has_arg = false;
maxWidth(&help, &longWidth, &shortWidth, &argWidth);
if (description == nullptr) if (description == nullptr)
{ {