Bump PHP version requirement to 7.0.0+
authorJames D. Forrester <jforrester@wikimedia.org>
Thu, 18 Jan 2018 23:34:32 +0000 (15:34 -0800)
committerReedy <reedy@wikimedia.org>
Wed, 18 Apr 2018 18:49:47 +0000 (18:49 +0000)
Bug: T172165
Change-Id: I740f32ac859d9bb3787fdf8414f82ae6f410492f

12 files changed:
INSTALL
RELEASE-NOTES-1.31
composer.json
includes/GlobalFunctions.php
includes/PHPVersionCheck.php
includes/http/CurlHttpRequest.php
includes/http/PhpHttpRequest.php
includes/installer/Installer.php
includes/libs/CSSMin.php
includes/libs/MultiHttpClient.php
includes/watcheditem/WatchedItemQueryService.php
tests/phpunit/includes/media/IPTCTest.php

diff --git a/INSTALL b/INSTALL
index 3b93505..aabbfa9 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -6,7 +6,7 @@ Starting with MediaWiki 1.2.0, it's possible to install and configure the wiki
 "in-place", as long as you have the necessary prerequisites available.
 
 Required software:
-* Web server with PHP 5.5.9 or higher.
+* Web server with PHP 7.0.0 or HHVM 3.18.5 or higher.
 * A SQL server, the following types are supported
 ** MySQL 5.5.8 or higher
 ** PostgreSQL 9.2 or higher
index c41b604..b7c4c54 100644 (file)
@@ -364,8 +364,8 @@ changes to languages because of Phabricator reports.
   will not have this trimming behavior.
 
 == Compatibility ==
-MediaWiki 1.31 requires PHP 5.5.9 or later. Although HHVM 3.18.5 or later is supported,
-it is generally advised to use PHP 5.5.9 or later for long term support.
+MediaWiki 1.31 requires PHP 7.0.0 or later. Although HHVM 3.18.5 or later is supported,
+it is generally advised to use PHP 7.0.0 or later for long term support.
 
 MySQL/MariaDB is the recommended DBMS. PostgreSQL or SQLite can also be used,
 but support for them is somewhat less mature. There is experimental support for
@@ -373,7 +373,7 @@ Oracle and Microsoft SQL Server.
 
 The supported versions are:
 
-* MySQL 5.0.3 or later
+* MySQL 5.5.8 or later
 * PostgreSQL 9.2 or later
 * SQLite 3.3.7 or later
 * Oracle 9.0.1 or later
index 98e4d49..be696f2 100644 (file)
@@ -26,7 +26,7 @@
                "liuggio/statsd-php-client": "1.0.18",
                "oojs/oojs-ui": "v0.26.4",
                "oyejorge/less.php": "1.7.0.14",
-               "php": ">=5.5.9",
+               "php": ">=7.0.0",
                "psr/log": "1.0.2",
                "wikimedia/assert": "0.2.2",
                "wikimedia/at-ease": "1.2.0",
index 3dfe12e..7667a9e 100644 (file)
@@ -32,75 +32,6 @@ use MediaWiki\Shell\Shell;
 use Wikimedia\ScopedCallback;
 use Wikimedia\Rdbms\DBReplicationWaitError;
 
