[php-src] Issue #7949: FFI struct with flexible array member

From: Date: Sat, 15 Jan 2022 21:55:21 +0000
Subject: [php-src] Issue #7949: FFI struct with flexible array member
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-239027@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/7949 Author: userqq ### Description The following code: ```php <?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_

« previous php.bugs (#239027) next »