Replace zend_object object with its header to prevent the "using flexible array in the middle of another struct" problem in its inheritted classes (static analyzer report)
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 40.4k
- Forks
- 8.1k
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 96
Description
Class zend_object is defined as a flexible array of length 1. The flexible array defined with size 1 and 0 is not the standard behavior. It is suggested to use the unsized definition (https://people.kernel.org/kees/bounded-flexible-arrays-in-c). Besides, not all its subclasses will use the array field properties_table of the zend_object class. If I understand the code correctly, when the properties_table[0] field is not used, it will store a ZVAL_UNDEF zval indicating the end of the iteration. Whereas when the properties_table[0] field is used, the flags and array length are checked first before accessing the data in the array.
If the properties_table[0] field is not used in these sub-classes, will it be better to replace the zend_object in these classes with only the header part of zend_object?
i.e. (as suggested in case 2 of https://lpc.events/event/18/contributions/1722/attachments/1591/3303/Wfamnae_lpceu2024.pdf)
We can define another struct with only the header part (let's name it zend_object_header_part), but leave the zend_object struct with both the header and the flexible array part.
When only the header is needed, we can use the zend_object_header_part (e.g. in the class inheritance), whereas for those requiring the array part, or using the object through a zend_object pointer, we can still use the full definition.
Usages of zend_object in the middle of other structs whose array field is potentially never used through the composite struct:
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/Zend/zend_generators.h#L58-L59
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/Zend/zend_interfaces.c#L490-L491
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/Zend/zend_closures.c#L31-L32
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/Zend/zend_fibers.h#L102-L104
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/Zend/zend_iterators.h#L64-L65
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/opcache/jit/zend_jit_ir.c#L8451-L8452
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/com_dotnet/com_saproxy.c#L35-L36
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/com_dotnet/php_com_dotnet_internal.h#L28-L29
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/com_dotnet/com_persist.c#L278-L279
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/ffi/ffi.c#L169-L170
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/ffi/ffi.c#L191-L192
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/ffi/ffi.c#L199-L200
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/pdo/php_pdo_driver.h#L645-L646
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/zend_test/fiber.h#L24-L25
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/intl/normalizer/normalizer_class.h#L25-L26
- https://github.com/php/php-src/blob/c2fddac8ca2c13b53dfe1044e9355355ae602e30/ext/intl/locale/locale_class.h#L25-L26
report ids: 250106-1639:1-6,8-17 (16 reports in total)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the zend_object definition and compare the checked usages in Zend/zend_generators.h and ext/pdo/php_pdo_driver.h with the unchecked composite structs listed in Zend and ext/. Determine which classes need properties_table, then preserve the full object where required and use a header-only representation elsewhere. Completion means addressing the listed static-analyzer reports without changing behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, php
- Domain
- compilers
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100