Skip to content

Use common function for TypeError on illegal offset access #10544

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

Merged
merged 6 commits into from
Jun 6, 2023

Conversation

Girgias
Copy link
Member

@Girgias Girgias commented Feb 8, 2023

Follow-up on #10504

This also fixes some consistency issues

Currently, using CI to check the JIT changes are correct as I am getting weird errors (possibly due to ASAN/UBSAN)

@Girgias
Copy link
Member Author

Girgias commented Feb 8, 2023

Would like to get opinions on the approach of using the BP_VAR_* constants.

Also, I've just used BP_VAR_R to get the default message, but my usages are probably wrong.

Opinions @arnaud-lb, @iluuu1994, @derickr ?

Copy link
Member

@iluuu1994 iluuu1994 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm always in favor of improving error messages. It seems like this will be somewhat inconsistent though as some of these functions aren't aware of the BP and can be used for any of them, but propagating it just for the error message doesn't seem worth it.

@Girgias Girgias force-pushed the offset-common-error-func branch from f0d0e33 to 93e78d4 Compare February 9, 2023 15:16
@@ -6,7 +6,7 @@ Bug #24773 (unset() of integers treated as arrays causes a crash)
unset($array["lvl1"]["lvl2"]["b"]);
?>
--EXPECTF--
Fatal error: Uncaught TypeError: Cannot access offset of type string on string in %s:%d
Fatal error: Uncaught TypeError: Cannot access offset of type string in unset in %s:%d
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this case shows we probably should improve the message somewhat. As this is inconsistent with trying to unset the offset of a string (which is banned in general). Maybe strings do need to be seperate :/

@Girgias Girgias force-pushed the offset-common-error-func branch from 93e78d4 to 1d35b17 Compare May 31, 2023 15:11
@Girgias Girgias requested review from dstogov and bukka as code owners May 31, 2023 15:11
@Girgias Girgias requested a review from iluuu1994 May 31, 2023 15:17
Copy link
Member

@iluuu1994 iluuu1994 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't go through all the changes this time because it doesn't seem the BPs have changed.

@@ -333,7 +333,8 @@ static zend_long spl_offset_convert_to_long(zval *offset) /* {{{ */
return Z_RES_HANDLE_P(offset);
}

zend_illegal_container_offset("SplFixedArray", offset, BP_VAR_R);
/* Use SplFixedArray name from the CE */
zend_illegal_container_offset(spl_ce_SplFixedArray->name, offset, BP_VAR_R);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be fully correct this would need to get the class name passed from the caller.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, but that requires some more intrusive changes, which I want to do as a follow-up. As I first notices this being an issue with the ArrayObject case. But I think in both cases some places have hard coded the value of the class name.

@@ -1651,7 +1631,7 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type
}
return offset;
}
zend_illegal_string_offset(dim);
zend_illegal_container_offset(ZSTR_KNOWN(ZEND_STR_STRING), dim, type);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You replace the calls to specialized functions with the calls to a single universal one. This requires sending more arguments and therefore will increases the VM code size.

Copy link
Member

@arnaud-lb arnaud-lb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me appart from other comments

@@ -11,4 +11,4 @@ try {

?>
--EXPECT--
Cannot access offset of type object on array
Cannot access offset of type Closure on array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only a question, not a suggestion: What do you think of also specifying what is allowed? Array offset must be int or string, cannot access offset of type Closure

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can only really do this for arrays and strings :/ as objects that implement ArrayOffset can in theory support any type

Copy link
Member

@dstogov dstogov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to split ``zend_illegal_container_offset() back to cheaper specialized functions at least for the VM handlers.

Girgias added 3 commits June 5, 2023 15:14
This merges all usages of emiting an offset TypeError into a new ZEND_API function
zend_illegal_container_offset(const char* container, const zval *offset, int type);

Where the container should represent the type on which the access is attempted (e.g. string, array)
The offset zval that is used, where the error message will display its type
The type of access, which should be a BP_VAR_* constant, to get special message for isset/empty/unset
@Girgias Girgias force-pushed the offset-common-error-func branch from 1d35b17 to 381e865 Compare June 5, 2023 14:37
@Girgias
Copy link
Member Author

Girgias commented Jun 5, 2023

I suggest to split ``zend_illegal_container_offset() back to cheaper specialized functions at least for the VM handlers.

I hope what I've done is what you asked, should I do the same for the JIT VM handlers?

@Girgias Girgias force-pushed the offset-common-error-func branch from 381e865 to c41efe0 Compare June 5, 2023 15:34
Copy link
Member

@dstogov dstogov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this state, the patch shouldn't make any harm, but I also don't see any benefits.
I'm indifferent.

@Girgias Girgias merged commit 99fa740 into php:master Jun 6, 2023
@Girgias Girgias deleted the offset-common-error-func branch June 6, 2023 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants