-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Convert warnings to exceptions in standard lib (reopened) #5004
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
@@ -83,7 +83,7 @@ static zend_string* php_password_make_salt(size_t length) /* {{{ */ | |||
zend_string *ret, *buffer; | |||
|
|||
if (length > (INT_MAX / 3)) { | |||
php_error_docref(NULL, E_WARNING, "Length is too large to safely generate"); | |||
zend_value_error("Length is too large to safely generate"); |
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.
This commit can be dropped, password_* changes have landed separately.
@@ -1050,7 +1050,7 @@ static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, in | |||
|
|||
if (resource->path == NULL) { | |||
if (options & REPORT_ERRORS) { | |||
php_error_docref(NULL, E_WARNING, "Invalid path provided in %s", url); | |||
zend_value_error("Invalid path provided in %s", url); |
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.
As a general rule of thumb, I don't think we should be throwing from inside stream wrapper operations. Beyond "filename cannot contain null bytes" I think we should stick with existing warnings where file-system operations are concerned.
@@ -219,7 +219,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa | |||
|
|||
if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) { | |||
if (options & REPORT_ERRORS) { | |||
php_error_docref(NULL, E_WARNING, "URL file-access is disabled in the server configuration"); | |||
zend_throw_error(NULL, "URL file-access is disabled in the server configuration"); |
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.
Same here. This seems like a clear "environment configuration" case that code may need to deal with.
php_error_docref(NULL, E_WARNING, "Filename cannot be empty!"); | ||
RETURN_FALSE; | ||
zend_value_error("Filename cannot be empty!"); | ||
return; |
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.
@cmb69 What do you think about moving this check into Z_PARAM_PATH? It seems to be a pretty common check (and it's also checked in php_stream_open_wrapper), but we probably don't check it everywhere we should be checking it. That would make sure it's treated consistently.
(Conversely: Are there any cases where an empty path should be accepted?)
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.
There are at least some cases where an empty path should be accepted, e.g. for SQLite3::open() (where an empty path is supposed to create a temporary on-disk database). Generally, I think that empty paths should be forbidden right away nonetheless. Maybe change Z_PARAM_PATH to reject empty paths, and cater to the few exceptions by checking for a string and adding a manual NUL byte check? Or maybe introduce another macro (say, Z_PARAM_PATH_MAYBE_EMPTY)? The latter won't work with classic ZPP, though (don't think that would a problem though).
php_error_docref(NULL, E_WARNING, "browscap ini directive not set"); | ||
RETURN_FALSE; | ||
zend_throw_error(NULL, "Browscap ini directive not set"); | ||
return; |
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.
Imho this is again an environment issue: Code may have to deal with the fact that browscap is not available.
php_error_docref(NULL, E_WARNING, "Dynamically loaded extensions aren't enabled"); | ||
RETURN_FALSE; | ||
zend_throw_error(NULL, "Dynamically loaded extensions aren't enabled"); | ||
return; |
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.
Similar here, environment issue.
php_error_docref(NULL, E_WARNING, "Host cannot be empty"); | ||
RETURN_FALSE; | ||
zend_value_error("Host cannot be empty"); | ||
return; |
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.
This is fine :)
@@ -354,7 +354,7 @@ static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */ | |||
option = PHP_STREAM_META_GROUP_NAME; | |||
value = Z_STRVAL_P(group); | |||
} else { | |||
php_error_docref(NULL, E_WARNING, "parameter 2 should be string or int, %s given", zend_zval_type_name(group)); | |||
zend_type_error("Parameter 2 should be string or int, %s given", zend_zval_type_name(group)); |
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.
This is fine, but RETURN_FALSE should be changed to return.
@@ -123,7 +123,7 @@ PHP_FUNCTION(levenshtein) | |||
} | |||
|
|||
if (distance < 0 && /* TODO */ ZEND_NUM_ARGS() != 3) { | |||
php_error_docref(NULL, E_WARNING, "Argument string(s) too long"); | |||
zend_value_error("Argument string(s) too long"); |
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.
Code may want to handle this condition, as I don't think the limit is exposed (and it's a low limit -- this is not a 2G string condition).
goto exit_fail; | ||
} | ||
if (Z_TYPE_P(ztarget) != IS_LONG) { | ||
php_error_docref(NULL, E_WARNING, "Redirection target must be an integer"); | ||
zend_value_error("Redirection target must be an integer"); |
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.
These should all be fine.
php_error_docref(NULL, E_WARNING, "Offset not contained in string"); | ||
RETURN_FALSE; | ||
zend_value_error("Offset not contained in string"); | ||
return; |
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.
These are a bit borderline (I wouldn't be surprised if there is code ignoring this warning out there), but overall I think we should do this change.
php_error_docref(NULL, E_WARNING, "Offset not contained in string"); | ||
RETURN_FALSE; | ||
zend_value_error("Offset not contained in string"); | ||
return; | ||
} | ||
p = ZSTR_VAL(haystack) + (size_t)offset; | ||
e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack); | ||
} else { | ||
if (offset < -INT_MAX || (size_t)(-offset) > ZSTR_LEN(haystack)) { |
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.
These INT_MAX should be ZEND_LONG_MAX.
Thanks for the thorough review! Let me sum it up:
Conclusion: I shouldn't create such a big PR with many promotions next time.. :) Can I go ahead and commit the promotions in the first category (after addressing the comment about |
Yeah. I'd also suggest to handle |
@nikic Ah, I made a mistake and also committed the |
@kocsismate It's okay. |
For these two, I think we shouldn't do the conversion, as the exception will only get thrown on the actual call, not when the function is registered. That means it's doing to be e.g. thrown when handling shutdown functions, which is not the best place to throw exceptions (in particular, it's going to skip all remaining shutdown functions).
I'm uncertain on that one... Generally, I think it would make sense to make constant() behaviorally consistent with a plain constant access. For that we should pass through the existing engine errors through, by removing the quiet flag, not changing the custom error.
Yeah. I think everything that should land here has landed (apart from constant maybe, which needs a different implementation), so I'll close this PR now. |
Cool, thanks for having a look! I also think that we are ok after learning about the facts you wrote. I'll maybe try to have a look at the constant stuff at a later time if I can do something about it. |
Reopening #4937 after it has been rebased to current master.