Open
Description
Description
The following code:
<?php
echo 'Creating FFI struct...' . PHP_EOL;
$value = FFI::new('struct {
int32_t length;
char data[];
}');
echo 'Our struct is:' . PHP_EOL;
var_dump($value);
echo 'Our struct->data is:' . PHP_EOL;
var_dump($value->data);
echo 'Please keep in memory following will not work:' . PHP_EOL;
try {
$value->data = FFI::new('char[4]');
} catch (Throwable $t) {
echo ' - ' . $t->getMessage() . PHP_EOL;
}
echo PHP_EOL . 'Let\'s try something dirty:' . PHP_EOL;
var_dump($value->data[0]); // Well, it's ok, FFI is unsafe
var_dump($value->data[1000]); // No problem at all, we should carefully check boundaries
echo PHP_EOL . 'And even more dirtier:' . PHP_EOL;
$value->data[0] = 'a';
var_dump($value);
var_dump($value->data[0]);
echo 'I think I could broke something.' . PHP_EOL;
echo PHP_EOL . 'Let\'s fill our struct with value: ' . PHP_EOL;
FFI::memcpy($value, pack('V', 5), 4);
var_dump($value);
echo PHP_EOL . 'Will it work for array member? ' . PHP_EOL;
try {
FFI::memcpy($value, pack('V', 5) . 'aaaa', 8);
var_dump($value);
} catch (Throwable $t) {
echo ' - ' . $t->getMessage() . PHP_EOL;
echo 'Seems like it won\'t.' . PHP_EOL;
}
echo PHP_EOL . 'Maybe I can assign data directly to array member? ' . PHP_EOL;
try {
FFI::memcpy($value->data, 'aaaa', 4);
var_dump($value);
} catch (Throwable $t) {
echo ' - ' . $t->getMessage() . PHP_EOL;
echo 'Doesn\'t work either.' . PHP_EOL;
}
echo PHP_EOL . 'Or maybe I can assign to array member itself? ' . PHP_EOL;
try {
$value->data = FFI::new('char[4]');
var_dump($value);
} catch (Throwable) {
echo ' - ' . $t->getMessage() . PHP_EOL;
}
echo 'Do you remember last time we did this we got different error: ' . PHP_EOL;
echo ' - It was "Incompatible types when assigning to type \'char[]\' from type \'char[4]\'"' . PHP_EOL;
Resulted in this output:
Creating FFI struct...
Our struct is:
object(FFI\CData:struct <anonymous>)#1 (2) {
["length"]=>
int(0)
["data"]=>
object(FFI\CData:char[])#2 (0) {
}
}
Our struct->data is:
object(FFI\CData:char[])#2 (0) {
}
Please keep in memory following will not work:
- Incompatible types when assigning to type 'char[]' from type 'char[4]'
Let's try something dirty:
string(1) "▒"
string(1) "▒"
And even more dirtier:
object(FFI\CData:struct <anonymous>)#1 (2) {
["length"]=>
int(0)
["data"]=>
object(FFI\CData:char[])#2 (0) {
}
}
string(1) "a"
I think I could broke something.
Let's fill our struct with value:
object(FFI\CData:struct <anonymous>)#1 (2) {
["length"]=>
int(5)
["data"]=>
object(FFI\CData:char[])#2 (0) {
}
}
Will it work for array member?
- Attempt to write over data boundary
Seems like it won't.
Maybe I can assign data directly to array member?
- Attempt to write over data boundary
Doesn't work either.
Or maybe I can assign to array member itself?
- Attempt to write over data boundary
Do you remember last time we did this we got different error, it was:
- Incompatible types when assigning to type 'char[]' from type 'char[4]'
I did not expect something different, but it seems strange to me - flexible array members in structs are allowed, but I can't find the way how to use them.
PHP Version
PHP 8.1.1 (cli) NTS
Operating System
No response