mirror of
https://github.com/pocketpy/pocketpy
synced 2025-11-08 20:50:16 +00:00
fix: singned integer overflow in parse_uint()
This commit is contained in:
parent
f9c00fd706
commit
b222fa320b
@ -509,11 +509,11 @@ IntParsingResult parse_uint(std::string_view text, i64* out, int base){
|
|||||||
if(base == 10){
|
if(base == 10){
|
||||||
// 10-base 12334
|
// 10-base 12334
|
||||||
if(text.length() == 0) return IntParsingResult::Failure;
|
if(text.length() == 0) return IntParsingResult::Failure;
|
||||||
|
constexpr i64 max_i64 = std::numeric_limits<i64>::max();
|
||||||
for(char c : text){
|
for(char c : text){
|
||||||
if(c >= '0' && c <= '9'){
|
if(c >= '0' && c <= '9'){
|
||||||
i64 prev_out = *out;
|
if (*out > (max_i64 - (c - '0')) / 10) return IntParsingResult::Overflow;
|
||||||
*out = (*out * 10) + (c - '0');
|
*out = (*out * 10) + (c - '0');
|
||||||
if(*out < prev_out) return IntParsingResult::Overflow;
|
|
||||||
}else{
|
}else{
|
||||||
return IntParsingResult::Failure;
|
return IntParsingResult::Failure;
|
||||||
}
|
}
|
||||||
@ -523,11 +523,11 @@ IntParsingResult parse_uint(std::string_view text, i64* out, int base){
|
|||||||
// 2-base 0b101010
|
// 2-base 0b101010
|
||||||
if(f_startswith_2(text, "0b")) text.remove_prefix(2);
|
if(f_startswith_2(text, "0b")) text.remove_prefix(2);
|
||||||
if(text.length() == 0) return IntParsingResult::Failure;
|
if(text.length() == 0) return IntParsingResult::Failure;
|
||||||
|
constexpr i64 mask = i64{1} << 63;
|
||||||
for(char c : text){
|
for(char c : text){
|
||||||
if(c == '0' || c == '1'){
|
if(c == '0' || c == '1'){
|
||||||
i64 prev_out = *out;
|
if (*out & mask) return IntParsingResult::Overflow;
|
||||||
*out = (*out << 1) | (c - '0');
|
*out = (*out << 1) | (c - '0');
|
||||||
if(*out < prev_out) return IntParsingResult::Overflow;
|
|
||||||
}else{
|
}else{
|
||||||
return IntParsingResult::Failure;
|
return IntParsingResult::Failure;
|
||||||
}
|
}
|
||||||
@ -537,11 +537,11 @@ IntParsingResult parse_uint(std::string_view text, i64* out, int base){
|
|||||||
// 8-base 0o123
|
// 8-base 0o123
|
||||||
if(f_startswith_2(text, "0o")) text.remove_prefix(2);
|
if(f_startswith_2(text, "0o")) text.remove_prefix(2);
|
||||||
if(text.length() == 0) return IntParsingResult::Failure;
|
if(text.length() == 0) return IntParsingResult::Failure;
|
||||||
|
constexpr i64 mask = i64{7} << 60;
|
||||||
for(char c : text){
|
for(char c : text){
|
||||||
if(c >= '0' && c <= '7'){
|
if(c >= '0' && c <= '7'){
|
||||||
i64 prev_out = *out;
|
if (*out & mask) return IntParsingResult::Overflow;
|
||||||
*out = (*out << 3) | (c - '0');
|
*out = (*out << 3) | (c - '0');
|
||||||
if(*out < prev_out) return IntParsingResult::Overflow;
|
|
||||||
}else{
|
}else{
|
||||||
return IntParsingResult::Failure;
|
return IntParsingResult::Failure;
|
||||||
}
|
}
|
||||||
@ -551,17 +551,15 @@ IntParsingResult parse_uint(std::string_view text, i64* out, int base){
|
|||||||
// 16-base 0x123
|
// 16-base 0x123
|
||||||
if(f_startswith_2(text, "0x")) text.remove_prefix(2);
|
if(f_startswith_2(text, "0x")) text.remove_prefix(2);
|
||||||
if(text.length() == 0) return IntParsingResult::Failure;
|
if(text.length() == 0) return IntParsingResult::Failure;
|
||||||
|
constexpr i64 mask = i64{15} << 59;
|
||||||
for(char c : text){
|
for(char c : text){
|
||||||
i64 prev_out = *out;
|
if (*out & mask) return IntParsingResult::Overflow;
|
||||||
if(c >= '0' && c <= '9'){
|
if(c >= '0' && c <= '9'){
|
||||||
*out = (*out << 4) | (c - '0');
|
*out = (*out << 4) | (c - '0');
|
||||||
if(*out < prev_out) return IntParsingResult::Overflow;
|
|
||||||
}else if(c >= 'a' && c <= 'f'){
|
}else if(c >= 'a' && c <= 'f'){
|
||||||
*out = (*out << 4) | (c - 'a' + 10);
|
*out = (*out << 4) | (c - 'a' + 10);
|
||||||
if(*out < prev_out) return IntParsingResult::Overflow;
|
|
||||||
}else if(c >= 'A' && c <= 'F'){
|
}else if(c >= 'A' && c <= 'F'){
|
||||||
*out = (*out << 4) | (c - 'A' + 10);
|
*out = (*out << 4) | (c - 'A' + 10);
|
||||||
if(*out < prev_out) return IntParsingResult::Overflow;
|
|
||||||
}else{
|
}else{
|
||||||
return IntParsingResult::Failure;
|
return IntParsingResult::Failure;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -142,7 +142,7 @@ except ZeroDivisionError:
|
|||||||
assert not 1 < 2 > 3
|
assert not 1 < 2 > 3
|
||||||
|
|
||||||
try:
|
try:
|
||||||
x = eval("231231312312312312312312312312312312314354657553423345632")
|
x = eval("0x12345678901234567890")
|
||||||
print(f"eval should fail, but got {x!r}")
|
print(f"eval should fail, but got {x!r}")
|
||||||
exit(1)
|
exit(1)
|
||||||
except SyntaxError:
|
except SyntaxError:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user