TTO has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/329039 )

Change subject: Proper handling of invalid/unknown time zones
......................................................................

Proper handling of invalid/unknown time zones

Currently, a user who has an invalid time zone stored in the database is
effectively locked out of their account on HHVM sites. This patch addresses
this by (1) preventing users from setting invalid time zones, and (2) not
throwing an unhandled exception if a user's TZ is unknown.

When the user saves their preferences, the code silently rewrites invalid
time zones to UTC. I think this is OK, since to cause this to happen you
have to manually muck around with the Preferences page DOM or submit the
form from a script.

Bug: T137182
Change-Id: I28c5e2ac9f2e681718c6080fb49b3b01e4af46dd
---
M includes/Preferences.php
M languages/Language.php
2 files changed, 37 insertions(+), 15 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/39/329039/1

diff --git a/includes/Preferences.php b/includes/Preferences.php
index cf8e7b8..a4aff99 100644
--- a/includes/Preferences.php
+++ b/includes/Preferences.php
@@ -696,18 +696,22 @@
                $tzOptions = self::getTimezoneOptions( $context );
 
                $tzSetting = $tzOffset;
+               if ( count( $tz ) > 1 && $tz[0] == 'ZoneInfo' &&
+                       !in_array( $tzOffset, HTMLFormField::flattenOptions( 
$tzOptions ) )
+               ) {
+                       // Timezone offset can vary with DST
+                       try {
+                               $userTZ = new DateTimeZone( $tz[2] );
+                               $minDiff = floor( timezone_offset_get( $userTZ, 
date_create( 'now' ) ) / 60 );
+                               $tzSetting = "ZoneInfo|$minDiff|{$tz[2]}";
+                       } catch ( Exception $e ) {
+                               // User has an invalid time zone set. Fall back 
to just using the offset
+                               $tz[0] = 'Offset';
+                       }
+               }
                if ( count( $tz ) > 1 && $tz[0] == 'Offset' ) {
                        $minDiff = $tz[1];
                        $tzSetting = sprintf( '%+03d:%02d', floor( $minDiff / 
60 ), abs( $minDiff ) % 60 );
-               } elseif ( count( $tz ) > 1 && $tz[0] == 'ZoneInfo' &&
-                       !in_array( $tzOffset, HTMLFormField::flattenOptions( 
$tzOptions ) )
-               ) {
-                       # Timezone offset can vary with DST
-                       $userTZ = timezone_open( $tz[2] );
-                       if ( $userTZ !== false ) {
-                               $minDiff = floor( timezone_offset_get( $userTZ, 
date_create( 'now' ) ) / 60 );
-                               $tzSetting = "ZoneInfo|$minDiff|{$tz[2]}";
-                       }
                }
 
                $defaultPreferences['timecorrection'] = [
@@ -1391,6 +1395,25 @@
                $data = explode( '|', $tz, 3 );
                switch ( $data[0] ) {
                        case 'ZoneInfo':
+                               $data = explode( '|', $tz, 3 );
+                               $valid = false;
+
+                               if ( count( $data ) === 3 ) {
+                                       // Make sure this timezone exists
+                                       try {
+                                               new DateTimeZone( $data[2] );
+                                               // If the constructor didn't 
throw, we know it's valid
+                                               $valid = true;
+                                       } catch ( Exception $e ) {
+                                               // Not a valid timezone
+                                       }
+                               }
+
+                               if ( !$valid ) {
+                                       // If the input is invalid, fall back 
to a safe default
+                                       return 'Offset|0';
+                               }
+                               return $tz;
                        case 'System':
                                return $tz;
                        default:
diff --git a/languages/Language.php b/languages/Language.php
index ac8d4cb..1afb6a7 100644
--- a/languages/Language.php
+++ b/languages/Language.php
@@ -2100,17 +2100,16 @@
                $data = explode( '|', $tz, 3 );
 
                if ( $data[0] == 'ZoneInfo' ) {
-                       MediaWiki\suppressWarnings();
-                       $userTZ = timezone_open( $data[2] );
-                       MediaWiki\restoreWarnings();
-                       if ( $userTZ !== false ) {
+                       try {
+                               $userTZ = new DateTimeZone( $data[2] );
                                $date = date_create( $ts, timezone_open( 'UTC' 
) );
                                date_timezone_set( $date, $userTZ );
                                $date = date_format( $date, 'YmdHis' );
                                return $date;
+                       } catch ( Exception $e ) {
+                               // Unrecognized timezone, default to 'Offset' 
with the stored offset.
+                               $data[0] = 'Offset';
                        }
-                       # Unrecognized timezone, default to 'Offset' with the 
stored offset.
-                       $data[0] = 'Offset';
                }
 
                if ( $data[0] == 'System' || $tz == '' ) {

-- 
To view, visit https://gerrit.wikimedia.org/r/329039
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I28c5e2ac9f2e681718c6080fb49b3b01e4af46dd
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: TTO <at.li...@live.com.au>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to