mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-04 21:29:21 +00:00
Restrict parse value to strtoll with restrictions on input.
This commit is contained in:
+11
-9
@@ -118,18 +118,20 @@ parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
|||||||
if (base != 0 && base != 8 && base != 10 && base != 16)
|
if (base != 0 && base != 8 && base != 10 && base != 16)
|
||||||
throw torrent::input_error("Command::string_to_value_unit(...) received invalid base.");
|
throw torrent::input_error("Command::string_to_value_unit(...) received invalid base.");
|
||||||
|
|
||||||
|
const char* first = src;
|
||||||
|
|
||||||
while (parse_is_space(*src))
|
while (parse_is_space(*src))
|
||||||
src++;
|
src++;
|
||||||
|
|
||||||
if (src[0] == '+')
|
if (src[0] == '+')
|
||||||
return src;
|
return first;
|
||||||
|
|
||||||
if (src[0] == '-') {
|
if (src[0] == '-') {
|
||||||
if (base == 8 || base == 16)
|
if (base == 8 || base == 16)
|
||||||
return src;
|
return first;
|
||||||
|
|
||||||
if (src[1] == '0')
|
if (src[1] == '0')
|
||||||
return src;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* last{};
|
char* last{};
|
||||||
@@ -138,7 +140,7 @@ parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
|||||||
*value = strtoll(src, &last, base);
|
*value = strtoll(src, &last, base);
|
||||||
|
|
||||||
if (errno == ERANGE)
|
if (errno == ERANGE)
|
||||||
return src;
|
return first;
|
||||||
|
|
||||||
if (last == src) {
|
if (last == src) {
|
||||||
*value = 0;
|
*value = 0;
|
||||||
@@ -148,7 +150,7 @@ parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
|||||||
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 first;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (*last) {
|
switch (*last) {
|
||||||
@@ -156,15 +158,15 @@ parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
|||||||
case 'B': ++last; break;
|
case 'B': ++last; break;
|
||||||
case 'k':
|
case 'k':
|
||||||
case 'K':
|
case 'K':
|
||||||
if (!value_fits_shifted(*value, 10)) return src; // overflow guard
|
if (!value_fits_shifted(*value, 10)) return first; // overflow guard
|
||||||
*value = *value << 10; ++last; break;
|
*value = *value << 10; ++last; break;
|
||||||
case 'm':
|
case 'm':
|
||||||
case 'M':
|
case 'M':
|
||||||
if (!value_fits_shifted(*value, 20)) return src; // overflow guard
|
if (!value_fits_shifted(*value, 20)) return first; // overflow guard
|
||||||
*value = *value << 20; ++last; break;
|
*value = *value << 20; ++last; break;
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'G':
|
case 'G':
|
||||||
if (!value_fits_shifted(*value, 30)) return src; // overflow guard
|
if (!value_fits_shifted(*value, 30)) return first; // overflow guard
|
||||||
*value = *value << 30; ++last; break;
|
*value = *value << 30; ++last; break;
|
||||||
// case ' ':
|
// case ' ':
|
||||||
// case '\0': *value = *value * unit; break;
|
// case '\0': *value = *value * unit; break;
|
||||||
@@ -172,7 +174,7 @@ parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
|||||||
default:
|
default:
|
||||||
if (*value > std::numeric_limits<int64_t>::max() / unit ||
|
if (*value > std::numeric_limits<int64_t>::max() / unit ||
|
||||||
*value < std::numeric_limits<int64_t>::min() / unit)
|
*value < std::numeric_limits<int64_t>::min() / unit)
|
||||||
return src; // overflow guard
|
return first; // overflow guard
|
||||||
|
|
||||||
*value = *value * unit;
|
*value = *value * unit;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -71,10 +71,18 @@ rtorrent_Test_Src_SOURCES = $(rtorrent_Test_Common) \
|
|||||||
src/test_command_path.h \
|
src/test_command_path.h \
|
||||||
src/test_command_string.cc \
|
src/test_command_string.cc \
|
||||||
src/test_command_string.h \
|
src/test_command_string.h \
|
||||||
|
src/test_command_throttle.cc \
|
||||||
|
src/test_command_throttle.h \
|
||||||
src/test_command_tracker.cc \
|
src/test_command_tracker.cc \
|
||||||
src/test_command_tracker.h \
|
src/test_command_tracker.h \
|
||||||
src/test_download_list.cc \
|
src/test_download_list.cc \
|
||||||
src/test_download_list.h \
|
src/test_download_list.h \
|
||||||
|
src/test_input_path_input.cc \
|
||||||
|
src/test_input_path_input.h \
|
||||||
|
src/test_session_commit.cc \
|
||||||
|
src/test_session_commit.h \
|
||||||
|
src/test_session_storer.cc \
|
||||||
|
src/test_session_storer.h \
|
||||||
src/test_setup.cc \
|
src/test_setup.cc \
|
||||||
src/test_setup.h \
|
src/test_setup.h \
|
||||||
src/test_ui_download_list.cc \
|
src/test_ui_download_list.cc \
|
||||||
|
|||||||
Reference in New Issue
Block a user