Replace the use of strtoul and strtol with parse_uint
Replace the use of strtoul and strtol with parse_uint to fix the handling of negative integer.
This commit is contained in:
parent
092014d5af
commit
a4d12f2a71
|
@ -235,6 +235,8 @@ if(ENABLE_HPACK_TOOLS)
|
||||||
set(deflatehd_SOURCES
|
set(deflatehd_SOURCES
|
||||||
deflatehd.cc
|
deflatehd.cc
|
||||||
comp_helper.c
|
comp_helper.c
|
||||||
|
util.cc
|
||||||
|
timegm.c
|
||||||
)
|
)
|
||||||
add_executable(inflatehd ${inflatehd_SOURCES})
|
add_executable(inflatehd ${inflatehd_SOURCES})
|
||||||
add_executable(deflatehd ${deflatehd_SOURCES})
|
add_executable(deflatehd ${deflatehd_SOURCES})
|
||||||
|
|
|
@ -246,7 +246,10 @@ if ENABLE_HPACK_TOOLS
|
||||||
|
|
||||||
bin_PROGRAMS += inflatehd deflatehd
|
bin_PROGRAMS += inflatehd deflatehd
|
||||||
|
|
||||||
HPACK_TOOLS_COMMON_SRCS = comp_helper.c comp_helper.h
|
HPACK_TOOLS_COMMON_SRCS = \
|
||||||
|
comp_helper.c comp_helper.h \
|
||||||
|
util.cc util.h \
|
||||||
|
timegm.c timegm.h
|
||||||
|
|
||||||
inflatehd_SOURCES = inflatehd.cc $(HPACK_TOOLS_COMMON_SRCS)
|
inflatehd_SOURCES = inflatehd.cc $(HPACK_TOOLS_COMMON_SRCS)
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
#include "comp_helper.h"
|
#include "comp_helper.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
|
|
||||||
|
@ -381,8 +382,6 @@ constexpr static struct option long_options[] = {
|
||||||
{nullptr, 0, nullptr, 0}};
|
{nullptr, 0, nullptr, 0}};
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
char *end;
|
|
||||||
|
|
||||||
config.table_size = 4_k;
|
config.table_size = 4_k;
|
||||||
config.deflate_table_size = 4_k;
|
config.deflate_table_size = 4_k;
|
||||||
config.http1text = 0;
|
config.http1text = 0;
|
||||||
|
@ -401,24 +400,26 @@ int main(int argc, char **argv) {
|
||||||
// --http1text
|
// --http1text
|
||||||
config.http1text = 1;
|
config.http1text = 1;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's': {
|
||||||
// --table-size
|
// --table-size
|
||||||
errno = 0;
|
auto n = util::parse_uint(optarg);
|
||||||
config.table_size = strtoul(optarg, &end, 10);
|
if (n == -1) {
|
||||||
if (errno == ERANGE || *end != '\0') {
|
|
||||||
fprintf(stderr, "-s: Bad option value\n");
|
fprintf(stderr, "-s: Bad option value\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
config.table_size = n;
|
||||||
break;
|
break;
|
||||||
case 'S':
|
}
|
||||||
|
case 'S': {
|
||||||
// --deflate-table-size
|
// --deflate-table-size
|
||||||
errno = 0;
|
auto n = util::parse_uint(optarg);
|
||||||
config.deflate_table_size = strtoul(optarg, &end, 10);
|
if (n == -1) {
|
||||||
if (errno == ERANGE || *end != '\0') {
|
|
||||||
fprintf(stderr, "-S: Bad option value\n");
|
fprintf(stderr, "-S: Bad option value\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
config.deflate_table_size = n;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'd':
|
case 'd':
|
||||||
// --dump-header-table
|
// --dump-header-table
|
||||||
config.dump_header_table = 1;
|
config.dump_header_table = 1;
|
||||||
|
|
|
@ -2370,44 +2370,65 @@ int main(int argc, char **argv) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'n':
|
case 'n': {
|
||||||
config.nreqs = strtoul(optarg, nullptr, 10);
|
auto n = util::parse_uint(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "-n: bad option value: " << optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.nreqs = n;
|
||||||
nreqs_set_manually = true;
|
nreqs_set_manually = true;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
}
|
||||||
config.nclients = strtoul(optarg, nullptr, 10);
|
case 'c': {
|
||||||
|
auto n = util::parse_uint(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "-c: bad option value: " << optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.nclients = n;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'd':
|
case 'd':
|
||||||
datafile = optarg;
|
datafile = optarg;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't': {
|
||||||
#ifdef NOTHREADS
|
#ifdef NOTHREADS
|
||||||
std::cerr << "-t: WARNING: Threading disabled at build time, "
|
std::cerr << "-t: WARNING: Threading disabled at build time, "
|
||||||
<< "no threads created." << std::endl;
|
<< "no threads created." << std::endl;
|
||||||
#else
|
#else
|
||||||
config.nthreads = strtoul(optarg, nullptr, 10);
|
auto n = util::parse_uint(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "-t: bad option value: " << optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.nthreads = n;
|
||||||
#endif // NOTHREADS
|
#endif // NOTHREADS
|
||||||
break;
|
break;
|
||||||
case 'm':
|
}
|
||||||
config.max_concurrent_streams = strtoul(optarg, nullptr, 10);
|
case 'm': {
|
||||||
|
auto n = util::parse_uint(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "-m: bad option value: " << optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.max_concurrent_streams = n;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'w':
|
case 'w':
|
||||||
case 'W': {
|
case 'W': {
|
||||||
errno = 0;
|
auto n = util::parse_uint(optarg);
|
||||||
char *endptr = nullptr;
|
if (n == -1 || n > 30) {
|
||||||
auto n = strtoul(optarg, &endptr, 10);
|
|
||||||
if (errno == 0 && *endptr == '\0' && n < 31) {
|
|
||||||
if (c == 'w') {
|
|
||||||
config.window_bits = n;
|
|
||||||
} else {
|
|
||||||
config.connection_window_bits = n;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
std::cerr << "-" << static_cast<char>(c)
|
std::cerr << "-" << static_cast<char>(c)
|
||||||
<< ": specify the integer in the range [0, 30], inclusive"
|
<< ": specify the integer in the range [0, 30], inclusive"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
if (c == 'w') {
|
||||||
|
config.window_bits = n;
|
||||||
|
} else {
|
||||||
|
config.connection_window_bits = n;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'f': {
|
case 'f': {
|
||||||
|
@ -2470,14 +2491,20 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'r':
|
case 'r': {
|
||||||
config.rate = strtoul(optarg, nullptr, 10);
|
auto n = util::parse_uint(optarg);
|
||||||
if (config.rate == 0) {
|
if (n == -1) {
|
||||||
|
std::cerr << "-r: bad option value: " << optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (n == 0) {
|
||||||
std::cerr << "-r: the rate at which connections are made "
|
std::cerr << "-r: the rate at which connections are made "
|
||||||
<< "must be positive." << std::endl;
|
<< "must be positive." << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
config.rate = n;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'T':
|
case 'T':
|
||||||
config.conn_active_timeout = util::parse_duration_with_unit(optarg);
|
config.conn_active_timeout = util::parse_duration_with_unit(optarg);
|
||||||
if (!std::isfinite(config.conn_active_timeout)) {
|
if (!std::isfinite(config.conn_active_timeout)) {
|
||||||
|
|
|
@ -2832,33 +2832,43 @@ int main(int argc, char **argv) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'M':
|
case 'M': {
|
||||||
// peer-max-concurrent-streams option
|
// peer-max-concurrent-streams option
|
||||||
config.peer_max_concurrent_streams = strtoul(optarg, nullptr, 10);
|
auto n = util::parse_uint(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "-M: Bad option value: " << optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.peer_max_concurrent_streams = n;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'O':
|
case 'O':
|
||||||
config.remote_name = true;
|
config.remote_name = true;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
print_help(std::cout);
|
print_help(std::cout);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
case 'b':
|
case 'b': {
|
||||||
config.padding = strtol(optarg, nullptr, 10);
|
auto n = util::parse_uint(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "-b: Bad option value: " << optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.padding = n;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'n':
|
case 'n':
|
||||||
config.null_out = true;
|
config.null_out = true;
|
||||||
break;
|
break;
|
||||||
case 'p': {
|
case 'p': {
|
||||||
errno = 0;
|
auto n = util::parse_uint(optarg);
|
||||||
auto n = strtoul(optarg, nullptr, 10);
|
if (n == -1 || NGHTTP2_MIN_WEIGHT > n || n > NGHTTP2_MAX_WEIGHT) {
|
||||||
if (errno == 0 && NGHTTP2_MIN_WEIGHT <= n && n <= NGHTTP2_MAX_WEIGHT) {
|
|
||||||
config.weight.push_back(n);
|
|
||||||
} else {
|
|
||||||
std::cerr << "-p: specify the integer in the range ["
|
std::cerr << "-p: specify the integer in the range ["
|
||||||
<< NGHTTP2_MIN_WEIGHT << ", " << NGHTTP2_MAX_WEIGHT
|
<< NGHTTP2_MIN_WEIGHT << ", " << NGHTTP2_MAX_WEIGHT
|
||||||
<< "], inclusive" << std::endl;
|
<< "], inclusive" << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
config.weight.push_back(n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'r':
|
case 'r':
|
||||||
|
@ -2884,21 +2894,18 @@ int main(int argc, char **argv) {
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
case 'W': {
|
case 'W': {
|
||||||
errno = 0;
|
auto n = util::parse_uint(optarg);
|
||||||
char *endptr = nullptr;
|
if (n == -1 || n > 30) {
|
||||||
unsigned long int n = strtoul(optarg, &endptr, 10);
|
|
||||||
if (errno == 0 && *endptr == '\0' && n < 31) {
|
|
||||||
if (c == 'w') {
|
|
||||||
config.window_bits = n;
|
|
||||||
} else {
|
|
||||||
config.connection_window_bits = n;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
std::cerr << "-" << static_cast<char>(c)
|
std::cerr << "-" << static_cast<char>(c)
|
||||||
<< ": specify the integer in the range [0, 30], inclusive"
|
<< ": specify the integer in the range [0, 30], inclusive"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
if (c == 'w') {
|
||||||
|
config.window_bits = n;
|
||||||
|
} else {
|
||||||
|
config.connection_window_bits = n;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'H': {
|
case 'H': {
|
||||||
|
@ -2939,9 +2946,15 @@ int main(int argc, char **argv) {
|
||||||
case 'd':
|
case 'd':
|
||||||
config.datafile = optarg;
|
config.datafile = optarg;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm': {
|
||||||
config.multiply = strtoul(optarg, nullptr, 10);
|
auto n = util::parse_uint(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "-m: Bad option value: " << optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.multiply = n;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'c': {
|
case 'c': {
|
||||||
auto n = util::parse_uint_with_unit(optarg);
|
auto n = util::parse_uint_with_unit(optarg);
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
|
@ -3025,10 +3038,17 @@ int main(int argc, char **argv) {
|
||||||
// no-push option
|
// no-push option
|
||||||
config.no_push = true;
|
config.no_push = true;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12: {
|
||||||
// max-concurrent-streams option
|
// max-concurrent-streams option
|
||||||
config.max_concurrent_streams = strtoul(optarg, nullptr, 10);
|
auto n = util::parse_uint(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "--max-concurrent-streams: Bad option value: " << optarg
|
||||||
|
<< std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.max_concurrent_streams = n;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 13:
|
case 13:
|
||||||
// expect-continue option
|
// expect-continue option
|
||||||
config.expect_continue = true;
|
config.expect_continue = true;
|
||||||
|
|
|
@ -250,9 +250,15 @@ int main(int argc, char **argv) {
|
||||||
case 'V':
|
case 'V':
|
||||||
config.verify_client = true;
|
config.verify_client = true;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b': {
|
||||||
config.padding = strtol(optarg, nullptr, 10);
|
auto n = util::parse_uint(optarg);
|
||||||
|
if (n == -1) {
|
||||||
|
std::cerr << "-b: Bad option value: " << optarg << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.padding = n;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'd':
|
case 'd':
|
||||||
config.htdocs = optarg;
|
config.htdocs = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -274,13 +280,12 @@ int main(int argc, char **argv) {
|
||||||
std::cerr << "-n: WARNING: Threading disabled at build time, "
|
std::cerr << "-n: WARNING: Threading disabled at build time, "
|
||||||
<< "no threads created." << std::endl;
|
<< "no threads created." << std::endl;
|
||||||
#else
|
#else
|
||||||
char *end;
|
auto n = util::parse_uint(optarg);
|
||||||
errno = 0;
|
if (n == -1) {
|
||||||
config.num_worker = strtoul(optarg, &end, 10);
|
|
||||||
if (errno == ERANGE || *end != '\0' || config.num_worker == 0) {
|
|
||||||
std::cerr << "-n: Bad option value: " << optarg << std::endl;
|
std::cerr << "-n: Bad option value: " << optarg << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
config.num_worker = n;
|
||||||
#endif // NOTHREADS
|
#endif // NOTHREADS
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -311,10 +316,8 @@ int main(int argc, char **argv) {
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
case 'W': {
|
case 'W': {
|
||||||
char *endptr;
|
auto n = util::parse_uint(optarg);
|
||||||
errno = 0;
|
if (n == -1 || n > 30) {
|
||||||
auto n = strtoul(optarg, &endptr, 10);
|
|
||||||
if (errno != 0 || *endptr != '\0' || n >= 31) {
|
|
||||||
std::cerr << "-" << static_cast<char>(c)
|
std::cerr << "-" << static_cast<char>(c)
|
||||||
<< ": specify the integer in the range [0, 30], inclusive"
|
<< ": specify the integer in the range [0, 30], inclusive"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
@ -432,7 +435,15 @@ int main(int argc, char **argv) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.port = strtol(argv[optind++], nullptr, 10);
|
{
|
||||||
|
auto portStr = argv[optind++];
|
||||||
|
auto n = util::parse_uint(portStr);
|
||||||
|
if (n == -1 || n > std::numeric_limits<uint16_t>::max()) {
|
||||||
|
std::cerr << "<PORT>: Bad value: " << portStr << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
config.port = n;
|
||||||
|
}
|
||||||
|
|
||||||
if (!config.no_tls) {
|
if (!config.no_tls) {
|
||||||
config.private_key_file = argv[optind++];
|
config.private_key_file = argv[optind++];
|
||||||
|
|
|
@ -423,26 +423,6 @@ int parse_uint_with_unit(T *dest, const StringRef &opt,
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Parses |optarg| as signed integer. This requires |optarg| to be
|
|
||||||
// NULL-terminated string.
|
|
||||||
template <typename T>
|
|
||||||
int parse_int(T *dest, const StringRef &opt, const char *optarg) {
|
|
||||||
char *end = nullptr;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
auto val = strtol(optarg, &end, 10);
|
|
||||||
|
|
||||||
if (!optarg[0] || errno != 0 || *end) {
|
|
||||||
LOG(ERROR) << opt << ": bad value. Specify an integer.";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*dest = val;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int parse_altsvc(AltSvc &altsvc, const StringRef &opt,
|
int parse_altsvc(AltSvc &altsvc, const StringRef &opt,
|
||||||
const StringRef &optarg) {
|
const StringRef &optarg) {
|
||||||
|
|
Loading…
Reference in New Issue