mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-25 12:04:21 +01:00
Merge 'Fix compute_shl negate with overflow' from Krishna Vishal
Fixes #1156 - Changed `compute_shl` implementation to handle negation with overflow. - Added TCL tests. Closes #1171
This commit is contained in:
@@ -975,7 +975,27 @@ pub fn exec_shift_left(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue
|
||||
}
|
||||
|
||||
fn compute_shl(lhs: i64, rhs: i64) -> i64 {
|
||||
compute_shr(lhs, -rhs)
|
||||
if rhs == 0 {
|
||||
lhs
|
||||
} else if rhs > 0 {
|
||||
// for positive shifts, if it's too large return 0
|
||||
if rhs >= 64 {
|
||||
0
|
||||
} else {
|
||||
lhs << rhs
|
||||
}
|
||||
} else {
|
||||
// for negative shifts, check if it's i64::MIN to avoid overflow on negation
|
||||
if rhs == i64::MIN || rhs <= -64 {
|
||||
if lhs < 0 {
|
||||
-1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
} else {
|
||||
lhs >> (-rhs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exec_shift_right(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue {
|
||||
@@ -1013,15 +1033,24 @@ pub fn exec_shift_right(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValu
|
||||
fn compute_shr(lhs: i64, rhs: i64) -> i64 {
|
||||
if rhs == 0 {
|
||||
lhs
|
||||
} else if rhs >= 64 && lhs >= 0 || rhs <= -64 {
|
||||
0
|
||||
} else if rhs >= 64 && lhs < 0 {
|
||||
-1
|
||||
} else if rhs < 0 {
|
||||
// if negative do left shift
|
||||
lhs << (-rhs)
|
||||
} else if rhs > 0 {
|
||||
// for positive right shifts
|
||||
if rhs >= 64 {
|
||||
if lhs < 0 {
|
||||
-1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
} else {
|
||||
lhs >> rhs
|
||||
}
|
||||
} else {
|
||||
lhs >> rhs
|
||||
// for negative right shifts, check if it's i64::MIN to avoid overflow
|
||||
if rhs == i64::MIN || -rhs >= 64 {
|
||||
0
|
||||
} else {
|
||||
lhs << (-rhs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,3 +165,53 @@ do_execsql_test select-not-like-expression {
|
||||
do_execsql_test select-like-expression {
|
||||
select 2 % 0.5
|
||||
} {}
|
||||
|
||||
do_execsql_test select_shl_large_negative_float {
|
||||
SELECT 1 << -1e19;
|
||||
SELECT 1 << -9223372036854775808; -- i64::MIN
|
||||
SELECT 1 << 9223372036854775807; -- i64::MAX
|
||||
} {0 0 0}
|
||||
|
||||
do_execsql_test select_shl_basic {
|
||||
SELECT 1 << 0, 1 << 1, 1 << 2, 1 << 3;
|
||||
SELECT 2 << 0, 2 << 1, 2 << 2, 2 << 3;
|
||||
} {1|2|4|8
|
||||
2|4|8|16}
|
||||
|
||||
do_execsql_test select_shl_negative_numbers {
|
||||
SELECT -1 << 0, -1 << 1, -1 << 2, -1 << 3;
|
||||
SELECT -2 << 0, -2 << 1, -2 << 2, -2 << 3;
|
||||
} {-1|-2|-4|-8
|
||||
-2|-4|-8|-16}
|
||||
do_execsql_test select_shl_negative_shifts {
|
||||
SELECT 8 << -1, 8 << -2, 8 << -3, 8 << -4;
|
||||
SELECT -8 << -1, -8 << -2, -8 << -3, -8 << -4;
|
||||
} {4|2|1|0
|
||||
-4|-2|-1|-1}
|
||||
|
||||
do_execsql_test select_shl_large_shifts {
|
||||
SELECT 1 << 62, 1 << 63, 1 << 64;
|
||||
SELECT -1 << 62, -1 << 63, -1 << 64;
|
||||
} {4611686018427387904|-9223372036854775808|0
|
||||
-4611686018427387904|-9223372036854775808|0}
|
||||
|
||||
do_execsql_test select_shl_text_conversion {
|
||||
SELECT '1' << '2';
|
||||
SELECT '8' << '-2';
|
||||
SELECT '-4' << '2';
|
||||
} {4 2 -16}
|
||||
|
||||
do_execsql_test select_shl_chained {
|
||||
SELECT (1 << 2) << 3;
|
||||
SELECT (2 << 1) << (1 << 1);
|
||||
} {32 16}
|
||||
|
||||
do_execsql_test select_shl_numeric_types {
|
||||
SELECT CAST(1 AS INTEGER) << 2;
|
||||
SELECT 1.0 << 2;
|
||||
SELECT 1.5 << 2;
|
||||
} {4 4 4}
|
||||
|
||||
do_execsql_test select_fuzz_failure_case {
|
||||
SELECT (-9 << ((-6) << (9)) >> ((5)) % -10 - + - (-9));
|
||||
} {-16}
|
||||
Reference in New Issue
Block a user