mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-18 15:16:17 +00:00
Reverted parse value to strtoll with restrictions on input.
This commit is contained in:
+25
-20
@@ -115,37 +115,42 @@ parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
|||||||
if (unit <= 0)
|
if (unit <= 0)
|
||||||
throw torrent::input_error("Command::string_to_value_unit(...) received unit <= 0.");
|
throw torrent::input_error("Command::string_to_value_unit(...) received unit <= 0.");
|
||||||
|
|
||||||
const char* first = src;
|
if (base != 0 && base != 8 && base != 10 && base != 16)
|
||||||
|
throw torrent::input_error("Command::string_to_value_unit(...) received invalid base.");
|
||||||
|
|
||||||
while (std::isspace(static_cast<unsigned char>(*first)))
|
while (parse_is_space(*src))
|
||||||
first++;
|
src++;
|
||||||
|
|
||||||
if ((base == 0 || base == 16) && first[0] == '0' && (first[1] == 'x' || first[1] == 'X')) {
|
if (src[0] == '+')
|
||||||
first += 2;
|
|
||||||
base = 16;
|
|
||||||
|
|
||||||
} else if (base == 0) {
|
|
||||||
base = 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto result = std::from_chars(first, first + std::strlen(first), *value, base);
|
|
||||||
|
|
||||||
if (result.ec == std::errc::result_out_of_range)
|
|
||||||
return src;
|
return src;
|
||||||
|
|
||||||
if (result.ec != std::errc()) {
|
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) {
|
||||||
*value = 0;
|
*value = 0;
|
||||||
|
|
||||||
if (strcasecmp(src, "no") == 0) { *value = 0; return src + strlen("no"); }
|
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, "yes") == 0) { *value = 1; return src + strlen("yes"); }
|
||||||
if (strcasecmp(src, "true") == 0) { *value = 1; return src + strlen("true"); }
|
if (strcasecmp(src, "true") == 0) { *value = 1; return src + strlen("true"); }
|
||||||
if (strcasecmp(src, "false") == 0) { *value = 0; return src + strlen("false"); }
|
if (strcasecmp(src, "false") == 0) { *value = 0; return src + strlen("false"); }
|
||||||
|
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* last = result.ptr;
|
|
||||||
|
|
||||||
switch (*last) {
|
switch (*last) {
|
||||||
case 'b':
|
case 'b':
|
||||||
case 'B': ++last; break;
|
case 'B': ++last; break;
|
||||||
|
|||||||
@@ -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
|
#ifndef RTORRENT_RPC_PARSE_H
|
||||||
#define RTORRENT_RPC_PARSE_H
|
#define RTORRENT_RPC_PARSE_H
|
||||||
|
|
||||||
|
|||||||
+13
-3
@@ -42,7 +42,11 @@ TestParse::test_whole_value_bases() {
|
|||||||
CPPUNIT_ASSERT(!rpc::parse_whole_value_nothrow("-0x1f", &value));
|
CPPUNIT_ASSERT(!rpc::parse_whole_value_nothrow("-0x1f", &value));
|
||||||
|
|
||||||
CPPUNIT_ASSERT(rpc::parse_whole_value_nothrow("0022", &value));
|
CPPUNIT_ASSERT(rpc::parse_whole_value_nothrow("0022", &value));
|
||||||
CPPUNIT_ASSERT_EQUAL(int64_t{22}, value);
|
CPPUNIT_ASSERT_EQUAL(int64_t{022}, value);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT(!rpc::parse_whole_value_nothrow("0028", &value));
|
||||||
|
CPPUNIT_ASSERT(!rpc::parse_whole_value_nothrow("+022", &value));
|
||||||
|
CPPUNIT_ASSERT(!rpc::parse_whole_value_nothrow("-022", &value));
|
||||||
|
|
||||||
CPPUNIT_ASSERT(rpc::parse_whole_value_nothrow("22", &value));
|
CPPUNIT_ASSERT(rpc::parse_whole_value_nothrow("22", &value));
|
||||||
CPPUNIT_ASSERT_EQUAL(int64_t{22}, value);
|
CPPUNIT_ASSERT_EQUAL(int64_t{22}, value);
|
||||||
@@ -53,13 +57,19 @@ TestParse::test_whole_value_bases() {
|
|||||||
CPPUNIT_ASSERT(rpc::parse_whole_value_nothrow("0x1f", &value, 16));
|
CPPUNIT_ASSERT(rpc::parse_whole_value_nothrow("0x1f", &value, 16));
|
||||||
CPPUNIT_ASSERT_EQUAL(int64_t{31}, value);
|
CPPUNIT_ASSERT_EQUAL(int64_t{31}, value);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT(rpc::parse_whole_value_nothrow("22", &value, 8));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(int64_t{022}, value);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT(rpc::parse_whole_value_nothrow("022", &value, 8));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(int64_t{022}, value);
|
||||||
|
|
||||||
const char* no_digits = "0x";
|
const char* no_digits = "0x";
|
||||||
CPPUNIT_ASSERT(!rpc::parse_whole_value_nothrow(no_digits, &value));
|
CPPUNIT_ASSERT(!rpc::parse_whole_value_nothrow(no_digits, &value));
|
||||||
CPPUNIT_ASSERT_EQUAL(no_digits, rpc::parse_value_nothrow(no_digits, &value));
|
CPPUNIT_ASSERT_EQUAL(no_digits + 1, rpc::parse_value_nothrow(no_digits, &value));
|
||||||
|
|
||||||
const char* bad_digits = "0xzz";
|
const char* bad_digits = "0xzz";
|
||||||
CPPUNIT_ASSERT(!rpc::parse_whole_value_nothrow(bad_digits, &value));
|
CPPUNIT_ASSERT(!rpc::parse_whole_value_nothrow(bad_digits, &value));
|
||||||
CPPUNIT_ASSERT_EQUAL(bad_digits, rpc::parse_value_nothrow(bad_digits, &value));
|
CPPUNIT_ASSERT_EQUAL(bad_digits + 1, rpc::parse_value_nothrow(bad_digits, &value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user