math.big: fix assert big.integer_from_int(1) == big.integer_from_bytes([u8(0), 0, 0, 0, 1]) (fix #23115) (#23124)

This commit is contained in:
Delyan Angelov 2024-12-10 18:18:30 +02:00 committed by GitHub
parent 6db0a8b7ea
commit ef7fdd0f84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 2 deletions

View File

@ -849,3 +849,23 @@ fn test_set_bit() {
a.set_bit(100, false)
assert a == b
}
fn test_integer_from_bytes_ignores_potential_leading_zero_bytes() {
bint0 := big.integer_from_int(0)
for j in 0 .. 10 {
assert bint0 == big.integer_from_bytes([]u8{len: j}, signum: 1)
assert bint0 == big.integer_from_bytes([]u8{len: j}, signum: 0)
assert bint0 == big.integer_from_bytes([]u8{len: j}, signum: -1)
}
for i in 0 .. 10 {
bint := big.integer_from_int(i)
nbint := big.integer_from_int(-i)
for j in 0 .. 15 {
mut input := []u8{len: j}
input << i
assert bint == big.integer_from_bytes(input)
assert bint == big.integer_from_bytes(input, signum: 1)
assert nbint == big.integer_from_bytes(input, signum: -1)
}
}
}

View File

@ -126,11 +126,23 @@ pub:
// If you want a negative integer, use in the following manner:
// `value := big.integer_from_bytes(bytes, signum: -1)`
@[direct_array_access]
pub fn integer_from_bytes(input []u8, config IntegerConfig) Integer {
pub fn integer_from_bytes(oinput []u8, config IntegerConfig) Integer {
// Thank you to Miccah (@mcastorina) for this implementation and relevant unit tests.
if input.len == 0 {
if oinput.len == 0 {
return integer_from_int(0)
}
// Ignore leading 0 bytes:
mut first_non_zero_index := -1
for i in 0 .. oinput.len {
if oinput[i] != 0 {
first_non_zero_index = i
break
}
}
if first_non_zero_index == -1 {
return integer_from_int(0)
}
input := oinput[first_non_zero_index..]
// pad input
mut padded_input := []u8{len: ((input.len + 3) & ~0x3) - input.len, cap: (input.len + 3) & ~0x3}
padded_input << input