From: Edward Chernenko Date: Sun, 1 Jul 2018 02:10:56 +0000 (+0300) Subject: Avoid arithmetics on localized number string ("0,04") in SpecialWatchlist X-Git-Tag: 1.34.0-rc.0~4837^2 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=6b240c699eb1e965dad3c51107566f1f27ed1887 Avoid arithmetics on localized number string ("0,04") in SpecialWatchlist In SpecialWatchlist::cutoffselector(), values like 1/24 or 6/24 are cast to string via strval(). However, in some locales (e.g. ru_RU.utf8) strval will return a localized form of the number, e.g. "0,04" instead of "0.04". This "0,04" is then used in arithmetic operations, where it's treated as 0, resulting in "0 hours" being shown instead of "1 hour", "2 hours", etc. Bug: T198501 Change-Id: Iaa4e6170b30a7bb9ce0f22d9d2cc4772b0faa3b8 --- diff --git a/includes/specials/SpecialWatchlist.php b/includes/specials/SpecialWatchlist.php index f716e920f0..41a059fba4 100644 --- a/includes/specials/SpecialWatchlist.php +++ b/includes/specials/SpecialWatchlist.php @@ -756,45 +756,36 @@ class SpecialWatchlist extends ChangesListSpecialPage { } function cutoffselector( $options ) { - // Cast everything to strings immediately, so that we know all of the values have the same - // precision, and can be compared with '==='. 2/24 has a few more decimal places than its - // default string representation, for example, and would confuse comparisons. - - // Misleadingly, the 'days' option supports hours too. - $days = array_map( 'strval', [ 1 / 24, 2 / 24, 6 / 24, 12 / 24, 1, 3, 7 ] ); - - $userWatchlistOption = (string)$this->getUser()->getOption( 'watchlistdays' ); - // add the user preference, if it isn't available already - if ( !in_array( $userWatchlistOption, $days ) && $userWatchlistOption !== '0' ) { - $days[] = $userWatchlistOption; - } - - $maxDays = (string)$this->maxDays; - // add the maximum possible value, if it isn't available already - if ( !in_array( $maxDays, $days ) ) { - $days[] = $maxDays; - } - - $selected = (string)$options['days']; + $selected = (float)$options['days']; if ( $selected <= 0 ) { - $selected = $maxDays; - } - - // add the currently selected value, if it isn't available already - if ( !in_array( $selected, $days ) ) { - $days[] = $selected; - } + $selected = $this->maxDays; + } + + $selectedHours = round( $selected * 24 ); + + $hours = array_unique( array_filter( [ + 1, + 2, + 6, + 12, + 24, + 72, + 168, + 24 * (float)$this->getUser()->getOption( 'watchlistdays', 0 ), + 24 * $this->maxDays, + $selectedHours + ] ) ); + asort( $hours ); - $select = new XmlSelect( 'days', 'days', $selected ); + $select = new XmlSelect( 'days', 'days', $selectedHours / 24 ); - asort( $days ); - foreach ( $days as $value ) { - if ( $value < 1 ) { - $name = $this->msg( 'hours' )->numParams( $value * 24 )->text(); + foreach ( $hours as $value ) { + if ( $value < 24 ) { + $name = $this->msg( 'hours' )->numParams( $value )->text(); } else { - $name = $this->msg( 'days' )->numParams( $value )->text(); + $name = $this->msg( 'days' )->numParams( $value / 24 )->text(); } - $select->addOption( $name, $value ); + $select->addOption( $name, $value / 24 ); } return $select->getHTML() . "\n
\n";