From 2dca358e999c4255a8b3432b520d2316783f5621 Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Wed, 10 Apr 2019 12:50:17 +1000 Subject: [PATCH] Fix notices emitted from DateFormatter Some languages have date abbreviations that contain ".", which allows the non-ISO regexes to match an input string containing an invalid month name. Use preg_quote() to avoid this. Also fix the error handling case of makeIsoMonth(). If the input date is invalid, don't try to wrap it in a date span, since that's semantically incorrect and may also access unset members of $bits, causing a notice. Bug: T220563 Change-Id: Ib2b3fb315dc93b60de595d3c445637f6bcc78a1a --- includes/parser/DateFormatter.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/includes/parser/DateFormatter.php b/includes/parser/DateFormatter.php index fb79442e68..c9bbc43a98 100644 --- a/includes/parser/DateFormatter.php +++ b/includes/parser/DateFormatter.php @@ -258,7 +258,7 @@ class DateFormatter { if ( !isset( $bits['m'] ) ) { $m = $this->makeIsoMonth( $bits['F'] ); - if ( !$m || $m == '00' ) { + if ( $m === false ) { $fail = true; } else { $bits['m'] = $m; @@ -311,7 +311,7 @@ class DateFormatter { if ( $fail ) { // This occurs when parsing a date with day or month outside the bounds // of possibilities. - $text = $orig; + return $orig; } $isoBits = []; @@ -336,8 +336,8 @@ class DateFormatter { private function getMonthRegex() { $names = []; for ( $i = 1; $i <= 12; $i++ ) { - $names[] = $this->lang->getMonthName( $i ); - $names[] = $this->lang->getMonthAbbreviation( $i ); + $names[] = preg_quote( $this->lang->getMonthName( $i ), '/' ); + $names[] = preg_quote( $this->lang->getMonthAbbreviation( $i ), '/' ); } return implode( '|', $names ); } @@ -345,11 +345,14 @@ class DateFormatter { /** * Makes an ISO month, e.g. 02, from a month name * @param string $monthName Month name - * @return string ISO month name + * @return string|false ISO month name, or false if the input was invalid */ private function makeIsoMonth( $monthName ) { - $n = $this->xMonths[$this->lang->lc( $monthName )]; - return sprintf( '%02d', $n ); + $isoMonth = $this->xMonths[$this->lang->lc( $monthName )] ?? false; + if ( $isoMonth === false ) { + return false; + } + return sprintf( '%02d', $isoMonth ); } /** -- 2.20.1