1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-06 03:28:33 +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 <cstdlib> /* exit() */
#include <cstring>
#include <string_view>
#include "transmission.h"
#include "tr-getopt.h"
@ -39,36 +40,27 @@ static char const* getArgName(tr_option const* opt)
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;
int len = strlen(description);
if (len < maxlen)
auto len = std::size(description);
if (len > maxlen)
{
description.remove_suffix(len - maxlen);
auto const pos = description.rfind(' ');
len = pos != std::string_view::npos ? pos : maxlen;
}
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)
{
int len;
char const* longName = opt->longName != nullptr ? opt->longName : "";
char const* shortName = opt->shortName != nullptr ? opt->shortName : "";
char const* arg = getArgName(opt);
int const d_indent = shortWidth + longWidth + argWidth + 7;
int const d_width = 80 - d_indent;
char const* d = opt->description;
auto d = std::string_view{ opt->description };
printf(
" %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_ARG_TUPLE(longWidth, longName),
TR_ARG_TUPLE(argWidth, arg));
len = get_next_line_len(d, d_width);
printf("%*.*s\n", TR_ARG_TUPLE(len, len, d));
d += len;
while (isspace(*d))
auto const strip_leading_whitespace = [](std::string_view text)
{
++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)
{
printf("%*.*s%*.*s\n", TR_ARG_TUPLE(d_indent, d_indent, ""), TR_ARG_TUPLE(len, len, d));
d += len;
while (isspace(*d))
{
++d;
}
printf("%*.*s%*.*s\n", TR_ARG_TUPLE(d_indent, d_indent, ""), TR_ARG_TUPLE(len, len, std::data(d)));
d.remove_prefix(len);
d = strip_leading_whitespace(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;
if (o->longName != nullptr)
{
*longWidth = std::max((size_t)*longWidth, strlen(o->longName));
longWidth = std::max(longWidth, strlen(o->longName));
}
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)
{
*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[])
{
int longWidth = 0;
int shortWidth = 0;
int argWidth = 0;
struct tr_option help;
auto longWidth = size_t{ 0 };
auto shortWidth = size_t{ 0 };
auto argWidth = size_t{ 0 };
for (tr_option const* o = opts; o->val != 0; ++o)
{
maxWidth(o, &longWidth, &shortWidth, &argWidth);
maxWidth(o, longWidth, shortWidth, argWidth);
}
help.val = -1;
help.longName = "help";
help.description = "Display this help page and exit";
help.shortName = "h";
help.has_arg = false;
maxWidth(&help, &longWidth, &shortWidth, &argWidth);
auto const help = tr_option{ -1, "help", "Display this help page and exit", "h", false, nullptr };
maxWidth(&help, longWidth, shortWidth, argWidth);
if (description == nullptr)
{