Skip to content

Commit 4cd9298

Browse files
committed
Merge branch 'PHP-8.2'
* PHP-8.2: Fix incorrect bitshifting and masking in ffi bitfield (#10403)
2 parents 2740920 + d5b307c commit 4cd9298

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

ext/ffi/ffi.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,22 +650,22 @@ static uint64_t zend_ffi_bit_field_read(void *ptr, zend_ffi_field *field) /* {{{
650650
/* Read partial prefix byte */
651651
if (pos != 0) {
652652
size_t num_bits = 8 - pos;
653-
mask = ((1U << num_bits) - 1U) << pos;
653+
mask = (1U << num_bits) - 1U;
654654
val = (*p++ >> pos) & mask;
655655
insert_pos += num_bits;
656656
}
657657

658658
/* Read full bytes */
659659
while (p < last_p) {
660-
val |= *p++ << insert_pos;
660+
val |= (uint64_t) *p++ << insert_pos;
661661
insert_pos += 8;
662662
}
663663

664664
/* Read partial suffix byte */
665665
if (p == last_p) {
666666
size_t num_bits = last_bit % 8 + 1;
667667
mask = (1U << num_bits) - 1U;
668-
val |= (*p & mask) << insert_pos;
668+
val |= (uint64_t) (*p & mask) << insert_pos;
669669
}
670670

671671
return val;

ext/ffi/tests/gh10403.phpt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
GH-10403: Fix incorrect bitshifting and masking in ffi bitfield
3+
--EXTENSIONS--
4+
ffi
5+
--SKIPIF--
6+
<?php if (PHP_INT_SIZE != 8) echo "skip this test is for 64-bit only"; ?>
7+
--FILE--
8+
<?php
9+
$ffi = FFI::cdef(<<<EOF
10+
struct MyStruct {
11+
uint64_t x : 10;
12+
uint64_t y : 54;
13+
};
14+
EOF);
15+
16+
$test_struct = $ffi->new('struct MyStruct');
17+
$test_struct->x = 1023;
18+
$test_values = [0x3fafbfcfdfefff, 0x01020304050607, 0, 0x3fffffffffffff, 0x2ffffffffffff5];
19+
foreach ($test_values as $test_value) {
20+
$test_struct->y = $test_value;
21+
var_dump($test_struct->y === $test_value);
22+
}
23+
var_dump($test_struct->x);
24+
--EXPECT--
25+
bool(true)
26+
bool(true)
27+
bool(true)
28+
bool(true)
29+
bool(true)
30+
int(1023)

0 commit comments

Comments
 (0)