Skip to content

FFI::cast() from pointer to array is broken #7867

Description

@userqq

Hi!
Not sure its incorrect behaviour, but as you can see FFI::cast when applied to FFI\CData with offset returns data different from copy result.

The following code:

$value = FFI::new('char[26]');
FFI::memcpy($value, implode('', range('a', 'z')), 26);

$slice = FFI::new('char[4]');

echo 'cast from start' . PHP_EOL;
FFI::memcpy($slice, $value, 4);
var_dump($value + 0, $slice, FFI::cast('char[4]', $value));
echo PHP_EOL;

echo 'cast with offset' . PHP_EOL;
FFI::memcpy($slice, $value + 4, 4);
var_dump($value + 4, $slice, FFI::cast('char[4]', $value + 4));
echo PHP_EOL;

Resulted in this output:

cast from start
object(FFI\CData:char*)#3 (1) {
  [0]=>
  string(1) "a"
}
object(FFI\CData:char[4])#2 (4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
  [3]=>
  string(1) "d"
}
object(FFI\CData:char[4])#4 (4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
  [3]=>
  string(1) "d"
}

cast with offset
object(FFI\CData:char*)#4 (1) {
  [0]=>
  string(1) "e"
}
object(FFI\CData:char[4])#2 (4) {
  [0]=>
  string(1) "e"
  [1]=>
  string(1) "f"
  [2]=>
  string(1) "g"
  [3]=>
  string(1) "h"
}
object(FFI\CData:char[4])#5 (4) {
  [0]=>
  string(1) "▒"
  [1]=>
  string(1) "C"
  [2]=>
  string(1) "▒"
  [3]=>
  string(1) "x"
}

But I expected this output instead:

cast from start
object(FFI\CData:char*)#3 (1) {
  [0]=>
  string(1) "a"
}
object(FFI\CData:char[4])#2 (4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
  [3]=>
  string(1) "d"
}
object(FFI\CData:char[4])#4 (4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
  [3]=>
  string(1) "d"
}

cast with offset
object(FFI\CData:char*)#4 (1) {
  [0]=>
  string(1) "e"
}
object(FFI\CData:char[4])#2 (4) {
  [0]=>
  string(1) "e"
  [1]=>
  string(1) "f"
  [2]=>
  string(1) "g"
  [3]=>
  string(1) "h"
}
object(FFI\CData:char[4])#5 (4) {
  [0]=>
  string(1) "e"
  [1]=>
  string(1) "f"
  [2]=>
  string(1) "g"
  [3]=>
  string(1) "h"
}

PHP Version

PHP 8.1.1

Operating System

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions