- bitorder::read and bitorder::write may fail because of unaligned access #2734.

This commit is contained in:
Christoffer Lerno
2026-01-12 01:11:31 +01:00
parent 8fa59cbb43
commit e93f22fbda
3 changed files with 18 additions and 8 deletions

View File

@@ -90,33 +90,35 @@ bitstruct UInt128LE : uint128 @littleendian
<*
@require @is_array_or_slice_of_char(bytes) : "argument must be an array, a pointer to an array or a slice of char"
@require is_bitorder($Type) : "type must be a bitorder integer"
@require $defined(*bytes) ||| $defined(bytes[:$Type.sizeof]) : "Data is too short to contain value"
*>
macro read(bytes, $Type)
{
char[] s;
char *ptr;
$switch $kindof(bytes):
$case POINTER:
s = (*bytes)[:$Type.sizeof];
ptr = bytes;
$default:
s = bytes[:$Type.sizeof];
ptr = bytes[..].ptr;
$endswitch
return bitcast(*(char[$Type.sizeof]*)s.ptr, $Type).val;
return bitcast(@unaligned_load(*(char[$Type.sizeof]*)ptr, 1), $Type).val;
}
<*
@require @is_arrayptr_or_slice_of_char(bytes) : "argument must be a pointer to an array or a slice of char"
@require is_bitorder($Type) : "type must be a bitorder integer"
@require $defined(*bytes) ||| $defined(bytes[:$Type.sizeof]) : "Data is not sufficent to hold value"
*>
macro write(x, bytes, $Type)
{
char[] s;
char *ptr;
$switch $kindof(bytes):
$case POINTER:
s = (*bytes)[:$Type.sizeof];
ptr = bytes;
$default:
s = bytes[:$Type.sizeof];
ptr = bytes[..].ptr;
$endswitch
*($typeof(x)*)s.ptr = bitcast(x, $Type).val;
@unaligned_store(*($typeof(x)*)ptr, bitcast(x, $Type).val, 1);
}
macro bool is_bitorder($Type)

View File

@@ -54,6 +54,7 @@
- Incorrect alignment on typedef and local variable debug info.
- Assert on optional-returning-function in a comma expression. #2722
- Creating recursive debug info for functions could cause assertions.
- bitorder::read and bitorder::write may fail because of unaligned access #2734.
### Stdlib changes
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.

View File

@@ -1,5 +1,12 @@
module std::core::bitorder @test;
fn void test_unaligned()
{
usz file_size;
char[64] response;
bitorder::write(file_size, response[9..], ULongLE);
}
fn void test_read()
{
char[*] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };