-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Fix GH-13970: Incorrect validation of #[\Attribute]’s first parameter #13976
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
In c1959e6 code was added to deal with preloading of enums, which had to be special cased because they are object instances. In 4397811 this code was changed because array instances can contain object instances due to enums. In that commit, the code started using zval_update_constant_ex() and stopped ZEND_AST_CONST_ENUM_INIT resolution when in compilation. Since the attribute in the testcase is resolved during compilation, the resolution fails as well, even though in this case we can resolve it fine as the problem is only with constants during preloading. This patch restores the original code but changes the IS_OBJECT condition to Z_COLLECTABLE such that both arrays and objects that are resolved from IS_CONSTANT_AST are not persisted to shm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The patch looks wrong to me (but I may be wrong as well).
@iluuu1994 please take a look
@@ -769,12 +769,6 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *as | |||
break; | |||
case ZEND_AST_CONST_ENUM_INIT: | |||
{ | |||
// Preloading will attempt to resolve constants but objects can't be stored in shm | |||
// Aborting here to store the const AST instead | |||
if (CG(in_compilation)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May this should be replaced by if (CG(compiler_options) & ZEND_COMPILE_PRELOAD) {
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replacing this with CG(in_compilation) && (CG(compiler_options) & ZEND_COMPILE_PRELOAD)
fixes the issue when not in preloading, but the issue still remains when in preloading.
{ | ||
zval tmp; | ||
ZVAL_COPY(&tmp, val); | ||
if (zval_update_constant_ex(&tmp, scope) == FAILURE || Z_COLLECTABLE(tmp)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why all COLLECTABLE
values can't be resolved.
This disables resolution of all constants which values are arrays.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too conservative maybe yes, an alternative is looping (recursively) over the array and checking if they contain objects.
I believe the root cause is that attributes call Line 6762 in c3acfb1
But also allow skipping validation when arguments cannot be resolved: php-src/Zend/zend_attributes.c Lines 43 to 48 in c3acfb1
To solve this properly, we either need to:
Otherwise, we may get unexpected non-int values in php-src/ext/reflection/php_reflection.c Lines 6747 to 6751 in c3acfb1
|
Your analysis is right, but I don't fully agree on the solution. |
In this case that's true. But we can't always fully resolve the constant AST (e.g. when preloading, or compiling with opcache). In that case, we'll still run into the problem of either having to delay resolution of the constant AST until runtime, or erroring early. It seems the So, I agree that we may allow resolution of the AST immediately when opcache is not enabled, but that would just be an enhancement, rather than a standalone solution for this issue. Maybe I'm missing something. |
I don't see why we can't resolve it in opcache or during preloading. It's not like we're storing the result. Could be just me. |
In c1959e6 code was added to deal with preloading of enums, which had to be special cased because they are object instances. In 4397811 this code was changed because array instances can contain object instances due to enums. In that commit, the code started using zval_update_constant_ex() and stopped ZEND_AST_CONST_ENUM_INIT resolution when in compilation.
Since the attribute in the testcase is resolved during compilation, the resolution fails as well, even though in this case we can resolve it fine as the problem is only with persisting constants during preloading.
This patch restores the original code but changes the IS_OBJECT condition to Z_COLLECTABLE such that both arrays and objects that are resolved from IS_CONSTANT_AST are not persisted to shm.
I don't know for sure if this is the best approach. An alternative I thought of is looping through the array to see if it contains objects but that seems more complicated and I'm not sure that's better.