Skip to content

Commit f49d6f0

Browse files
committed
Fix encoding of integers with units
Signed-off-by: Paul Guyot <[email protected]>
1 parent d9040e9 commit f49d6f0

File tree

3 files changed

+16
-9
lines changed

3 files changed

+16
-9
lines changed

src/libAtomVM/bitstring.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,14 @@ bool bitstring_insert_any_integer(uint8_t *dst, avm_int_t offset, avm_int64_t va
6363
if (bs_flags != 0) {
6464
return false;
6565
}
66+
// value is truncated to 64 bits
67+
if (n > 8 * sizeof(value)) {
68+
offset += n - (8 * sizeof(value));
69+
n = 8 * sizeof(value);
70+
}
6671
for (int i = 0; i < n; ++i) {
6772
int k = (n - 1) - i;
68-
int bit_val = (value & (0x01 << k)) >> k;
73+
int bit_val = (value & (0x01LL << k)) >> k;
6974
if (bit_val) {
7075
int bit_pos = offset + i;
7176
int byte_pos = bit_pos >> 3; // div 8

src/libAtomVM/opcodesswitch.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3643,14 +3643,10 @@ static bool maybe_call_native(Context *ctx, AtomString module_name, AtomString f
36433643

36443644
avm_int64_t src_value = term_maybe_unbox_int64(src);
36453645
avm_int_t size_value = term_to_int(size);
3646-
if (unit != 1) {
3647-
TRACE("bs_put_integer: unit is not 1\n");
3648-
RAISE_ERROR(UNSUPPORTED_ATOM);
3649-
}
36503646

36513647
TRACE("bs_put_integer/5, fail=%u size=%li unit=%u flags=%x src=%i\n", (unsigned) fail, size_value, (unsigned) unit, (int) flags_value, (unsigned int) src_value);
36523648

3653-
bool result = bitstring_insert_integer(ctx->bs, ctx->bs_offset, src_value, size_value, flags_value);
3649+
bool result = bitstring_insert_integer(ctx->bs, ctx->bs_offset, src_value, size_value * unit, flags_value);
36543650
if (UNLIKELY(!result)) {
36553651
TRACE("bs_put_integer: Failed to insert integer into binary\n");
36563652
RAISE_ERROR(BADARG_ATOM);

tests/erlang_tests/test_bs.erl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ start() ->
3636

3737
ok = test_create_with_invalid_int_value(),
3838
ok = test_create_with_invalid_int_size(),
39-
ok = test_create_with_unsupported_int_unit(),
39+
ok = test_create_with_int_unit(),
4040
ok = test_create_with_unsupported_unaligned_int_size(),
4141
ok = test_create_with_int_little_endian(),
4242
ok = test_create_with_int_signed(),
@@ -119,8 +119,14 @@ test_create_with_invalid_int_value() ->
119119
test_create_with_invalid_int_size() ->
120120
expect_error(fun() -> create_int_binary(16#F, id(bar)) end, badarg).
121121

122-
test_create_with_unsupported_int_unit() ->
123-
atom_unsupported(fun() -> create_int_binary_unit_3(16#F, id(32)) end).
122+
test_create_with_int_unit() ->
123+
<<1, 66, 67>> = create_int_binary_unit_3(16#14243, id(8)),
124+
<<0, 0, 0, 1, 66, 67>> = create_int_binary_unit_3(16#14243, id(16)),
125+
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15>> = create_int_binary_unit_3(16#F, id(32)),
126+
<<0, 0, 0, 0, 16#12, 16#34, 16#56, 16#78, 16#90, 16#AB, 16#CD, 16#EF>> = create_int_binary_unit_3(
127+
16#1234567890ABCDEF, id(32)
128+
),
129+
ok.
124130

125131
test_create_with_unsupported_unaligned_int_size() ->
126132
atom_unsupported(fun() -> create_int_binary(16#FFFF, id(28)) end).

0 commit comments

Comments
 (0)