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

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.
 
Top Bottom