Fixed verifyTimezone accepts timezones that will result in exceptions

PaulB

Well-known member
Affected version
2.2.12, PHP < 8.2.2
\XF\Entity\User::verifyTimezone uses the following logic in an attempt to filter out timezones that won't be accepted by DateTimeZone::__construct:

PHP:
$tzs = \DateTimeZone::listIdentifiers(\DateTimeZone::ALL_WITH_BC);
if (!in_array($timezone, $tzs))
{
	$this->error(\XF::phrase('please_select_valid_time_zone'), 'timezone');
	return false;
}

Unfortunately, \DateTimeZone::listIdentifiers can't be used to get a list of supported timezones. Without the ALL_WITH_BC flag, acceptable timezones are omitted. With the ALL_WITH_BC, some acceptable timezones are omitted, while others are returned that can't actually be parsed (https://github.com/php/php-src/issues/10218). This will (probably) be fixed in PHP 8.2.2, but support prior to that is inconsistent, even between PHP revisions: https://3v4l.org/HMcFD

A better approach would be to attempt to instantiate \DateTimeZone with the provided identifier. If it throws an exception, return false.
 
Patch attached. As usual, this is just intended as a reference; don't apply this to a production XenForo installation unless you're comfortable debugging PHP issues and can vet the quality of the patch.

This makes use of a static local variable to minimize the impact of the patch. Generally, this isn't a great practice, although it's harmless here. A proper patch should probably utilize a class property instead.

If you'd like to fix existing entries in your database, search for any timezones in xf_user that match Etc/GMT+%. You can fix these by inverting the sign and removing the Etc/ prefix. (The Etc/GMT[+-]# timezone format uses POSIX offsets, which are inverted from IANA conventions, hence the sign flip.) For example, Etc/GMT+3 becomes GMT-3. This still isn't guaranteed to be supported forever, but there aren't any known regressions that prevent the timezone from being parsed. I'm oversimplifying a great deal, and a robust fix should be able to check the validity of the resulting timezones and canonicalize them, but this should get you close enough.

As far as I know, vanilla XF has never allowed these Etc/GMT pseudo-timezones, but you might have them in your database if you've imported from other forums software or have expanded XenForo's timezone offerings.
 

Attachments

  • 2023-01-23-verifytimezone-paul.diff
    837 bytes · Views: 6
Thank you for reporting this issue, it has now been resolved. We are aiming to include any changes that have been made in a future XF release (2.2.13).

Change log:
Make user entity timezone verification more robust
There may be a delay before changes are rolled out to the XenForo Community.
 
Back
Top Bottom