-// Hide compatibility functions from Doxygen
-/// @cond
-/**
- * Compatibility functions
- *
- * We support PHP 5.5.9 and up.
- * Re-implementations of newer functions or functions in non-standard
- * PHP extensions may be included here.
- */
-
-// hash_equals function only exists in PHP >= 5.6.0
-// https://secure.php.net/hash_equals
-if ( !function_exists( 'hash_equals' ) ) {
-       /**
-        * Check whether a user-provided string is equal to a fixed-length secret string
-        * without revealing bytes of the secret string through timing differences.
-        *
-        * The usual way to compare strings (PHP's === operator or the underlying memcmp()
-        * function in C) is to compare corresponding bytes and stop at the first difference,
-        * which would take longer for a partial match than for a complete mismatch. This
-        * is not secure when one of the strings (e.g. an HMAC or token) must remain secret
-        * and the other may come from an attacker. Statistical analysis of timing measurements
-        * over many requests may allow the attacker to guess the string's bytes one at a time
-        * (and check his guesses) even if the timing differences are extremely small.
-        *
-        * When making such a security-sensitive comparison, it is essential that the sequence
-        * in which instructions are executed and memory locations are accessed not depend on
-        * the secret string's value. HOWEVER, for simplicity, we do not attempt to minimize
-        * the inevitable leakage of the string's length. That is generally known anyway as
-        * a chararacteristic of the hash function used to compute the secret value.
-        *
-        * Longer explanation: http://www.emerose.com/timing-attacks-explained
-        *
-        * @codeCoverageIgnore
-        * @param string $known_string Fixed-length secret string to compare against
-        * @param string $user_string User-provided string
-        * @return bool True if the strings are the same, false otherwise
-        */
-       function hash_equals( $known_string, $user_string ) {
-               // Strict type checking as in PHP's native implementation
-               if ( !is_string( $known_string ) ) {
-                       trigger_error( 'hash_equals(): Expected known_string to be a string, ' .
-                               gettype( $known_string ) . ' given', E_USER_WARNING );
-
-                       return false;
-               }
-
-               if ( !is_string( $user_string ) ) {
-                       trigger_error( 'hash_equals(): Expected user_string to be a string, ' .
-                               gettype( $user_string ) . ' given', E_USER_WARNING );
-
-                       return false;
-               }
-
-               $known_string_len = strlen( $known_string );
-               if ( $known_string_len !== strlen( $user_string ) ) {
-                       return false;
-               }
-
-               $result = 0;
-               for ( $i = 0; $i < $known_string_len; $i++ ) {
-                       $result |= ord( $known_string[$i] ) ^ ord( $user_string[$i] );
-               }
-
-               return ( $result === 0 );
-       }
-}
-/// @endcond
-
 /**
  * Load an extension
  *
index 37d4632..a7ece4d 100644 (file)
@@ -94,7 +94,7 @@ class PHPVersionCheck {
                        'version' => PHP_VERSION,
                        'vendor' => 'the PHP Group',
                        'upstreamSupported' => '5.6.0',
-                       'minSupported' => '5.5.9',
+                       'minSupported' => '7.0.0',
                        'upgradeURL' => 'https://secure.php.net/downloads.php',
                );
        }
@@ -120,7 +120,7 @@ class PHPVersionCheck {
                                . "MediaWiki $this->mwVersion needs {$phpInfo['implementation']}"
                                . " $minimumVersion or higher or {$otherInfo['implementation']} version "
                                . "{$otherInfo['minSupported']}.\n\nCheck if you have a"
-                               . " newer php executable with a different name, such as php5.\n\n";
+                               . " newer php executable with a different name.\n\n";
 
                        // phpcs:disable Generic.Files.LineLength
                        $longHtml = <<<HTML
index 44bdddb..a8fbed0 100644 (file)
@@ -82,16 +82,7 @@ class CurlHttpRequest extends MWHttpRequest {
                        // Don't interpret POST parameters starting with '@' as file uploads, because this
                        // makes it impossible to POST plain values starting with '@' (and causes security
                        // issues potentially exposing the contents of local files).
-                       // The PHP manual says this option was introduced in PHP 5.5 defaults to true in PHP 5.6,
-                       // but we support lower versions, and the option doesn't exist in HHVM 5.6.99.
-                       if ( defined( 'CURLOPT_SAFE_UPLOAD' ) ) {
-                               $this->curlOptions[CURLOPT_SAFE_UPLOAD] = true;
-                       } elseif ( is_array( $postData ) ) {
-                               // In PHP 5.2 and later, '@' is interpreted as a file upload if POSTFIELDS
-                               // is an array, but not if it's a string. So convert $req['body'] to a string
-                               // for safety.
-                               $postData = wfArrayToCgi( $postData );
-                       }
+                       $this->curlOptions[CURLOPT_SAFE_UPLOAD] = true;
                        $this->curlOptions[CURLOPT_POSTFIELDS] = $postData;
 
                        // Suppress 'Expect: 100-continue' header, as some servers
index 0636314..0f499c2 100644 (file)
@@ -46,21 +46,6 @@ class PhpHttpRequest extends MWHttpRequest {
                $certLocations = [];
                if ( $this->caInfo ) {
                        $certLocations = [ 'manual' => $this->caInfo ];
-               } elseif ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
-                       // Default locations, based on
-                       // https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/
-                       // PHP 5.5 and older doesn't have any defaults, so we try to guess ourselves.
-                       // PHP 5.6+ gets the CA location from OpenSSL as long as it is not set manually,
-                       // so we should leave capath/cafile empty there.
-                       $certLocations = array_filter( [
-                               getenv( 'SSL_CERT_DIR' ),
-                               getenv( 'SSL_CERT_PATH' ),
-                               '/etc/pki/tls/certs/ca-bundle.crt', # Fedora et al
-                               '/etc/ssl/certs',  # Debian et al
-                               '/etc/pki/tls/certs/ca-bundle.trust.crt',
-                               '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem',
-                               '/System/Library/OpenSSL', # OSX
-                       ] );
                }
 
                foreach ( $certLocations as $key => $cert ) {
index 1efe5d6..aa9cd49 100644 (file)
@@ -1199,7 +1199,7 @@ abstract class Installer {
                $scriptTypes = [
                        'php' => [
                                "<?php echo 'ex' . 'ec';",
-                               "#!/var/env php5\n<?php echo 'ex' . 'ec';",
+                               "#!/var/env php\n<?php echo 'ex' . 'ec';",
                        ],
                ];
 
index 73825e8..b538d3b 100644 (file)
@@ -402,6 +402,7 @@ class CSSMin {
                        // Match these three variants separately to avoid broken urls when
                        // e.g. a double quoted url contains a parenthesis, or when a
                        // single quoted url contains a double quote, etc.
+                       // FIXME: Simplify now we only support PHP 7.0.0+
                        // Note: PCRE doesn't support multiple capture groups with the same name by default.
                        // - PCRE 6.7 introduced the "J" modifier (PCRE_INFO_JCHANGED for PCRE_DUPNAMES).
                        //   https://secure.php.net/manual/en/reference.pcre.pattern.modifiers.php
index 053a5ff..dd8772c 100644 (file)
@@ -346,16 +346,7 @@ class MultiHttpClient implements LoggerAwareInterface {
                        // Don't interpret POST parameters starting with '@' as file uploads, because this
                        // makes it impossible to POST plain values starting with '@' (and causes security
                        // issues potentially exposing the contents of local files).
-                       // The PHP manual says this option was introduced in PHP 5.5 defaults to true in PHP 5.6,
-                       // but we support lower versions, and the option doesn't exist in HHVM 5.6.99.
-                       if ( defined( 'CURLOPT_SAFE_UPLOAD' ) ) {
-                               curl_setopt( $ch, CURLOPT_SAFE_UPLOAD, true );
-                       } elseif ( is_array( $req['body'] ) ) {
-                               // In PHP 5.2 and later, '@' is interpreted as a file upload if POSTFIELDS
-                               // is an array, but not if it's a string. So convert $req['body'] to a string
-                               // for safety.
-                               $req['body'] = http_build_query( $req['body'] );
-                       }
+                       curl_setopt( $ch, CURLOPT_SAFE_UPLOAD, true );
                        curl_setopt( $ch, CURLOPT_POSTFIELDS, $req['body'] );
                } else {
                        if ( is_resource( $req['body'] ) || $req['body'] !== '' ) {
index 506ee00..b91e36e 100644 (file)
@@ -320,8 +320,8 @@ class WatchedItemQueryService {
        }
 
        private function getRecentChangeFieldsFromRow( stdClass $row ) {
-               // This can be simplified to single array_filter call filtering by key value,
-               // once we stop supporting PHP 5.5
+               // FIXME: This can be simplified to single array_filter call filtering by key value,
+               // now we have stopped supporting PHP 5.5
                $allFields = get_object_vars( $row );
                $rcKeys = array_filter(
                        array_keys( $allFields ),
index 826957e..4b3ba07 100644 (file)
@@ -44,13 +44,6 @@ class IPTCTest extends MediaWikiTestCase {
         * @covers IPTC::parse
         */
        public function testIPTCParseForcedUTFButInvalid() {
-               if ( version_compare( PHP_VERSION, '5.5.26', '<' )
-                       || ( version_compare( PHP_VERSION, '5.6.0', '>' )
-                               && version_compare( PHP_VERSION, '5.6.10', '<' )
-                       )
-               ) {
-                       $this->markTestSkipped( 'Test fails on pre-PHP 5.5.25. See T124574/T39665 for details.' );
-               }
                $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x11\x1c\x02\x19\x00\x04\xC3\xC3\xC3\xB8"
                        . "\x1c\x01\x5A\x00\x03\x1B\x25\x47";
                $res = IPTC::parse( $iptcData );