aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Vorwerk <zabe@avorwerk.net>2022-09-19 17:51:15 +0200
committerJforrester <jforrester@wikimedia.org>2022-09-29 14:40:13 +0000
commit872970a21ccdb7e9deb1f88311d9e58d6e87458b (patch)
tree4ddda58a354991ba4834ce890c5768debd3a48cd
parentdeaa06a21d866c23b622f76eea17d083e3799167 (diff)
downloadmediawikicore-872970a21ccdb7e9deb1f88311d9e58d6e87458b.tar.gz
mediawikicore-872970a21ccdb7e9deb1f88311d9e58d6e87458b.zip
Drop some pre-7.4 php compat code
Change-Id: Ie92e4b2722692c64f38557bfcd3687168d245e8e (cherry picked from commit eec198b245901d9a5dbe52a426e909ffbff32ac0)
-rw-r--r--includes/WebResponse.php5
-rw-r--r--includes/language/Message.php23
-rw-r--r--includes/libs/http/SetCookieCompat.php234
-rw-r--r--tests/phpunit/unit/includes/libs/http/SetCookieCompatTest.php277
4 files changed, 3 insertions, 536 deletions
diff --git a/includes/WebResponse.php b/includes/WebResponse.php
index c046c95122c8..67f4ca2ebf38 100644
--- a/includes/WebResponse.php
+++ b/includes/WebResponse.php
@@ -22,7 +22,6 @@
use MediaWiki\MainConfigNames;
use MediaWiki\MediaWikiServices;
-use Wikimedia\Http\SetCookieCompat;
/**
* Allow programs to request this object from WebRequest::response()
@@ -242,9 +241,9 @@ class WebResponse {
wfDebugLog( 'cookie', $logDesc );
if ( $func === 'setrawcookie' ) {
- SetCookieCompat::setrawcookie( $prefixedName, $value, $setOptions );
+ setrawcookie( $prefixedName, $value, $setOptions );
} else {
- SetCookieCompat::setcookie( $prefixedName, $value, $setOptions );
+ setcookie( $prefixedName, $value, $setOptions );
}
self::$setCookies[$key] = $deleting ? null : $optionsForDeduplication;
}
diff --git a/includes/language/Message.php b/includes/language/Message.php
index 3f599f78b337..88c08457d464 100644
--- a/includes/language/Message.php
+++ b/includes/language/Message.php
@@ -25,7 +25,6 @@ use MediaWiki\MediaWikiServices;
use MediaWiki\Message\UserGroupMembershipParam;
use MediaWiki\Page\PageReference;
use MediaWiki\Page\PageReferenceValue;
-use Wikimedia\RequestTimeout\TimeoutException;
/**
* The Message class deals with fetching and processing of interface message
@@ -1029,27 +1028,7 @@ class Message implements MessageSpecifier, Serializable {
* @return string
*/
public function __toString() {
- // PHP before 7.4.0 doesn't allow __toString to throw exceptions and will
- // trigger a fatal error if it does. So, catch any exceptions.
- if ( version_compare( PHP_VERSION, '7.4.0', '<' ) ) {
- try {
- return $this->format( self::FORMAT_PARSE );
- } catch ( TimeoutException $e ) {
- // Fatal is OK in this case
- throw $e;
- } catch ( Exception $ex ) {
- try {
- trigger_error( "Exception caught in " . __METHOD__ . " (message " . $this->key . "): "
- . $ex, E_USER_WARNING );
- } catch ( Exception $ex ) {
- // Doh! Cause a fatal error after all?
- }
-
- return '⧼' . htmlspecialchars( $this->key ) . '⧽';
- }
- } else {
- return $this->format( self::FORMAT_PARSE );
- }
+ return $this->format( self::FORMAT_PARSE );
}
/**
diff --git a/includes/libs/http/SetCookieCompat.php b/includes/libs/http/SetCookieCompat.php
deleted file mode 100644
index 4f5a3fc5e98e..000000000000
--- a/includes/libs/http/SetCookieCompat.php
+++ /dev/null
@@ -1,234 +0,0 @@
-<?php
-
-namespace Wikimedia\Http;
-
-/**
- * @internal
- * @since 1.35
- */
-class SetCookieCompat {
- /**
- * Temporary emulation for setcookie() with a SameSite option and encoding
- * spaces in values as "%20" rather than "+".
- *
- * Prior to PHP 7.4.3, setcookie() encoded spaces in cookie values as plus
- * signs. PHP 7.4.2 and later no longer decode plus signs as spaces, which
- * is a backward incompatible change that poses a problem when upgrading a
- * live site, especially if not all servers are to be upgraded at once.
- *
- * Once MediaWiki requires PHP 7.4.3, this can be replaced with a setcookie()
- * call in the caller.
- *
- * @see https://phabricator.wikimedia.org/T291127
- * @see https://bugs.php.net/bug.php?id=79174
- * @param string $name The full cookie name
- * @param string $value The cookie value
- * @param array $options The options as passed to setcookie() in PHP 7.3+
- * @return bool
- */
- public static function setcookie( $name, $value, $options = [] ) {
- return ( new self )->setCookieInternal( true, $name, $value, $options );
- }
-
- /**
- * Temporary emulation for setrawcookie() with a SameSite option
- *
- * Once MediaWiki requires PHP 7.3, this can be replaced with a setrawcookie()
- * call in the caller.
- *
- * @param string $name The full cookie name
- * @param string $value The cookie value
- * @param array $options The options as passed to setrawcookie() in PHP 7.3+
- * @return bool
- */
- public static function setrawcookie( $name, $value, $options = [] ) {
- return ( new self )->setCookieInternal( false, $name, $value, $options );
- }
-
- /**
- * @internal
- * @param bool $urlEncode True for setcookie(), false for setrawcookie()
- * @param string $name The full cookie name
- * @param string $value The cookie value
- * @param array $options The options as passed to setcookie() in PHP 7.3+
- * @return bool
- */
- public function setCookieInternal( $urlEncode, $name, $value, $options = [] ) {
- $supportsAssoc = version_compare( PHP_VERSION, '7.3.0', '>=' );
- if ( $supportsAssoc ) {
- if ( $urlEncode && version_compare( PHP_VERSION, '7.4.3', '>=' ) ) {
- return setcookie( $name, $value, $options );
- } elseif ( $urlEncode ) {
- return setrawcookie( $name, rawurlencode( $value ), $options );
- } else {
- return setrawcookie( $name, $value, $options );
- }
- }
-
- if ( !isset( $options['samesite'] ) || !strlen( $options['samesite'] ) ) {
- return setrawcookie(
- $name,
- $urlEncode ? rawurlencode( $value ) : $value,
- $options['expires'],
- $options['path'],
- $options['domain'],
- $options['secure'],
- $options['httponly']
- );
- }
-
- return self::setCookieEmulated( $urlEncode, $name, $value, $options );
- }
-
- /**
- * Temporary emulation for setcookie() or setrawcookie() to match PHP 7.4.3
- *
- * This function corresponds to php_head_parse_cookie_options_array() and
- * php_setcookie() in the PHP source code:
- *
- * https://github.com/php/php-src/blob/PHP-7.4.3/ext/standard/head.c#L189-L226
- * https://github.com/php/php-src/blob/PHP-7.4.3/ext/standard/head.c#L79-L187
- *
- * @internal
- * @param bool $urlEncode True for setcookie(), false for setrawcookie()
- * @param string $name The full cookie name
- * @param string|null $value The cookie value
- * @param array $options The options as passed to setcookie() in PHP 7.3+
- * @return bool
- */
- public function setCookieEmulated( $urlEncode, $name, $value, $options = [] ) {
- $func = $urlEncode ? 'setcookie()' : 'setrawcookie()';
- $expires = 0;
- $path = null;
- $domain = null;
- $secure = false;
- $httponly = false;
- $samesite = null;
- $found = 0;
- foreach ( $options as $key => $opt ) {
- if ( $key === 'expires' ) {
- $expires = (int)$opt;
- $found++;
- } elseif ( $key === 'path' ) {
- $path = (string)$opt;
- $found++;
- } elseif ( $key === 'domain' ) {
- $domain = (string)$opt;
- $found++;
- } elseif ( $key === 'secure' ) {
- $secure = (bool)$opt;
- $found++;
- } elseif ( $key === 'httponly' ) {
- $httponly = (bool)$opt;
- $found++;
- } elseif ( $key === 'samesite' ) {
- $samesite = (string)$opt;
- $found++;
- } else {
- $this->error( "$func: Unrecognized key '$key' found in the options array" );
- }
- }
-
- if ( $found == 0 && count( $options ) > 0 ) {
- $this->error( "$func: No valid options were found in the given array" );
- }
-
- if ( !strlen( $name ) ) {
- $this->error( 'Cookie names must not be empty' );
- return false;
- } elseif ( strpbrk( $name, "=,; \t\r\n\013\014" ) !== false ) {
- $this->error( "Cookie names cannot contain any of the following " .
- "'=,; \\t\\r\\n\\013\\014'" );
- return false;
- }
-
- if ( !$urlEncode && $value !== null
- && strpbrk( $value, ",; \t\r\n\013\014" ) !== false
- ) {
- $this->error( "Cookie values cannot contain any of the following ',; \\t\\r\\n\\013\\014'" );
- return false;
- }
-
- if ( $path !== null && strpbrk( $path, ",; \t\r\n\013\014" ) !== false ) {
- $this->error( "Cookie paths cannot contain any of the following ',; \\t\\r\\n\\013\\014'" );
- return false;
- }
-
- if ( $domain !== null && strpbrk( $domain, ",; \t\r\n\013\014" ) !== false ) {
- $this->error( "Cookie domains cannot contain any of the following ',; \\t\\r\\n\\013\\014'" );
- return false;
- }
-
- $buf = '';
- if ( $value === null || strlen( $value ) === 0 ) {
- $dt = gmdate( "D, d-M-Y H:i:s T", 1 );
- $buf .= "Set-Cookie: $name=deleted; expires=$dt; Max-Age=0";
- } else {
- $buf .= "Set-Cookie: $name=";
- if ( $urlEncode ) {
- $buf .= rawurlencode( $value );
- } else {
- $buf .= $value;
- }
-
- if ( $expires > 0 ) {
- $dt = gmdate( "D, d-M-Y H:i:s T", $expires );
- $p = strrpos( $dt, '-' );
- if ( $p === false || substr( $dt, $p + 5, 1 ) !== ' ' ) {
- $this->error( "Expiry date cannot have a year greater than 9999" );
- return false;
- }
-
- $buf .= "; expires=$dt";
-
- $diff = $expires - $this->time();
- if ( $diff < 0 ) {
- $diff = 0;
- }
- $buf .= "; Max-Age=$diff";
- }
- }
-
- if ( $path !== null && strlen( $path ) ) {
- $buf .= "; path=$path";
- }
- if ( $domain !== null && strlen( $domain ) ) {
- $buf .= "; domain=$domain";
- }
- if ( $secure ) {
- $buf .= "; secure";
- }
- if ( $httponly ) {
- $buf .= "; HttpOnly";
- }
- if ( $samesite !== null && strlen( $samesite ) ) {
- $buf .= "; SameSite=$samesite";
- }
-
- // sapi_header_op() returns a value which setcookie() uses, but
- // header() discards it. The most likely way for sapi_header_op() to
- // fail is due to headers already being sent.
- if ( $this->headers_sent() ) {
- $this->error( "Cannot modify header information - headers already sent" );
- return false;
- }
- $this->header( $buf );
- return true;
- }
-
- protected function time() {
- return time();
- }
-
- protected function error( $message ) {
- trigger_error( $message, E_USER_WARNING );
- }
-
- protected function headers_sent() {
- return headers_sent();
- }
-
- protected function header( $header ) {
- header( $header, false );
- }
-}
diff --git a/tests/phpunit/unit/includes/libs/http/SetCookieCompatTest.php b/tests/phpunit/unit/includes/libs/http/SetCookieCompatTest.php
deleted file mode 100644
index 90d98a18feba..000000000000
--- a/tests/phpunit/unit/includes/libs/http/SetCookieCompatTest.php
+++ /dev/null
@@ -1,277 +0,0 @@
-<?php
-
-use PHPUnit\Framework\TestCase;
-use Wikimedia\Http\SetCookieCompat;
-
-/**
- * @covers \Wikimedia\Http\SetCookieCompat
- */
-class SetCookieCompatTest extends TestCase {
- use MediaWikiCoversValidator;
-
- public static function provideSetCookieEmulated() {
- // Expected values are all copied from PHP 7.4
- return [
- 'unrecognised key' => [
- true, 'a', '',
- [
- 'path' => '/',
- 'foo' => 'bar'
- ],
- [
- 'headers' => [
- 'Set-Cookie: a=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/',
- ],
- 'returnValue' => true,
- 'errors' => [
- 'setcookie(): Unrecognized key \'foo\' found in the options array',
- ],
- ],
- ],
- 'no valid options' => [
- true, 'a', '',
- [
- 'foo' => 'bar'
- ],
- [
- 'headers' => [
- 'Set-Cookie: a=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0',
- ],
- 'returnValue' => true,
- 'errors' => [
- 'setcookie(): Unrecognized key \'foo\' found in the options array',
- 'setcookie(): No valid options were found in the given array',
- ],
- ]
- ],
- 'empty name' => [
- true, '', '', [],
- [
- 'headers' => [],
- 'returnValue' => false,
- 'errors' => [
- 'Cookie names must not be empty',
- ],
- ],
- ],
- 'invalid name' => [
- true, "\n", '', [],
- [
- 'headers' => [],
- 'returnValue' => false,
- 'errors' => [
- 'Cookie names cannot contain any of the following \'=,; \\t\\r\\n\\013\\014\'',
- ],
- ]
- ],
- 'invalid value' => [
- false, 'a', "\n", [],
- [
- 'headers' => [],
- 'returnValue' => false,
- 'errors' => [
- 'Cookie values cannot contain any of the following \',; \\t\\r\\n\\013\\014\'',
- ],
- ]
- ],
- 'escaped invalid value' => [
- true, 'a', "\n", [],
- [
- 'headers' => [
- 'Set-Cookie: a=%0A',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'invalid path' => [
- true, 'a', 'b', [ 'path' => "\n" ],
- [
- 'headers' => [],
- 'returnValue' => false,
- 'errors' => [
- 'Cookie paths cannot contain any of the following \',; \\t\\r\\n\\013\\014\'',
- ],
- ]
- ],
- 'invalid domain' => [
- true, 'a', 'b', [ 'domain' => "\013" ],
- [
- 'headers' => [],
- 'returnValue' => false,
- 'errors' => [
- 'Cookie domains cannot contain any of the following \',; \\t\\r\\n\\013\\014\'',
- ],
- ]
- ],
- 'empty value' => [
- true, 'a', '', [],
- [
- 'headers' => [
- 'Set-Cookie: a=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'encoded value' => [
- true, 'a', '%', [],
- [
- 'headers' => [
- 'Set-Cookie: a=%25',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'encoded value with space' => [
- true, 'a', 'b c', [],
- [
- 'headers' => [
- 'Set-Cookie: a=b%20c',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'raw value' => [
- false, 'a', '%', [],
- [
- 'headers' => [
- 'Set-Cookie: a=%',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'expires too large' => [
- true, 'a', 'b', [ 'expires' => 253430725200 ],
- [
- 'headers' => [],
- 'returnValue' => false,
- 'errors' => [
- 'Expiry date cannot have a year greater than 9999',
- ],
- ]
- ],
- 'expires in the past' => [
- true, 'a', 'b', [ 'expires' => 979477200 ],
- [
- 'headers' => [
- 'Set-Cookie: a=b; expires=Sun, 14-Jan-2001 13:00:00 GMT; Max-Age=0',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'expires in the future' => [
- true, 'a', 'b', [ 'expires' => 32504889600 ],
- [
- 'headers' => [
- 'Set-Cookie: a=b; expires=Wed, 15-Jan-3000 00:00:00 GMT; Max-Age=30911234470',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'path' => [
- false, 'a', 'b', [ 'path' => '%%' ],
- [
- 'headers' => [
- 'Set-Cookie: a=b; path=%%',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'domain' => [
- false, 'a', 'b', [ 'domain' => '%%' ],
- [
- 'headers' => [
- 'Set-Cookie: a=b; domain=%%',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'secure' => [
- false, 'a', 'b', [ 'secure' => true ],
- [
- 'headers' => [
- 'Set-Cookie: a=b; secure',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'httponly' => [
- false, 'a', 'b', [ 'httponly' => true ],
- [
- 'headers' => [
- 'Set-Cookie: a=b; HttpOnly',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'samesite' => [
- false, 'a', 'b', [ 'samesite' => 'None' ],
- [
- 'headers' => [
- 'Set-Cookie: a=b; SameSite=None',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
- 'multiple options' => [
- false, 'a', 'b', [
- 'expires' => 32504889600,
- 'path' => '/%',
- 'domain' => '%.com',
- 'secure' => true,
- 'httponly' => true
- ],
- [
- 'headers' => [
- 'Set-Cookie: a=b; expires=Wed, 15-Jan-3000 00:00:00 GMT; Max-Age=30911234470; path=/%; domain=%.com; secure; HttpOnly',
- ],
- 'returnValue' => true,
- 'errors' => [],
- ]
- ],
-
- ];
- }
-
- /**
- * @dataProvider provideSetCookieEmulated
- */
- public function testSetCookieEmulated( $urlEncode, $name, $value, $options, $expected ) {
- $instance = new class extends SetCookieCompat {
- public $headers = [];
- public $errors = [];
-
- protected function time() {
- return 1593655130;
- }
-
- protected function error( $error ) {
- $this->errors[] = $error;
- }
-
- protected function headers_sent() {
- return false;
- }
-
- protected function header( $header ) {
- $this->headers[] = $header;
- }
- };
-
- $ret = $instance->setCookieEmulated( $urlEncode, $name, $value, $options );
- $this->assertSame( $expected['headers'], $instance->headers );
- $this->assertSame( $expected['errors'], $instance->errors );
- $this->assertSame( $expected['returnValue'], $ret );
- }
-}