Make WordPress Core

Ticket #55635: 55635.0.2.diff

File 55635.0.2.diff, 6.9 KB (added by dmsnell, 4 years ago)

Incorporates some style feedback and checks for false input.

  • wp-includes/load.php

    diff --git a/wp-includes/load.php b/wp-includes/load.php
    index ae5ada388d..5256a33fce 100644
    a b function is_ssl() { 
    14251425}
    14261426
    14271427/**
    1428  * Converts a shorthand byte value to an integer byte value.
     1428 * Returns byte size represented in a numeric php.ini directive.
     1429 *
     1430 * php.ini directives may use a string representation of a number of bytes
     1431 * or a "shorthand" byte size to reference larger values. Multiple numeric
     1432 * php.ini directive use these shorthands even when they don't refer bytes.
     1433 *
     1434 * Example:
     1435 *
     1436 *     wp_convert_hr_to_bytes( "1m" ) == 1048576
     1437 *     wp_convert_hr_to_bytes( "2K" ) == 2048 // 2 * 1024
     1438 *     wp_convert_hr_to_bytes( "0.5g" ) == 0
     1439 *     wp_convert_hr_to_bytes( "14.6e-13g" ) == 15032385536 // 14 * 1024^3
     1440 *     wp_convert_hr_to_bytes( "-813k" ) == 0;
     1441 *     wp_convert_hr_to_bytes( "boat" ) == 0;
     1442 *
     1443 *     // This gives an answer, but it's _wrong_ because
     1444 *     // the underlying mechanism in PHP overflowed and
     1445 *     // the real return value depends on whether PHP
     1446 *     // was built with 64-bit support.
     1447 *     wp_convert_hr_to_bytes( "9223372036854775807g" ) == ??
     1448 *
     1449 * Notes:
     1450 *  - Suffix units are case-insensitive and are always determined
     1451 *    by looking at the last character in the input string.
     1452 *  - Suffix units k/m/g report powers of 1024. PHP and the IEC disagree
     1453 *    on the meaning of "kilobyte," "megabyte," and "gigabyte."
     1454 *  - This function will not fail; it stops parsing after finding
     1455 *    the last consecutive digit at the front of the trimmed string.
     1456 *  - Invalid string representations return a value of 0.
     1457 *  - This code mirrors the computation inside PHP and should only
     1458 *    change its output if PHP redefines how it parses numeric php.ini
     1459 *    directive. If you think something is wrong or should be
     1460 *    refactored it probably shouldn't be. Consult `zend_operators.c`
     1461 *    in the PHP-SRC repository for more info; specifically
     1462 *    `zend_atol()` and `_is_numeric_string_ex()`.
     1463 *  - As noted in the PHP documentation, any numeric value that overflows
     1464 *    an integer for the platform on which PHP is built will break.
    14291465 *
    14301466 * @since 2.3.0
    14311467 * @since 4.6.0 Moved from media.php to load.php.
     1468 * @since 6.1.0 Mirrors size calculation in PHP.
    14321469 *
    14331470 * @link https://www.php.net/manual/en/function.ini-get.php
    14341471 * @link https://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes
     1472 * @link https://en.wikipedia.org/wiki/Byte#Multiple-byte_units
    14351473 *
    1436  * @param string $value A (PHP ini) byte value, either shorthand or ordinary.
    1437  * @return int An integer byte value.
     1474 * @param string|false $value A numeric php.ini directive's byte value,
     1475 *                            either shorthand or ordinary, as returned
     1476 *                            by a call to `ini_get()`.
     1477 * @return int                Parsed numeric value represented by given string.
    14381478 */
    14391479function wp_convert_hr_to_bytes( $value ) {
    1440         $value = strtolower( trim( $value ) );
    1441         $bytes = (int) $value;
     1480        /*
     1481         * Ideally callers would check for the absence of any configured value
     1482         * before passing `false` but it's commonly called with an inline call
     1483         * to get the value: e.g. `wp_convert_hr_to_bytes( ini_get( 'post_size_max' ) );`
     1484         */
     1485        if ( false === $value ) {
     1486                return 0;
     1487        }
     1488
     1489        /**
     1490         * Number of bytes in input string; we're only assessing 7-bit ASCII/Unicode characters.
     1491         * @var int
     1492         */
     1493        $strlen = strlen( $value );
     1494
     1495        /**
     1496         * Count (of bytes) represented by value string.
     1497         * @var int|float
     1498         */
     1499        $scalar = 0;
     1500
     1501        /**
     1502         * Sign of number represented by input, either positive (1) or negative (-1).
     1503         * @var int
     1504         */
     1505        $sign = 1;
     1506
     1507        /**
     1508         * Numeric base of digits; determined by string prefix (e.g. "0x" or "0").
     1509         * @var int
     1510         */
     1511        $base = 10;
    14421512
    1443         if ( false !== strpos( $value, 'g' ) ) {
    1444                 $bytes *= GB_IN_BYTES;
    1445         } elseif ( false !== strpos( $value, 'm' ) ) {
    1446                 $bytes *= MB_IN_BYTES;
    1447         } elseif ( false !== strpos( $value, 'k' ) ) {
    1448                 $bytes *= KB_IN_BYTES;
     1513        /**
     1514         * Index into input string as we walk through it and analyze each character.
     1515         * @var int
     1516         */
     1517        $i = 0;
     1518
     1519        // Trim leading whitespace.
     1520        for ( ; $i < $strlen; $i++ ) {
     1521                switch ( $value[ $i ] ) {
     1522                        case ' ':
     1523                        case "\t":
     1524                        case "\r":
     1525                        case "\v":
     1526                        case "\f":
     1527                                break;
     1528
     1529                        default:
     1530                                break 2;
     1531                }
     1532        }
     1533
     1534        // Handle optional sign indicator.
     1535        switch ( $value[ $i ] ) {
     1536                case '+':
     1537                        $i++;
     1538                        break;
     1539
     1540                case '-':
     1541                        $sign = -1;
     1542                        $i++;
     1543                        break;
    14491544        }
    14501545
    1451         // Deal with large (float) values which run into the maximum integer size.
    1452         return min( $bytes, PHP_INT_MAX );
     1546        // Determine base for digit conversion, if not decimal.
     1547        $base_a = $i < $strlen ? $value[ $i ] : '';
     1548        $base_b = $i + 1 < $strlen ? $value[ $i + 1 ] : '';
     1549
     1550        if ( $base_a === '0' && ( $base_b === 'x' || $base_b === 'X' ) ) {
     1551                $base = 16;
     1552                $i += 2;
     1553        } else if ( $base_a === '0' && ctype_digit( $base_b ) ) {
     1554                $base = 8;
     1555                $i += 1;
     1556        }
     1557
     1558        // Trim leading zeros.
     1559        for ( ; $i < $strlen; $i++ ) {
     1560                if ( '0' !== $value[ $i ] ) {
     1561                        break;
     1562                }
     1563        }
     1564
     1565        /**
     1566         * Numeric values for scanned digits.
     1567         * @var array
     1568         */
     1569        $digits = [
     1570                '0' =>  0, '1' =>  1, '2' =>  2, '3' =>  3, '4' =>  4,
     1571                '5' =>  5, '6' =>  6, '7' =>  7, '8' =>  8, '9' =>  9,
     1572                'A' => 10, 'a' => 10, 'B' => 11, 'b' => 11, 'C' => 12,
     1573                'c' => 12, 'D' => 13, 'd' => 13, 'E' => 14, 'e' => 14,
     1574                'F' => 15, 'f' => 15,
     1575        ];
     1576
     1577        /*
     1578         * Build the scalar value by eating the
     1579         * next sequence of contiguous digits.
     1580         */
     1581        for ( ; $i < $strlen; $i++) {
     1582                $c = $value[ $i ];
     1583
     1584                /*
     1585                 * Only digits recognized in this base system can be used.
     1586                 * Once we find an unrecognized digit we abort and move
     1587                 * on to the next step in parsing the size suffix.
     1588                 */
     1589                if ( ! isset( $digits[ $c ] ) || $digits[ $c ] >= $base ) {
     1590                        break;
     1591                }
     1592
     1593                $scalar = $scalar * $base + $digits[ $c ];
     1594        }
     1595
     1596        // Clamp the parsed digits to an integer value as PHP does internally.
     1597        if ( $sign > 0 && $scalar >= PHP_INT_MAX ) {
     1598                $scalar = PHP_INT_MAX;
     1599        } else if ( $sign < 0 && $scalar >= -PHP_INT_MIN ) {
     1600                $scalar = PHP_INT_MIN;
     1601        } else if ( $sign < 0 ) {
     1602                $scalar = -$scalar;
     1603        }
     1604
     1605        /*
     1606         * Do not use WP constants here (GB_IN_BYTES, MB_IN_BYTES, KB_IN_BYTES)
     1607         * since they are re-definable; PHP shorthand values are hard-coded
     1608         * in PHP itself and stay the same regardless of these constants.
     1609         *
     1610         * Note that we can overflow here, as happens in PHP itself.
     1611         * Overflow results will likely not match PHP's value, but
     1612         * will likely break in most cases anyway and so leaving
     1613         * this loose is the best we can do until and unless PHP
     1614         * makes a more concrete choice on how to handle overflow.
     1615         */
     1616        switch ( $value[ $strlen - 1 ] ) {
     1617                case 'g':
     1618                case 'G':
     1619                        $scalar *= 1073741824; // 1024^3
     1620                        break;
     1621
     1622                case 'm':
     1623                case 'M':
     1624                        $scalar *= 1048576; // 1024^2
     1625                        break;
     1626
     1627                case 'k':
     1628                case 'K':
     1629                        $scalar *= 1024;
     1630                        break;
     1631        }
     1632
     1633        return (int) $scalar;
    14531634}
    14541635
     1636
    14551637/**
    14561638 * Determines whether a PHP ini value is changeable at runtime.
    14571639 *