mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fix FFI Parsing of Pointer Declaration Lists (#17794)
* Fix ffi parsing of pointer declaration lists * Fix ffi pointer declaration lists grammar
This commit is contained in:
parent
765cebf73a
commit
52c91f0fb7
3 changed files with 39 additions and 2 deletions
|
@ -264,12 +264,14 @@ struct_contents(zend_ffi_dcl *dcl):
|
||||||
|
|
||||||
struct_declaration(zend_ffi_dcl *struct_dcl):
|
struct_declaration(zend_ffi_dcl *struct_dcl):
|
||||||
{zend_ffi_dcl common_field_dcl = ZEND_FFI_ATTR_INIT;}
|
{zend_ffi_dcl common_field_dcl = ZEND_FFI_ATTR_INIT;}
|
||||||
|
{zend_ffi_dcl base_field_dcl = ZEND_FFI_ATTR_INIT;}
|
||||||
specifier_qualifier_list(&common_field_dcl)
|
specifier_qualifier_list(&common_field_dcl)
|
||||||
|
{base_field_dcl = common_field_dcl;}
|
||||||
( /* empty */
|
( /* empty */
|
||||||
{zend_ffi_add_anonymous_field(struct_dcl, &common_field_dcl);}
|
{zend_ffi_add_anonymous_field(struct_dcl, &common_field_dcl);}
|
||||||
| struct_declarator(struct_dcl, &common_field_dcl)
|
| struct_declarator(struct_dcl, &common_field_dcl)
|
||||||
( ","
|
( ","
|
||||||
{zend_ffi_dcl field_dcl = common_field_dcl;}
|
{zend_ffi_dcl field_dcl = base_field_dcl;}
|
||||||
attributes(&field_dcl)?
|
attributes(&field_dcl)?
|
||||||
struct_declarator(struct_dcl, &field_dcl)
|
struct_declarator(struct_dcl, &field_dcl)
|
||||||
)*
|
)*
|
||||||
|
|
|
@ -2472,14 +2472,16 @@ _yy_state_2:
|
||||||
|
|
||||||
static int parse_struct_declaration(int sym, zend_ffi_dcl *struct_dcl) {
|
static int parse_struct_declaration(int sym, zend_ffi_dcl *struct_dcl) {
|
||||||
zend_ffi_dcl common_field_dcl = ZEND_FFI_ATTR_INIT;
|
zend_ffi_dcl common_field_dcl = ZEND_FFI_ATTR_INIT;
|
||||||
|
zend_ffi_dcl base_field_dcl = ZEND_FFI_ATTR_INIT;
|
||||||
sym = parse_specifier_qualifier_list(sym, &common_field_dcl);
|
sym = parse_specifier_qualifier_list(sym, &common_field_dcl);
|
||||||
|
base_field_dcl = common_field_dcl;
|
||||||
if (sym == YY__SEMICOLON || sym == YY__RBRACE) {
|
if (sym == YY__SEMICOLON || sym == YY__RBRACE) {
|
||||||
zend_ffi_add_anonymous_field(struct_dcl, &common_field_dcl);
|
zend_ffi_add_anonymous_field(struct_dcl, &common_field_dcl);
|
||||||
} else if (sym == YY__STAR || sym == YY_ID || sym == YY__LPAREN || sym == YY__COLON) {
|
} else if (sym == YY__STAR || sym == YY_ID || sym == YY__LPAREN || sym == YY__COLON) {
|
||||||
sym = parse_struct_declarator(sym, struct_dcl, &common_field_dcl);
|
sym = parse_struct_declarator(sym, struct_dcl, &common_field_dcl);
|
||||||
while (sym == YY__COMMA) {
|
while (sym == YY__COMMA) {
|
||||||
sym = get_sym();
|
sym = get_sym();
|
||||||
zend_ffi_dcl field_dcl = common_field_dcl;
|
zend_ffi_dcl field_dcl = base_field_dcl;
|
||||||
if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
|
if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) {
|
||||||
sym = parse_attributes(sym, &field_dcl);
|
sym = parse_attributes(sym, &field_dcl);
|
||||||
}
|
}
|
||||||
|
|
33
ext/ffi/tests/ptr_declaration_list.phpt
Normal file
33
ext/ffi/tests/ptr_declaration_list.phpt
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
--TEST--
|
||||||
|
Declaration Lists with Pointers
|
||||||
|
--EXTENSIONS--
|
||||||
|
ffi
|
||||||
|
--SKIPIF--
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$ffi = FFI::cdef(<<<EOF
|
||||||
|
struct MyStruct {
|
||||||
|
uint8_t** a, *b, c;
|
||||||
|
};
|
||||||
|
EOF);
|
||||||
|
|
||||||
|
$test_struct = $ffi->new('struct MyStruct');
|
||||||
|
$one = $ffi->new("uint8_t");
|
||||||
|
$oneptr = $ffi->new("uint8_t*");
|
||||||
|
$oneptrptr = $ffi->new("uint8_t**");
|
||||||
|
$one->cdata = 1;
|
||||||
|
$oneptr = FFI::addr($one);
|
||||||
|
$oneptrptr = FFI::addr($oneptr);
|
||||||
|
|
||||||
|
$test_struct->a = $oneptrptr;
|
||||||
|
$test_struct->b = $oneptr;
|
||||||
|
$test_struct->c = $one;
|
||||||
|
|
||||||
|
var_dump($test_struct->a[0][0]);
|
||||||
|
var_dump($test_struct->b[0]);
|
||||||
|
var_dump($test_struct->c);
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
int(1)
|
||||||
|
int(1)
|
||||||
|
int(1)
|
Loading…
Add table
Add a link
Reference in a new issue