Restrict parse value to strtoll with restrictions on input.

This commit is contained in:
rakshasa
2026-09-30 12:01:13 +02:00
committed by Jari Sundell
parent 44d51171e1
commit c5d54fbb97
16 changed files with 440 additions and 60 deletions
+4
View File
@@ -1,5 +1,6 @@
#include "config.h"
#include <limits>
#include <memory>
#include <torrent/download/resource_manager.h>
@@ -232,6 +233,9 @@ apply_cg_max_set(const torrent::Object::list_type& args, bool is_up) {
int64_t second_arg = 0;
rpc::parse_whole_value(args.back().as_string().c_str(), &second_arg);
if (second_arg < -1 || second_arg > std::numeric_limits<uint32_t>::max())
throw torrent::input_error("Max unchoked must be between -1 and 4294967295.");
if (is_up)
cg_get_group(args.front())->up_queue()->set_max_unchoked(second_arg);
else
+13
View File
@@ -1,12 +1,25 @@
#ifndef RTORRENT_UTILS_COMMAND_HELPERS_H
#define RTORRENT_UTILS_COMMAND_HELPERS_H
#include <cstdint>
#include <limits>
#include <string>
#include <torrent/exceptions.h>
#include "rpc/command.h"
#include "rpc/parse_commands.h"
#include "rpc/object_storage.h"
void initialize_commands();
inline uint16_t
checked_port_value(int64_t value, const char* label) {
if (value < 0 || value > std::numeric_limits<uint16_t>::max())
throw torrent::input_error(std::string("Invalid ") + label + " port number.");
return static_cast<uint16_t>(value);
}
//
// Aliases with CMD_* for the below
//
+4 -12
View File
@@ -54,14 +54,6 @@ set_listen_port_range(const std::string& arg) {
torrent::runtime::client_config()->set_listen_port_range(port_first, port_last);
}
uint16_t
checked_local_port_value(int64_t value, const char* label) {
if (value < 0 || value > 65535)
throw torrent::input_error(std::string("Invalid ") + label + " port number.");
return static_cast<uint16_t>(value);
}
torrent::Object
get_encryption() {
auto encryption_modes = torrent::runtime::network_config()->encryption_modes();
@@ -325,7 +317,7 @@ initialize_command_network() {
auto nw_config = torrent::runtime::network_config();
CMD_ANY ("network.listen.port", [](auto, auto) { return torrent::runtime::network_manager()->listen_port(); });
CMD_ANY_VALUE_V ("network.listen.port.set", [](auto, auto& value) { return torrent::runtime::network_manager()->set_listen_port(value); });
CMD_ANY_VALUE_V ("network.listen.port.set", [](auto, auto& value) { return torrent::runtime::network_manager()->set_listen_port(checked_port_value(value, "listen")); });
CMD_ANY ("network.listen.port.random", [](auto, auto) { return torrent::runtime::client_config()->listen_port_random(); });
CMD_ANY_VALUE_V ("network.listen.port.random.set", [](auto, auto& value) { return torrent::runtime::client_config()->set_listen_port_random(value); });
CMD_ANY ("network.listen.port.range", [](auto, auto) { return listen_port_range(); });
@@ -394,11 +386,11 @@ initialize_command_network() {
CMD_ANY_STRING_V("network.local_address.ipv6.set", [nw_config](auto, auto& str) { return nw_config->set_local_inet6_address(str); });
CMD_ANY ("network.local_port", [nw_config](auto, auto) { return nw_config->local_port_best_match(); });
CMD_ANY_VALUE_V ("network.local_port.set", [nw_config](auto, auto& value) { return nw_config->set_local_port(checked_local_port_value(value, "local")); });
CMD_ANY_VALUE_V ("network.local_port.set", [nw_config](auto, auto& value) { return nw_config->set_local_port(checked_port_value(value, "local")); });
CMD_ANY ("network.local_port.ipv4", [nw_config](auto, auto) { return nw_config->local_inet_port(); });
CMD_ANY_VALUE_V ("network.local_port.ipv4.set", [nw_config](auto, auto& value) { return nw_config->set_local_inet_port(checked_local_port_value(value, "local ipv4")); });
CMD_ANY_VALUE_V ("network.local_port.ipv4.set", [nw_config](auto, auto& value) { return nw_config->set_local_inet_port(checked_port_value(value, "local ipv4")); });
CMD_ANY ("network.local_port.ipv6", [nw_config](auto, auto) { return nw_config->local_inet6_port(); });
CMD_ANY_VALUE_V ("network.local_port.ipv6.set", [nw_config](auto, auto& value) { return nw_config->set_local_inet6_port(checked_local_port_value(value, "local ipv6")); });
CMD_ANY_VALUE_V ("network.local_port.ipv6.set", [nw_config](auto, auto& value) { return nw_config->set_local_inet6_port(checked_port_value(value, "local ipv6")); });
CMD_ANY ("network.proxy.global", [](auto, auto) { return torrent::runtime::proxy_manager()->proxy_url(); });
CMD_ANY_STRING_V("network.proxy.global.set", [](auto, auto& str) { return torrent::runtime::proxy_manager()->set_proxy_url(str); });
+1 -1
View File
@@ -142,7 +142,7 @@ initialize_command_tracker() {
lt_log_print(torrent::LOG_DHT_ERROR, "dht.port.set is no longer supported, use dht.override_port.set", 0);
});
CMD2_ANY ("dht.override_port", [](auto, auto) { return torrent::runtime::network_config()->override_dht_port(); });
CMD2_ANY_VALUE_V ("dht.override_port.set", [](auto, auto& value) { return torrent::runtime::network_manager()->set_dht_port(value); });
CMD2_ANY_VALUE_V ("dht.override_port.set", [](auto, auto& value) { return torrent::runtime::network_manager()->set_dht_port(checked_port_value(value, "DHT override")); });
CMD2_ANY_STRING ("dht.add_node", [](auto, auto& str) { return apply_dht_add_node(str); });
CMD2_ANY ("dht.statistics", [](auto, auto) { return control->dht_manager()->dht_statistics(); });
+1 -1
View File
@@ -82,7 +82,7 @@ DownloadList::find(const torrent::HashString& hash) {
DownloadList::iterator
DownloadList::find_hex(const char* hash) {
if (strlen(hash) < 40)
if (strlen(hash) != 40)
return end();
torrent::HashString key;
+30 -4
View File
@@ -1,5 +1,7 @@
#include "config.h"
#include <cctype>
#include <charconv>
#include <cstring>
#include <cstdio>
#include <limits>
@@ -113,13 +115,37 @@ parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
if (unit <= 0)
throw torrent::input_error("Command::string_to_value_unit(...) received unit <= 0.");
char* last;
if (base != 0 && base != 8 && base != 10 && base != 16)
throw torrent::input_error("Command::string_to_value_unit(...) received invalid base.");
while (parse_is_space(*src))
src++;
if (src[0] == '+')
return src;
if (src[0] == '-') {
if (base == 8 || base == 16)
return src;
if (src[1] == '0')
return src;
}
char* last{};
errno = 0;
*value = strtoll(src, &last, base);
if (errno == ERANGE)
return src;
if (last == src) {
if (strcasecmp(src, "no") == 0) { *value = 0; return src + strlen("no"); }
if (strcasecmp(src, "yes") == 0) { *value = 1; return src + strlen("yes"); }
if (strcasecmp(src, "true") == 0) { *value = 1; return src + strlen("true"); }
*value = 0;
if (strcasecmp(src, "no") == 0) { *value = 0; return src + strlen("no"); }
if (strcasecmp(src, "yes") == 0) { *value = 1; return src + strlen("yes"); }
if (strcasecmp(src, "true") == 0) { *value = 1; return src + strlen("true"); }
if (strcasecmp(src, "false") == 0) { *value = 0; return src + strlen("false"); }
return src;
-34
View File
@@ -1,37 +1,3 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005-2011, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations
// including the two.
//
// You must obey the GNU General Public License in all respects for
// all of the code used other than OpenSSL. If you modify file(s)
// with this exception, you may extend this exception to your version
// of the file(s), but you are not obligated to do so. If you do not
// wish to do so, delete this exception statement from your version.
// If you delete this exception statement from all source files in the
// program, then also delete it here.
//
// Contact: Jari Sundell <sundell.software@gmail.com>
#ifndef RTORRENT_RPC_PARSE_H
#define RTORRENT_RPC_PARSE_H