Ticket #55635: 55635.0.3.diff
| File 55635.0.3.diff, 23.1 KB (added by , 4 years ago) |
|---|
-
src/wp-admin/includes/class-wp-debug-data.php
diff --git a/src/wp-admin/includes/class-wp-debug-data.php b/src/wp-admin/includes/class-wp-debug-data.php index a921fc4dcb..6fb5cf1253 100644
a b class WP_Debug_Data { 544 544 $post_max_size = ini_get( 'post_max_size' ); 545 545 $upload_max_filesize = ini_get( 'upload_max_filesize' ); 546 546 $max_file_uploads = ini_get( 'max_file_uploads' ); 547 $effective = min( wp_convert_hr_to_bytes( $post_max_size ), wp_convert_hr_to_bytes( $upload_max_filesize ));547 $effective = wp_ini_lesser_quantity( $post_max_size, $upload_max_filesize ); 548 548 549 549 // Add info in Media section. 550 550 $info['wp-media']['fields']['file_uploads'] = array( -
src/wp-admin/includes/class-wp-site-health.php
diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index 7c94e8be10..542fbc280f 100644
a b class WP_Site_Health { 2163 2163 $post_max_size = ini_get( 'post_max_size' ); 2164 2164 $upload_max_filesize = ini_get( 'upload_max_filesize' ); 2165 2165 2166 if ( wp_ convert_hr_to_bytes( $post_max_size ) < wp_convert_hr_to_bytes( $upload_max_filesize )) {2166 if ( wp_ini_quantity_cmp( $post_max_size, $upload_max_filesize ) < 0 ) { 2167 2167 $result['label'] = sprintf( 2168 2168 /* translators: 1: post_max_size, 2: upload_max_filesize */ 2169 2169 __( 'The "%1$s" value is smaller than "%2$s"' ), … … class WP_Site_Health { 2172 2172 ); 2173 2173 $result['status'] = 'recommended'; 2174 2174 2175 if ( 0 === wp_convert_hr_to_bytes( $post_max_size )) {2175 if ( wp_ini_parse_quantity( $post_max_size ) <= 0 ) { 2176 2176 $result['description'] = sprintf( 2177 2177 '<p>%s</p>', 2178 2178 sprintf( -
src/wp-includes/default-constants.php
diff --git a/src/wp-includes/default-constants.php b/src/wp-includes/default-constants.php index 56754033a0..dff6db37aa 100644
a b function wp_initial_constants() { 39 39 define( 'WP_START_TIMESTAMP', microtime( true ) ); 40 40 } 41 41 42 $current_limit = ini_get( 'memory_limit' ); 43 $current_limit_int = wp_convert_hr_to_bytes( $current_limit ); 42 $current_limit = ini_get( 'memory_limit' ); 44 43 45 44 // Define memory limits. 46 45 if ( ! defined( 'WP_MEMORY_LIMIT' ) ) { … … function wp_initial_constants() { 56 55 if ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) ) { 57 56 if ( false === wp_is_ini_value_changeable( 'memory_limit' ) ) { 58 57 define( 'WP_MAX_MEMORY_LIMIT', $current_limit ); 59 } elseif ( -1 === $current_limit_int || $current_limit_int > 268435456 /* = 256M */) {58 } elseif ( wp_ini_quantity_cmp( $current_limit, '256M' ) > 0 ) { 60 59 define( 'WP_MAX_MEMORY_LIMIT', $current_limit ); 61 60 } else { 62 61 define( 'WP_MAX_MEMORY_LIMIT', '256M' ); … … function wp_initial_constants() { 64 63 } 65 64 66 65 // Set memory limits. 67 $wp_limit_int = wp_convert_hr_to_bytes( WP_MEMORY_LIMIT ); 68 if ( -1 !== $current_limit_int && ( -1 === $wp_limit_int || $wp_limit_int > $current_limit_int ) ) { 66 if ( wp_ini_quantity_cmp( WP_MEMORY_LIMIT, $current_limit ) > 0 ) { 69 67 ini_set( 'memory_limit', WP_MEMORY_LIMIT ); 70 68 } 71 69 -
src/wp-includes/functions.php
diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 946853c361..587ec21ed9 100644
a b function wp_raise_memory_limit( $context = 'admin' ) { 7454 7454 return false; 7455 7455 } 7456 7456 7457 $current_limit = ini_get( 'memory_limit' ); 7458 $current_limit_int = wp_convert_hr_to_bytes( $current_limit ); 7457 $current_limit = ini_get( 'memory_limit' ); 7459 7458 7460 if ( -1 === $current_limit_int ) { 7459 // If we're already set to an unlimited value there's no higher limit to set. 7460 if ( wp_ini_parse_quantity( $current_limit ) <= 0 ) { 7461 7461 return false; 7462 7462 } 7463 7463 7464 $wp_max_limit = WP_MAX_MEMORY_LIMIT; 7465 $wp_max_limit_int = wp_convert_hr_to_bytes( $wp_max_limit ); 7466 $filtered_limit = $wp_max_limit; 7464 $wp_max_limit = WP_MAX_MEMORY_LIMIT; 7465 $filtered_limit = $wp_max_limit; 7467 7466 7468 7467 switch ( $context ) { 7469 7468 case 'admin': … … function wp_raise_memory_limit( $context = 'admin' ) { 7523 7522 break; 7524 7523 } 7525 7524 7526 $filtered_limit_int = wp_convert_hr_to_bytes( $filtered_limit ); 7525 // Set the memory limit to the greatest of all the filtered value, the MAX limit, and the current limit. 7526 $new_limit = wp_ini_greater_quantity( $current_limit, WP_MAX_MEMORY_LIMIT ); 7527 $new_limit = wp_ini_greater_quantity( $filtered_limit, $new_limit ); 7527 7528 7528 if ( -1 === $filtered_limit_int || ( $filtered_limit_int > $wp_max_limit_int && $filtered_limit_int > $current_limit_int ) ) { 7529 if ( false !== ini_set( 'memory_limit', $filtered_limit ) ) { 7530 return $filtered_limit; 7531 } else { 7532 return false; 7533 } 7534 } elseif ( -1 === $wp_max_limit_int || $wp_max_limit_int > $current_limit_int ) { 7535 if ( false !== ini_set( 'memory_limit', $wp_max_limit ) ) { 7536 return $wp_max_limit; 7537 } else { 7538 return false; 7539 } 7529 // If we're already set at the greatest limit we don't need to change it. 7530 if ( 0 === wp_ini_quantity_cmp( $new_limit, $current_limit ) ) { 7531 return false; 7540 7532 } 7541 7533 7542 return false; 7534 // Otherwise attempt to set the new limit and return the new value if it succeeded. 7535 return false !== ini_set( 'memory_limit', $new_limit ) 7536 ? $new_limit 7537 : false; 7543 7538 } 7544 7539 7545 7540 /** -
src/wp-includes/load.php
diff --git a/src/wp-includes/load.php b/src/wp-includes/load.php index d4bc58b9c2..af2148b9f0 100644
a b 5 5 * @package WordPress 6 6 */ 7 7 8 require_once __DIR__ . '/php-compat.php'; 9 8 10 /** 9 11 * Return the HTTP protocol sent by the server. 10 12 * … … function is_ssl() { 1465 1467 * 1466 1468 * @since 2.3.0 1467 1469 * @since 4.6.0 Moved from media.php to load.php. 1470 * @deprecated 6.1.0 Use wp_ini_parse_quantity() or wp_hr_bytes() instead. 1468 1471 * 1469 1472 * @link https://www.php.net/manual/en/function.ini-get.php 1470 1473 * @link https://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes … … function is_ssl() { 1473 1476 * @return int An integer byte value. 1474 1477 */ 1475 1478 function wp_convert_hr_to_bytes( $value ) { 1479 _deprecated_function( __FUNCTION__, '6.1.0', 'wp_ini_parse_quantity' ); 1480 return wp_hr_bytes( $value ); 1481 } 1482 1483 /** 1484 * Parses a "human-readable" byte value into an integer. 1485 * 1486 * @since 6.1.0 1487 * 1488 * @param string $value Human-readable description of a byte size 1489 * @return int An integer byte value. 1490 */ 1491 function wp_hr_bytes( $value ) { 1476 1492 $value = strtolower( trim( $value ) ); 1477 1493 $bytes = (int) $value; 1478 1494 -
src/wp-includes/media.php
diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index caf8d247f5..51a6382f1e 100644
a b function wp_expand_dimensions( $example_width, $example_height, $max_width, $max 3787 3787 * @return int Allowed upload size. 3788 3788 */ 3789 3789 function wp_max_upload_size() { 3790 $u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) ); 3791 $p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) ); 3790 $upload_max_filesize = ini_get( 'upload_max_filesize' ); 3791 $post_max_size = ini_get( 'post_max_size' ); 3792 $max_upload = wp_ini_lesser_quantity( $upload_max_filesize, $post_max_size ); 3792 3793 3793 3794 /** 3794 3795 * Filters the maximum upload size allowed in php.ini. … … function wp_max_upload_size() { 3799 3800 * @param int $u_bytes Maximum upload filesize in bytes. 3800 3801 * @param int $p_bytes Maximum size of POST data in bytes. 3801 3802 */ 3802 return apply_filters( 'upload_size_limit', min( $u_bytes, $p_bytes ), $u_bytes, $p_bytes ); 3803 return apply_filters( 3804 'upload_size_limit', 3805 wp_ini_parse_quantity( $max_upload ), 3806 wp_ini_parse_quantity( $upload_max_filesize ), 3807 wp_ini_parse_quantity( $post_max_size ) 3808 ); 3803 3809 } 3804 3810 3805 3811 /** -
new file src/wp-includes/php-compat.php
diff --git a/src/wp-includes/php-compat.php b/src/wp-includes/php-compat.php new file mode 100644 index 0000000000..584bfa63a0
- + 1 <?php 2 3 defined( 'IS_32_BIT_SYSTEM' ) || define( 'IS_32_BIT_SYSTEM', 2147483647 === PHP_INT_MAX ); 4 defined( 'PHP_INT_MAX' ) || define( 'PHP_INT_MAX', IS_32_BIT_SYSTEM ? 2147483647 : 9223372036854775807 ); 5 defined( 'PHP_INT_MIN' ) || define( 'PHP_INT_MIN', IS_32_BIT_SYSTEM ? -2147483648 : -9223372036854775808 ); 6 7 /* 8 * Returns byte size represented in a numeric php.ini directive. 9 * 10 * Generally this can be used in combination with `ini_get( $option )` 11 * for values that accept a numeric "byte" size, such as `post_max_size`. 12 * It will return the value which PHP interprets from the "shorthand" 13 * syntax, such as "128m" being 128 MiB and "128mb" being 128 B. 14 * 15 * Since PHP 8.2 this may return inaccurate results if passed the value 16 * for the `memory_limit` INI directive as it uses the new unsigned 17 * parser. 18 * 19 * @param false|int|string $value 20 * @return int 21 */ 22 function wp_ini_parse_quantity( $value ) { 23 // A missing value is an implicit lack of limit, thus we return `0`, meaning "no limit." 24 if ( false === $value ) { 25 return 0; 26 } 27 28 /* 29 * Directly return pre-parsed values so we can repeatedly call 30 * this without tracking if we've already parsed a given value. 31 */ 32 if ( is_int( $value ) ) { 33 return $value; 34 } 35 36 /* 37 * Non-string inputs "fail" to no limit, because there's 38 * no limit we could ascribe to this invalid value. 39 */ 40 if ( ! is_string( $value ) ) { 41 return 0; 42 } 43 44 return ini_parse_quantity( $value ); 45 } 46 47 /** 48 * Returns larger of two php.ini directive quantity values. 49 * 50 * Example: 51 * wp_ini_greater_quantity( '256m', -1 ) === -1 52 * wp_ini_greater_quantity( '64K', '64') === '64K' 53 * wp_ini_greater_quantity( 1000, 2000 ) === 2000 54 * 55 * @param int|string|false $a Quantity value. 56 * @param int|string|false $b Quantity value. 57 * @return int|string|false Larger quantity value. 58 */ 59 function wp_ini_greater_quantity( $a, $b ) { 60 return wp_ini_quantity_cmp( $a, $b ) >= 0 ? $a : $b; 61 } 62 63 /** 64 * Returns smaller of two php.ini directive quantity values. 65 * 66 * Example: 67 * wp_ini_lesser_quantity( '256m', -1 ) === '256m' 68 * wp_ini_lesser_quantity( '64K', '64') === '64' 69 * wp_ini_lesser_quantity( 1000, 2000 ) === 1000 70 * 71 * @param int|string|false $a Quantity value. 72 * @param int|string|false $b Quantity value. 73 * @return int|string|false Smaller quantity value. 74 */ 75 function wp_ini_lesser_quantity( $a, $b ) { 76 return wp_ini_quantity_cmp( $a, $b ) <= 0 ? $a : $b; 77 } 78 79 /** 80 * Comparator for php.ini quantity values, can be used 81 * as the callback for functions such as `usort()`. 82 * 83 * Example: 84 * $a < $b => -1 85 * $a === $b => 0 86 * $a > $b => 1 87 * 88 * @param int|string|false $a Quantity being compared. 89 * @param int|string|false $b Quantity against which $a is compared. 90 * @return int 91 */ 92 function wp_ini_quantity_cmp( $a, $b ) { 93 $a_scalar = wp_ini_parse_quantity( $a ); 94 $b_scalar = wp_ini_parse_quantity( $b ); 95 96 if ( $a_scalar === $b_scalar ) { 97 return 0; 98 } 99 100 // No limit on $a means it's at least as large as any $b value. 101 if ( $a_scalar <= 0 ) { 102 return 1; 103 } 104 105 // No limit on $b means it's at least as large as any $a value. 106 if ( $b_scalar <= 0 ) { 107 return -1; 108 } 109 110 return $a_scalar > $b_scalar ? 1 : -1; 111 } 112 113 // ini_parse_quantity added to PHP in PHP 8.2 114 if ( ! function_exists( 'ini_parse_quantity' ) ) : 115 /** 116 * Returns quantity represented by a php.ini directive's "byte size shorthand." 117 * 118 * php.ini directives may use a string representation of a number of bytes 119 * or a "shorthand" byte size to reference larger values. Multiple numeric 120 * php.ini directive use these shorthands even when they don't refer to bytes. 121 * 122 * Example: 123 * 124 * ini_parse_quantity( "1m" ) == 1048576 125 * ini_parse_quantity( "2K" ) == 2048 // 2 * 1024 126 * ini_parse_quantity( "0.5g" ) == 0 127 * ini_parse_quantity( "14.6e-13g" ) == 15032385536 // 14 * 1024^3 128 * ini_parse_quantity( "-813k" ) == -832512; // -813 * 1024 129 * ini_parse_quantity( "boat" ) == 0; 130 * 131 * // This gives an answer, but it's _wrong_ because 132 * // the underlying mechanism in PHP overflowed and 133 * // the real return value depends on whether PHP 134 * // was built with 64-bit support. 135 * ini_parse_quantity( "9223372036854775807g" ) == ?? 136 * 137 * Notes: 138 * - Suffixes are specifically _the last character_ and case-insensitive. 139 * - Suffixes k/m/g intentionally report powers of 1024 to agree with PHP. 140 * - This function does not fail on invalid input; it returns `0` in such cses. 141 * - As noted in the PHP documentation, overflow behavior is unspecified and 142 * platform-dependant. Values that trigger overflow are likely wrong 143 * - In PHP 8.2+ this function may return an invalid count for shorthand values 144 * parsed with the new unsigned parser. Currently only affects "memory_limit" 145 * and only when the value overflows an unsigned integer on the platform. 146 * 147 * @since 6.1. 148 * 149 * @link https://www.php.net/manual/en/function.ini-get.php 150 * @link https://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes 151 152 * @param string $value Numeric string value possibly in "shorthand notation." 153 * @return int Parsed numeric value represented by given string. 154 */ 155 function ini_parse_quantity( $value ) { 156 /** 157 * Number of bytes in input string; because we're only assessing 7-bit 158 * ASCII/Unicode characters we can safely count bytes vs. needing to 159 * worry about code units, code points, or grapheme clusters. 160 * 161 * @var int 162 */ 163 $strlen = strlen( $value ); 164 165 /** @var int|float Numeric quantity represented by value string. */ 166 $scalar = 0; 167 168 /** @var int Sign of numeric quantity, either positive (1) or negative (-1). */ 169 $sign = 1; 170 171 /** 172 * Numeric base of digits determined by string prefix (e.g. "0x" or "0"). 173 * Must be 8 for octal, 10 for decimal, or 16 for hexadecimal. 174 * 175 * @var int 176 */ 177 $base = 10; 178 179 /** @var int Index into input string as we walk through it and analyze each character. */ 180 $i = 0; 181 182 /* 183 * Trim leading whitespace. 184 * 185 * We could also do this with `ltrim()` but that adds a needless 186 * string copy and makes it appear like we could add `+` to the 187 * list of values to trim, which we cannot, because that 188 * results in the wrong parse for strings with multiple 189 * `+` or `-` characters in a row. 190 */ 191 for ( ; $i < $strlen; $i++ ) { 192 $c = $value[ $i ]; 193 194 if ( ' ' === $c || "\t" === $c || "\r" === $c || "\v" === $c || "\f" === $c ) { 195 continue; 196 } 197 198 break; 199 } 200 201 // Handle optional sign indicator. 202 switch ( $value[ $i ] ) { 203 case '+': 204 $i++; 205 break; 206 207 case '-': 208 $sign = -1; 209 $i++; 210 break; 211 } 212 213 // Determine base for digit conversion, if not decimal. 214 $base_a = $i < $strlen ? $value[ $i ] : ''; 215 $base_b = $i + 1 < $strlen ? $value[ $i + 1 ] : ''; 216 217 if ( '0' === $base_a && ( 'x' === $base_b || 'X' === $base_b ) ) { 218 $base = 16; 219 $i += 2; 220 } else if ( '0' === $base_a && ctype_digit( $base_b ) ) { 221 $base = 8; 222 $i += 1; 223 } 224 225 // Trim leading zeros. 226 for ( ; $i < $strlen; $i++ ) { 227 if ( '0' !== $value[ $i ] ) { 228 break; 229 } 230 } 231 232 /** 233 * Numeric values for scanned digits. 234 * 235 * These are used to determine the decimal value the digit 236 * represents and whether it's an allowed character in 237 * the given base. It's allowed if its value is less 238 * than the base: e.g. '7' is allowed in octal (base 8) 239 * but '8' and '9' aren't because they are greater than 8. 240 * 241 * @var array 242 */ 243 $digits = array( 244 '0' => 0, 245 '1' => 1, 246 '2' => 2, 247 '3' => 3, 248 '4' => 4, 249 '5' => 5, 250 '6' => 6, 251 '7' => 7, 252 '8' => 8, 253 '9' => 9, 254 'A' => 10, 255 'a' => 10, 256 'B' => 11, 257 'b' => 11, 258 'C' => 12, 259 'c' => 12, 260 'D' => 13, 261 'd' => 13, 262 'E' => 14, 263 'e' => 14, 264 'F' => 15, 265 'f' => 15, 266 ); 267 268 // Build the scalar value by consuming the next sequence of contiguous digits. 269 for ( ; $i < $strlen; $i++ ) { 270 $c = $value[ $i ]; 271 272 /* 273 * Only digits recognized in this base system can be used. 274 * Once we find an unrecognized digit we abort and move 275 * on to the next step in parsing the size suffix. 276 */ 277 if ( ! isset( $digits[ $c ] ) || $digits[ $c ] >= $base ) { 278 break; 279 } 280 281 /* 282 * This is the step that computes our integer as we see new digits. 283 * 284 * Example: 285 * 4 = (0 * 10) + 4 286 * 45 = ((0 * 10 + 4) * 10) + 5 287 * 458 = ((0 * 10 + 4) * 10 + 5) * 10 + 8 288 */ 289 $scalar = $scalar * $base + $digits[ $c ]; 290 291 // Stop processing if we're already at the maximum magnitude for the sign. 292 if ( 293 ( $sign > 0 && $scalar > PHP_INT_MAX ) || 294 ( $sign < 0 && $scalar > -PHP_INT_MIN ) 295 ) { 296 break; 297 } 298 } 299 300 // Clamp the parsed digits to an integer value as PHP does internally. 301 if ( $sign > 0 && $scalar >= PHP_INT_MAX ) { 302 $scalar = PHP_INT_MAX; 303 } else if ( $sign < 0 && $scalar >= -PHP_INT_MIN ) { 304 $scalar = PHP_INT_MIN; 305 } else if ( $sign < 0 ) { 306 $scalar = -$scalar; 307 } 308 309 /* 310 * Do not use WP constants here (GB_IN_BYTES, MB_IN_BYTES, KB_IN_BYTES) 311 * since they are re-definable; PHP shorthand values are hard-coded 312 * in PHP itself and stay the same regardless of these constants. 313 * 314 * Note that we can overflow here, as happens in PHP itself. 315 * Overflow results will likely not match PHP's value, but 316 * will likely break in most cases anyway and so leaving 317 * this loose is the best we can do until we can read these 318 * values directly from PHP. 319 */ 320 switch ( $value[ $strlen - 1 ] ) { 321 case 'g': 322 case 'G': 323 $scalar *= 1073741824; // 1024^3 324 break; 325 326 case 'm': 327 case 'M': 328 $scalar *= 1048576; // 1024^2 329 break; 330 331 case 'k': 332 case 'K': 333 $scalar *= 1024; 334 break; 335 } 336 337 return (int) $scalar; 338 } 339 340 endif; -
tests/phpunit/tests/load/wpConvertHrToBytes.php
diff --git a/tests/phpunit/tests/load/wpConvertHrToBytes.php b/tests/phpunit/tests/load/wpConvertHrToBytes.php index 66f4d4329b..cf08e58761 100644
a b class Tests_Load_wpConvertHrToBytes extends WP_UnitTestCase { 44 44 array( '128m', 134217728 ), 45 45 array( '256M', 268435456 ), 46 46 array( '1g', 1073741824 ), 47 array( '128m ', 134217728 ), // Leading/trailing whitespace gets trimmed. 47 48 /** 49 * Leading/trailing whitespace gets trimmed. 50 * Note that this is not the value that PHP uses internally. 51 * PHP interprets the value as 128, not 128 MiB. 52 * 53 * @see wp_ini_parse_quantity() 54 */ 55 array( '128m ', 134217728 ), 48 56 array( '1024', 1024 ), // No letter will be interpreted as integer value. 49 57 50 58 // Edge cases. -
new file tests/phpunit/tests/php-compat/ini_parse_quantity.php
diff --git a/tests/phpunit/tests/php-compat/ini_parse_quantity.php b/tests/phpunit/tests/php-compat/ini_parse_quantity.php new file mode 100644 index 0000000000..5f6233615c
- + 1 <?php 2 3 /** 4 * Tests for PHP compatability functions. 5 * 6 * @group php-compat.php 7 * @covers ::wp_ini_parse_quantity 8 */ 9 class Tests_PHP_Compat_wpIniParseQuantity extends WP_UnitTestCase { 10 public function test_unset_limit_is_no_limit() { 11 $this->assertEquals( 0, wp_ini_parse_quantity( false ) ); 12 } 13 14 public function test_absent_limit_is_no_limit() { 15 $this->assertEquals( 0, wp_ini_parse_quantity( '' ) ); 16 } 17 18 public function test_unlimited_is_unlimited() { 19 $this->assertEquals( -1, wp_ini_parse_quantity( '-1' ) ); 20 } 21 22 public function test_unlimited_is_same_as_missing_limit() { 23 $this->assertEqual( '', wp_ini_greater_quantity( '', '-1' ) ); 24 $this->assertEqual( '-1', wp_ini_greater_quantity( '-1', '' ) ); 25 $this->assertEqual( '', wp_ini_lesser_quantity( '', '-1' ) ); 26 $this->assertEqual( '-1', wp_ini_lesser_quantity( '-1', '' ) ); 27 } 28 29 public function test_unlimited_is_greater_than_hard_limit() { 30 $this->assertEqual( 1, wp_ini_quantity_cmp( -1, 1348 ) ); 31 $this->assertEqual( 1, wp_ini_quantity_cmp( -1, '1348g' ) ); 32 $this->assertEqual( 1, wp_ini_quantity_cmp( '', 1348 ) ); 33 $this->assertEqual( 1, wp_ini_quantity_cmp( '', '1348g' ) ); 34 $this->assertEqual( 1, wp_ini_quantity_cmp( 0, 1348 ) ); 35 $this->assertEqual( 1, wp_ini_quantity_cmp( 0, '1348g' ) ); 36 $this->assertEqual( 1, wp_ini_quantity_cmp( false, 1348 ) ); 37 $this->assertEqual( 1, wp_ini_quantity_cmp( false, '1348g' ) ); 38 } 39 40 public function test_invalid_data_is_no_limit() { 41 $this->assertEquals( 0, wp_ini_parse_quantity( true ) ); 42 $this->assertEquals( 0, wp_ini_parse_quantity( false ) ); 43 $this->assertEquals( 0, wp_ini_parse_quantity( array( 1, 2, 3 ) ) ); 44 $this->assertEquals( 0, wp_ini_parse_quantity( new stdClass ) ); 45 } 46 47 public function test_returns_already_parsed_values() { 48 $this->assertEquals( 15, wp_ini_parse_quantity( 15 ) ); 49 $this->assertEquals( -1543, wp_ini_parse_quantity( -1543 ) ); 50 } 51 52 public function test_clamped_to_max_int_before_suffix() { 53 if ( IS_32_BIT_SYSTEM ) { 54 $this->assertEquals( PHP_INT_MAX, wp_ini_parse_quantity( '2147483648' ) ); 55 $this->assertEquals( PHP_INT_MIN, wp_ini_parse_quantity( '-2147483649' ) ); 56 } else { 57 $this->assertEquals( PHP_INT_MAX, wp_ini_parse_quantity( '9223372036854775808' ) ); 58 $this->assertEquals( PHP_INT_MIN, wp_ini_parse_quantity( '-9223372036854775809' ) ); 59 } 60 } 61 62 public function test_suffix_math_may_overflow() { 63 if ( IS_32_BIT_SYSTEM ) { 64 $this->assertNotEquals( PHP_INT_MAX, wp_ini_parse_quantity( '2147483648g' ) ); 65 $this->assertNotEquals( PHP_INT_MIN, wp_ini_parse_quantity( '-2147483648g' ) ); 66 } else { 67 $this->assertNotEquals( PHP_INT_MAX, wp_ini_parse_quantity( '9223372036854775807g' ) ); 68 $this->assertNotEquals( PHP_INT_MIN, wp_ini_parse_quantity( '-9223372036854775807g' ) ); 69 } 70 } 71 72 /** 73 * Tests converting numeric php.ini directive strings into their scalar equivalents. 74 * 75 * @ticket 55635 76 * 77 * @dataProvider data_php_numeric_strings 78 * 79 * @param $value 80 * @param $expected 81 */ 82 public function test_parse_matches_php_internal_value( $value, $expected ) { 83 $this->assertEquals( $expected, wp_ini_parse_quantity( $value ) ); 84 } 85 86 public function data_php_numeric_strings() { 87 return array( 88 // Decimal integer input. 89 array( '0', 0 ), 90 array( '100', 100 ), 91 array( '-14', -14 ), 92 93 // Octal integer input. 94 array( '0100', 64 ), 95 array( '-0654', -428 ), 96 97 // Hex input. 98 array( '0x14', 20 ), 99 array( '0X14', 20 ), 100 array( '-0xAA', -170 ), 101 102 // Size suffixes. 103 array( '1g', 1073741824 ), 104 array( '1gb', 0 ), 105 array( '32k', 32768 ), 106 array( '64K', 65536 ), 107 array( '07k', 7168 ), 108 array( '-0xF3d7m', -65455259648 ), 109 array( '128m', 134217728 ), 110 array( '128m ', 128 ), 111 array( '128mk', 131072 ), 112 array( '128km', 134217728 ), 113 array( '1.28 kmg', 1073741824 ), 114 array( '256M', 268435456 ), 115 116 // Leading characters. 117 array( ' 68', 68 ), 118 array( '+1', 1 ), 119 array( ' -0xdeadbeef', -3735928559 ), 120 array( ' 00000077', 63 ), 121 122 // Things that don't look valid but are still possible. 123 array( '', 0 ), 124 array( '3km', 3145728 ), 125 array( '1mg', 1073741824 ), 126 array( 'boat', 0 ), 127 array( '-14chairsk', -14336 ), 128 array( '0xt', 0 ), 129 array( '++3', 0 ), 130 array( '0x5ome 🅰🅱🅲 attack', 5120 ), 131 ); 132 } 133 }