mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-14 05:06:16 +00:00
Guard the value suffixes against negative overflow.
The k, m and g guards only checked the positive side, so -4611686018427387904K became 0.
This commit is contained in:
+9
-3
@@ -102,6 +102,12 @@ parse_whole_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
value_fits_shifted(int64_t value, int shift) {
|
||||||
|
return value <= (std::numeric_limits<int64_t>::max() >> shift) &&
|
||||||
|
value >= (std::numeric_limits<int64_t>::min() >> shift);
|
||||||
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
||||||
if (unit <= 0)
|
if (unit <= 0)
|
||||||
@@ -124,15 +130,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 > (int64_t)0x1FFFFFFFFFFFFF) return src; // overflow guard
|
if (!value_fits_shifted(*value, 10)) return src; // overflow guard
|
||||||
*value = *value << 10; ++last; break;
|
*value = *value << 10; ++last; break;
|
||||||
case 'm':
|
case 'm':
|
||||||
case 'M':
|
case 'M':
|
||||||
if (*value > (int64_t)0x7FFFFFFFFFF) return src; // overflow guard
|
if (!value_fits_shifted(*value, 20)) return src; // overflow guard
|
||||||
*value = *value << 20; ++last; break;
|
*value = *value << 20; ++last; break;
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'G':
|
case 'G':
|
||||||
if (*value > (int64_t)0x1FFFFFFFF) return src; // overflow guard
|
if (!value_fits_shifted(*value, 30)) return src; // 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;
|
||||||
|
|||||||
Reference in New Issue
Block a user