Skip to content

Commit a7e3396

Browse files
committed
Fix byteOffset typo in BitArray DataView construction
BitArray$BitArray$data used `array.byteOffest` (swpped 'e'), which evaluated to undefined and caused DataView to always read from offset 0 instead of the slice's actual start.
1 parent 63b8048 commit a7e3396

6 files changed

Lines changed: 30 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@
1111
### Formatter
1212

1313
### Bug fixes
14+
15+
- Fixed a bug where `BitArray$BitArray$data` constructed a `DataView` with
16+
offset 0 instead of the slice's actual byte offset, causing sliced bit arrays
17+
to read from the wrong position in the underlying buffer on JavaScript.
18+
([John Downey](https://github.com/jtdowney))

compiler-core/templates/prelude.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ export const BitArray$BitArray$data = (bitArray) => {
301301
if (bitArray.bitSize % 8 !== 0)
302302
throw new Error("BitArray$BitArray$data called on un-aligned bit array");
303303
const array = bitArray.rawBuffer;
304-
return new DataView(array.buffer, array.byteOffest, bitArray.byteLength);
304+
return new DataView(array.buffer, array.byteOffset, bitArray.byteLength);
305305
};
306306

307307
/**

test/language/test/ffi.gleam

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,7 @@ pub fn to_dynamic(a: x) -> Dynamic
2727
@external(erlang, "ffi_erlang", "to_codepoint")
2828
@external(javascript, "./ffi_javascript.mjs", "toCodepoint")
2929
pub fn utf_codepoint(a: Int) -> UtfCodepoint
30+
31+
@external(erlang, "ffi_erlang", "read_uint16_from_bit_array")
32+
@external(javascript, "./ffi_javascript.mjs", "readUint16FromBitArray")
33+
pub fn read_uint16_from_bit_array(a: BitArray) -> Int

test/language/test/ffi_erlang.erl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
-module(ffi_erlang).
22

33
-export([
4-
to_string/1, append/2, print/1, file_exists/1, halt/1, to_dynamic/1, to_codepoint/1
4+
to_string/1, append/2, print/1, file_exists/1, halt/1, to_dynamic/1, to_codepoint/1,
5+
read_uint16_from_bit_array/1
56
]).
67

78
append(A, B) ->
@@ -25,3 +26,7 @@ to_dynamic(X) ->
2526
X.
2627

2728
to_codepoint(X) -> X.
29+
30+
read_uint16_from_bit_array(BitArray) ->
31+
<<Value:16/big-unsigned-integer, _/binary>> = BitArray,
32+
Value.

test/language/test/ffi_javascript.mjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { UtfCodepoint } from "./gleam.mjs";
1+
import { UtfCodepoint, BitArray$BitArray$data } from "./gleam.mjs";
22

33
let fs;
44

@@ -56,3 +56,7 @@ export function toDynamic(a) {
5656
export function toCodepoint(x) {
5757
return new UtfCodepoint(x);
5858
}
59+
60+
export function readUint16FromBitArray(bitArray) {
61+
return BitArray$BitArray$data(bitArray).getUint16(0);
62+
}

test/language/test/language/bit_array_test.gleam

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import ffi
2+
import gleam/bit_array
23

34
pub fn utf8_emoji_equal_test() {
45
let left = <<"Gleam":utf8, "👍":utf8>>
@@ -174,3 +175,11 @@ pub fn unicode_overflow_test() {
174175
let string = "5"
175176
assert "🌵" != string
176177
}
178+
179+
pub fn sliced_bit_array_data_view_offset_test() {
180+
let data = <<0xAA, 0xBB, 0xCC, 0xDD>>
181+
let assert Ok(sliced) = bit_array.slice(data, 1, 3)
182+
assert sliced == <<0xBB, 0xCC, 0xDD>>
183+
let value = ffi.read_uint16_from_bit_array(sliced)
184+
assert value == 48_076
185+
}

0 commit comments

Comments
 (0)