From b55dc586bde6eadaf068fe9745147774f3c2cd38 Mon Sep 17 00:00:00 2001 From: krishvishal Date: Tue, 25 Mar 2025 10:10:15 +0530 Subject: [PATCH 1/5] change `compute_shl` implementation to handle negation with overflow --- core/vdbe/insn.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index 1e2af1820..34c5c0005 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -975,7 +975,15 @@ 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 >= 64 || rhs <= -64 { + 0 + } else if rhs > 0 { + lhs << rhs + } else { + lhs >> -rhs + } } pub fn exec_shift_right(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue { From a8129d5e58327c17f991a207eb7d152e12c7b1d3 Mon Sep 17 00:00:00 2001 From: krishvishal Date: Tue, 25 Mar 2025 10:26:08 +0530 Subject: [PATCH 2/5] Add TCL tests for `compute_shl` --- testing/select.test | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/testing/select.test b/testing/select.test index f10f33b24..6f5fe485b 100755 --- a/testing/select.test +++ b/testing/select.test @@ -165,3 +165,32 @@ 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} From f12e3a6993d57626eed89c7482a881bae75e9ecf Mon Sep 17 00:00:00 2001 From: krishvishal Date: Tue, 25 Mar 2025 10:28:48 +0530 Subject: [PATCH 3/5] For a few TCL tests more. --- testing/select.test | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/testing/select.test b/testing/select.test index 6f5fe485b..626803431 100755 --- a/testing/select.test +++ b/testing/select.test @@ -194,3 +194,20 @@ do_execsql_test select_shl_large_shifts { 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} From 785be8479f23e4f4c23cf01fd7370fc09e4bd0d1 Mon Sep 17 00:00:00 2001 From: krishvishal Date: Tue, 25 Mar 2025 11:43:51 +0530 Subject: [PATCH 4/5] Fix a fuzzer failure and add tcl test covering the failure --- core/vdbe/insn.rs | 45 +++++++++++++++++++++++++++++++++------------ testing/select.test | 4 ++++ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index 34c5c0005..583a094b0 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -977,12 +977,24 @@ pub fn exec_shift_left(mut lhs: &OwnedValue, mut rhs: &OwnedValue) -> OwnedValue fn compute_shl(lhs: i64, rhs: i64) -> i64 { if rhs == 0 { lhs - } else if rhs >= 64 || rhs <= -64 { - 0 } else if rhs > 0 { - lhs << rhs + // for positive shifts, if it's too large return 0 + if rhs >= 64 { + 0 + } else { + lhs << rhs + } } else { - lhs >> -rhs + // 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) + } } } @@ -1021,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) + } } } diff --git a/testing/select.test b/testing/select.test index 626803431..74856eda4 100755 --- a/testing/select.test +++ b/testing/select.test @@ -211,3 +211,7 @@ do_execsql_test select_shl_numeric_types { 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} \ No newline at end of file From 1660ae5542f6d9f7129f4fbb9b2d3483c0a2f590 Mon Sep 17 00:00:00 2001 From: krishvishal Date: Tue, 25 Mar 2025 12:04:48 +0530 Subject: [PATCH 5/5] missed adding _ and a space. --- testing/select.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/select.test b/testing/select.test index 74856eda4..f8b033077 100755 --- a/testing/select.test +++ b/testing/select.test @@ -212,6 +212,6 @@ do_execsql_test select_shl_numeric_types { SELECT 1.5 << 2; } {4 4 4} -do execsql_test select_fuzz_failure_case { +do_execsql_test select_fuzz_failure_case { SELECT (-9 << ((-6) << (9)) >> ((5)) % -10 - + - (-9)); -}{-16} \ No newline at end of file +} {-16} \ No newline at end of file