-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fixed bug #73239 (DateTime shows strange error message with invalid timezone) #8594
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
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.
Thank you! Generally good, but I'm not sure whether we should fix that long standing behavior in a revision.
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.
ext/date/tests/bug73239.phpt
Outdated
?> | ||
--EXPECTF-- | ||
Warning: ini_set(): Invalid date.timezone value 'dummy' in %sbug73239.php on line %d | ||
DateTime::__construct(): Invalid date.timezone value 'dummy', we selected the timezone 'UTC' for now. |
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 think you might have mixed things up? The "we selected the timezone 'UTC' for now" should be on the ini_set() error message (where it makes sense) and not the DateTime::__construct() message (where it doesn't, because of the exception).
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, as is, removes both "we selected the timezone 'UTC' for now" messages; only that test expection isn't in line with that. I agree though, that the message raised from PHP_INI_MH(OnUpdate_date_timezone)
might better stay as is (well, not really the wording; I'd go with passive voice instead).
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.
No, I did not mix this up. The ini_set()
warning is correct. At that state, PHP never fell back to UTC
, it just shown the warning to hint that you messed up.
The warning for DateTime was correct as in the test, the code is wrong. It should very much tell you there that there was an actual fallback to UTC
. And I have updated the wording.
I don't want to change the behaviour here.
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.
Well, but throwing an exception with the message "DateTime::__construct(): UTC was used as timezone, because the date.timezone value 'dummy' is invalid" doesn't make sense. If UTC was used, there is no reason to throw an exception. And when an exception is thrown, that UTC is irrelevant. Or do I miss something?
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.
Oh yes, of course. That's why I originally had removed that part of the sentence. I'll fix that back then. Need more 🍵 .
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.
It isn't actually that simple. The location where this warning message is thrown, is in guess_timezone
:
if (!timelib_timezone_id_is_valid(DATEG(default_timezone), tzdb)) {
php_error_docref(NULL, E_WARNING, "UTC was used as timezone, because the date.timezone value '%s' is invalid", DATEG(default_timezone));
return "UTC";
}
Where the warning is correct. This same guess_timezone
function is also called in date_initialize
(via get_timezone_info()
). get_timezone_info()
is used plenty of times, where the warning message should be shown.
However, get_timezone_info()
is also called as part of the DateTime
constructor, where then the exception message is indeed silly, although it should refuse to construct the DateTime
object as it currently does. Instead the exception ought to say the same as the warning from ini_set()
. However, having a flag on the function to switch between two error messages is perhaps silly too, so I don't have a real good answer here.
I think what we should be doing here is to fail the ini update if the timezone is invalid (i.e. keep the previous valid value). This way we cannot hit this error condition in guess_timezone at all and the problem is nicely resolved. |
OK, with this latest commit, the warning now only shows up when setting a wrong timezone through |
f7cee44
to
438c798
Compare
ext/date/php_date.c
Outdated
@@ -497,21 +497,19 @@ timelib_tzinfo *php_date_parse_tzfile_wrapper(const char *formal_tzname, const t | |||
/* {{{ static PHP_INI_MH(OnUpdate_date_timezone) */ | |||
static PHP_INI_MH(OnUpdate_date_timezone) | |||
{ | |||
if (OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage) == FAILURE) { | |||
DATEG(timezone_valid) = 0; |
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 think this assignment is needed anymore?
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.
And possibly the entire timezone_valid flag?
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.
Perhaps not, but I didn't want to risk just removing it in case there is a weird edge case that I didn't think of, and it is used in other places.
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 far as I can tell this is the one place that would assign zero to it, others assign 1 or check for 1. We should probably retarget this change to master though, as there's some minor changes in behavior (as seen in tests).
if (OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage) == FAILURE) { | ||
return FAILURE; | ||
} | ||
|
||
return SUCCESS; |
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.
if (OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage) == FAILURE) { | |
return FAILURE; | |
} | |
return SUCCESS; | |
return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); |
Maybe?
@nikic You OK with this now? |
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.
Yeah, looks good to me.
ext/date/php_date.c
Outdated
@@ -478,19 +477,13 @@ timelib_tzinfo *php_date_parse_tzfile_wrapper(const char *formal_tzname, const t | |||
/* {{{ static PHP_INI_MH(OnUpdate_date_timezone) */ | |||
static PHP_INI_MH(OnUpdate_date_timezone) | |||
{ | |||
if (OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage) == FAILURE) { | |||
if (new_value && ZSTR_VAL(new_value) && !timelib_timezone_id_is_valid(ZSTR_VAL(new_value), DATE_TIMEZONEDB)) { | |||
php_error_docref(NULL, E_WARNING, "Invalid date.timezone value '%s', using 'UTC' instead", ZSTR_VAL(new_value)); |
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.
Strictly speaking, this isn't using UTC
but whatever the old value is. Maybe we should print the old value instead?
No description provided.