WordPress.org

Make WordPress Core


Ignore:
Timestamp:
11/08/2017 11:47:04 AM (4 years ago)
Author:
dd32
Message:

External Libraries: Update Random_Compat from 1.2.1 to 2.0.11.

Notably this fixes PHP7 parse errors of the files and removes the OpenSSL functionality.
Full Changes: https://github.com/paragonie/random_compat/compare/v1.2.1...v2.0.11

Props jrdelarosa.
See #42439.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/random_compat/random.php

    r36886 r42130  
    44 * for using the new PHP 7 random_* API in PHP 5 projects
    55 *
    6  * @version 1.2.1
    7  * @released 2016-02-29
     6 * @version 2.0.10
     7 * @released 2017-03-13
    88 *
    99 * The MIT License (MIT)
    1010 *
    11  * Copyright (c) 2015 Paragon Initiative Enterprises
     11 * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
    1212 *
    1313 * Permission is hereby granted, free of charge, to any person obtaining a copy
     
    3232if (!defined('PHP_VERSION_ID')) {
    3333    // This constant was introduced in PHP 5.2.7
    34     $RandomCompatversion = explode('.', PHP_VERSION);
     34    $RandomCompatversion = array_map('intval', explode('.', PHP_VERSION));
    3535    define(
    3636        'PHP_VERSION_ID',
     
    4242}
    4343
    44 if (PHP_VERSION_ID < 70000) {
    45 
    46     if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
    47         define('RANDOM_COMPAT_READ_BUFFER', 8);
    48     }
    49 
    50     $RandomCompatDIR = dirname(__FILE__);
    51 
    52     require_once $RandomCompatDIR.'/byte_safe_strings.php';
    53     require_once $RandomCompatDIR.'/cast_to_int.php';
    54     require_once $RandomCompatDIR.'/error_polyfill.php';
    55 
    56     if (!function_exists('random_bytes')) {
     44/**
     45 * PHP 7.0.0 and newer have these functions natively.
     46 */
     47if (PHP_VERSION_ID >= 70000) {
     48    return;
     49}
     50
     51if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
     52    define('RANDOM_COMPAT_READ_BUFFER', 8);
     53}
     54
     55$RandomCompatDIR = dirname(__FILE__);
     56
     57require_once $RandomCompatDIR . '/byte_safe_strings.php';
     58require_once $RandomCompatDIR . '/cast_to_int.php';
     59require_once $RandomCompatDIR . '/error_polyfill.php';
     60
     61if (!is_callable('random_bytes')) {
     62    /**
     63     * PHP 5.2.0 - 5.6.x way to implement random_bytes()
     64     *
     65     * We use conditional statements here to define the function in accordance
     66     * to the operating environment. It's a micro-optimization.
     67     *
     68     * In order of preference:
     69     *   1. Use libsodium if available.
     70     *   2. fread() /dev/urandom if available (never on Windows)
     71     *   3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
     72     *   4. COM('CAPICOM.Utilities.1')->GetRandom()
     73     *
     74     * See RATIONALE.md for our reasoning behind this particular order
     75     */
     76    if (extension_loaded('libsodium')) {
     77        // See random_bytes_libsodium.php
     78        if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
     79            require_once $RandomCompatDIR . '/random_bytes_libsodium.php';
     80        } elseif (method_exists('Sodium', 'randombytes_buf')) {
     81            require_once $RandomCompatDIR . '/random_bytes_libsodium_legacy.php';
     82        }
     83    }
     84
     85    /**
     86     * Reading directly from /dev/urandom:
     87     */
     88    if (DIRECTORY_SEPARATOR === '/') {
     89        // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
     90        // way to exclude Windows.
     91        $RandomCompatUrandom = true;
     92        $RandomCompat_basedir = ini_get('open_basedir');
     93
     94        if (!empty($RandomCompat_basedir)) {
     95            $RandomCompat_open_basedir = explode(
     96                PATH_SEPARATOR,
     97                strtolower($RandomCompat_basedir)
     98            );
     99            $RandomCompatUrandom = (array() !== array_intersect(
     100                array('/dev', '/dev/', '/dev/urandom'),
     101                $RandomCompat_open_basedir
     102            ));
     103            $RandomCompat_open_basedir = null;
     104        }
     105
     106        if (
     107            !is_callable('random_bytes')
     108            &&
     109            $RandomCompatUrandom
     110            &&
     111            @is_readable('/dev/urandom')
     112        ) {
     113            // Error suppression on is_readable() in case of an open_basedir
     114            // or safe_mode failure. All we care about is whether or not we
     115            // can read it at this point. If the PHP environment is going to
     116            // panic over trying to see if the file can be read in the first
     117            // place, that is not helpful to us here.
     118
     119            // See random_bytes_dev_urandom.php
     120            require_once $RandomCompatDIR . '/random_bytes_dev_urandom.php';
     121        }
     122        // Unset variables after use
     123        $RandomCompat_basedir = null;
     124    } else {
     125        $RandomCompatUrandom = false;
     126    }
     127
     128    /**
     129     * mcrypt_create_iv()
     130     *
     131     * We only want to use mcypt_create_iv() if:
     132     *
     133     * - random_bytes() hasn't already been defined
     134     * - the mcrypt extensions is loaded
     135     * - One of these two conditions is true:
     136     *   - We're on Windows (DIRECTORY_SEPARATOR !== '/')
     137     *   - We're not on Windows and /dev/urandom is readabale
     138     *     (i.e. we're not in a chroot jail)
     139     * - Special case:
     140     *   - If we're not on Windows, but the PHP version is between
     141     *     5.6.10 and 5.6.12, we don't want to use mcrypt. It will
     142     *     hang indefinitely. This is bad.
     143     *   - If we're on Windows, we want to use PHP >= 5.3.7 or else
     144     *     we get insufficient entropy errors.
     145     */
     146    if (
     147        !is_callable('random_bytes')
     148        &&
     149        // Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be.
     150        (DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307)
     151        &&
     152        // Prevent this code from hanging indefinitely on non-Windows;
     153        // see https://bugs.php.net/bug.php?id=69833
     154        (
     155            DIRECTORY_SEPARATOR !== '/' ||
     156            (PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
     157        )
     158        &&
     159        extension_loaded('mcrypt')
     160    ) {
     161        // See random_bytes_mcrypt.php
     162        require_once $RandomCompatDIR . '/random_bytes_mcrypt.php';
     163    }
     164    $RandomCompatUrandom = null;
     165
     166    /**
     167     * This is a Windows-specific fallback, for when the mcrypt extension
     168     * isn't loaded.
     169     */
     170    if (
     171        !is_callable('random_bytes')
     172        &&
     173        extension_loaded('com_dotnet')
     174        &&
     175        class_exists('COM')
     176    ) {
     177        $RandomCompat_disabled_classes = preg_split(
     178            '#\s*,\s*#',
     179            strtolower(ini_get('disable_classes'))
     180        );
     181
     182        if (!in_array('com', $RandomCompat_disabled_classes)) {
     183            try {
     184                $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
     185                if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
     186                    // See random_bytes_com_dotnet.php
     187                    require_once $RandomCompatDIR . '/random_bytes_com_dotnet.php';
     188                }
     189            } catch (com_exception $e) {
     190                // Don't try to use it.
     191            }
     192        }
     193        $RandomCompat_disabled_classes = null;
     194        $RandomCompatCOMtest = null;
     195    }
     196
     197    /**
     198     * throw new Exception
     199     */
     200    if (!is_callable('random_bytes')) {
    57201        /**
    58          * PHP 5.2.0 - 5.6.x way to implement random_bytes()
     202         * We don't have any more options, so let's throw an exception right now
     203         * and hope the developer won't let it fail silently.
    59204         *
    60          * We use conditional statements here to define the function in accordance
    61          * to the operating environment. It's a micro-optimization.
    62          *
    63          * In order of preference:
    64          *   1. Use libsodium if available.
    65          *   2. fread() /dev/urandom if available (never on Windows)
    66          *   3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
    67          *   4. COM('CAPICOM.Utilities.1')->GetRandom()
    68          *   5. openssl_random_pseudo_bytes() (absolute last resort)
    69          *
    70          * See ERRATA.md for our reasoning behind this particular order
     205         * @param mixed $length
     206         * @return void
     207         * @throws Exception
    71208         */
    72         if (extension_loaded('libsodium')) {
    73             // See random_bytes_libsodium.php
    74             if (PHP_VERSION_ID >= 50300 && function_exists('\\Sodium\\randombytes_buf')) {
    75                 require_once $RandomCompatDIR.'/random_bytes_libsodium.php';
    76             } elseif (method_exists('Sodium', 'randombytes_buf')) {
    77                 require_once $RandomCompatDIR.'/random_bytes_libsodium_legacy.php';
    78             }
    79         }
    80 
    81         /**
    82          * Reading directly from /dev/urandom:
    83          */
    84         if (DIRECTORY_SEPARATOR === '/') {
    85             // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
    86             // way to exclude Windows.
    87             $RandomCompatUrandom = true;
    88             $RandomCompat_basedir = ini_get('open_basedir');
    89 
    90             if (!empty($RandomCompat_basedir)) {
    91                 $RandomCompat_open_basedir = explode(
    92                     PATH_SEPARATOR,
    93                     strtolower($RandomCompat_basedir)
    94                 );
    95                 $RandomCompatUrandom = in_array(
    96                     '/dev',
    97                     $RandomCompat_open_basedir
    98                 );
    99                 $RandomCompat_open_basedir = null;
    100             }
    101 
    102             if (
    103                 !function_exists('random_bytes')
    104                 &&
    105                 $RandomCompatUrandom
    106                 &&
    107                 @is_readable('/dev/urandom')
    108             ) {
    109                 // Error suppression on is_readable() in case of an open_basedir
    110                 // or safe_mode failure. All we care about is whether or not we
    111                 // can read it at this point. If the PHP environment is going to
    112                 // panic over trying to see if the file can be read in the first
    113                 // place, that is not helpful to us here.
    114 
    115                 // See random_bytes_dev_urandom.php
    116                 require_once $RandomCompatDIR.'/random_bytes_dev_urandom.php';
    117             }
    118             // Unset variables after use
    119             $RandomCompat_basedir = null;
    120             $RandomCompatUrandom = null;
    121         }
    122 
    123         /**
    124          * mcrypt_create_iv()
    125          */
    126         if (
    127             !function_exists('random_bytes')
    128             &&
    129             PHP_VERSION_ID >= 50307
    130             &&
    131             extension_loaded('mcrypt')
    132         ) {
    133             // Prevent this code from hanging indefinitely on non-Windows;
    134             // see https://bugs.php.net/bug.php?id=69833
    135             if (
    136                 DIRECTORY_SEPARATOR !== '/' ||
    137                 (PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
    138             ) {
    139                 // See random_bytes_mcrypt.php
    140                 require_once $RandomCompatDIR.'/random_bytes_mcrypt.php';
    141             }
    142         }
    143 
    144         if (
    145             !function_exists('random_bytes')
    146             &&
    147             extension_loaded('com_dotnet')
    148             &&
    149             class_exists('COM')
    150         ) {
    151             $RandomCompat_disabled_classes = preg_split(
    152                 '#\s*,\s*#',
    153                 strtolower(ini_get('disable_classes'))
     209        function random_bytes($length)
     210        {
     211            unset($length); // Suppress "variable not used" warnings.
     212            throw new Exception(
     213                'There is no suitable CSPRNG installed on your system'
    154214            );
    155 
    156             if (!in_array('com', $RandomCompat_disabled_classes)) {
    157                 try {
    158                     $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
    159                     if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
    160                         // See random_bytes_com_dotnet.php
    161                         require_once $RandomCompatDIR.'/random_bytes_com_dotnet.php';
    162                     }
    163                 } catch (com_exception $e) {
    164                     // Don't try to use it.
    165                 }
    166             }
    167             $RandomCompat_disabled_classes = null;
    168             $RandomCompatCOMtest = null;
    169         }
    170 
    171         /**
    172          * openssl_random_pseudo_bytes()
    173          */
    174         if (
    175             (
    176                 // Unix-like with PHP >= 5.3.0 or
    177                 (
    178                     DIRECTORY_SEPARATOR === '/'
    179                     &&
    180                     PHP_VERSION_ID >= 50300
    181                 )
    182                 ||
    183                 // Windows with PHP >= 5.4.1
    184                 PHP_VERSION_ID >= 50401
    185             )
    186             &&
    187             !function_exists('random_bytes')
    188             &&
    189             extension_loaded('openssl')
    190         ) {
    191             // See random_bytes_openssl.php
    192             require_once $RandomCompatDIR.'/random_bytes_openssl.php';
    193         }
    194 
    195         /**
    196          * throw new Exception
    197          */
    198         if (!function_exists('random_bytes')) {
    199             /**
    200              * We don't have any more options, so let's throw an exception right now
    201              * and hope the developer won't let it fail silently.
    202              */
    203             function random_bytes($length)
    204             {
    205                 throw new Exception(
    206                     'There is no suitable CSPRNG installed on your system'
    207                 );
    208             }
    209         }
    210     }
    211 
    212     if (!function_exists('random_int')) {
    213         require_once $RandomCompatDIR.'/random_int.php';
    214     }
    215 
    216     $RandomCompatDIR = null;
    217 }
     215        }
     216    }
     217}
     218
     219if (!is_callable('random_int')) {
     220    require_once $RandomCompatDIR . '/random_int.php';
     221}
     222
     223$RandomCompatDIR = null;
Note: See TracChangeset for help on using the changeset viewer.