1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 08:12:21 +01:00

Deprecate zend_atol() / add zend_ini_parse_quantity() (#7951)

Add zend_ini_parse_quantity() and deprecate zend_atol(), zend_atoi()

zend_atol() and zend_atoi() don't just do number parsing.
They also check for a 'K', 'M', or 'G' at the end of the string,
and multiply the parsed value out accordingly.

Unfortunately, they ignore any other non-numerics between the
numeric component and the last character in the string.
This means that numbers such as the following are both valid
and non-intuitive in their final output.

* "123KMG" is interpreted as "123G" -> 132070244352
* "123G " is interpreted as "123 " -> 123
* "123GB" is interpreted as "123B" -> 123
* "123 I like tacos." is also interpreted as "123." -> 123

Currently, in php-src these functions are used only for parsing ini values.

In this change we deprecate zend_atol(), zend_atoi(), and introduce a new
function with the same behavior, but with the ability to report invalid inputs
to the caller. The function's name also makes the behavior less unexpected:
zend_ini_parse_quantity().

Co-authored-by: Sara Golemon <pollita@php.net>
This commit is contained in:
Arnaud Le Blanc
2022-06-17 14:12:53 +02:00
committed by GitHub
parent 9458f5f2c8
commit efc8f0ebf8
25 changed files with 1666 additions and 22 deletions

View File

@@ -342,6 +342,91 @@ PHP 8.2 UPGRADE NOTES
11. Changes to INI File Handling
========================================
- Parsing of some ill-formatted values will now trigger a warning when this was
silently ignored before. Interpretation of these values is not changed, for
backwards compatibility. This affects the following settings:
. bcmath.scale
. com.code_page
. default_socket_timeout
. fiber.stack_size
. hard_timeout
. intl.error_level
. ldap.max_links
. max_input_nesting_level
. max_input_vars
. mbstring.regex_retry_limit
. mbstring.regex_stack_limit
. mysqli.allow_local_infile
. mysqli.allow_persistent
. mysqli.default_port
. mysqli.max_links
. mysqli.max_persistent
. mysqli.reconnect
. mysqli.rollback_on_cached_plink
. mysqlnd.log_mask
. mysqlnd.mempool_default_size
. mysqlnd.net_read_buffer_size
. mysqlnd.net_read_timeout
. oci8.default_prefetch
. oci8.max_persistent
. oci8.persistent_timeout
. oci8.ping_interval
. oci8.prefetch_lob_size
. oci8.privileged_connect
. oci8.statement_cache_size
. odbc.allow_persistent
. odbc.check_persistent
. odbc.defaultbinmode
. odbc.default_cursortype
. odbc.defaultlrl
. odbc.max_links
. odbc.max_persistent
. opcache.consistency_checks
. opcache.file_update_protection
. opcache.force_restart_timeout
. opcache.interned_strings_buffer
. opcache.jit_bisect_limit
. opcache.jit_blacklist_root_trace
. opcache.jit_blacklist_side_trace
. opcache.jit_debug
. opcache.jit_hot_func
. opcache.jit_hot_loop
. opcache.jit_hot_return
. opcache.jit_hot_side_exit
. opcache.jit_max_exit_counters
. opcache.jit_max_loop_unrolls
. opcache.jit_max_polymorphic_calls
. opcache.jit_max_recursive_calls
. opcache.jit_max_recursive_returns
. opcache.jit_max_root_traces
. opcache.jit_max_side_traces
. opcache.log_verbosity_level
. opcache.max_file_size
. opcache.opt_debug_level
. opcache.optimization_level
. opcache.revalidate_freq
. output_buffering
. pcre.backtrack_limit
. pcre.recursion_limit
. pgsql.max_links
. pgsql.max_persistent
. post_max_size
. realpath_cache_size
. realpath_cache_ttl
. session.cache_expire
. session.cookie_lifetime
. session.gc_divisor
. session.gc_maxlifetime
. session.gc_probability
. soap.wsdl_cache_limit
. soap.wsdl_cache_ttl
. unserialize_max_depth
. upload_max_filesize
. user_ini.cache_ttl
. xmlrpc_error_number
. zend.assertions
. zlib.output_compression_level
========================================
12. Windows Support
========================================

View File

@@ -29,6 +29,9 @@ PHP 8.2 INTERNALS UPGRADE NOTES
* A new ZEND_THREEWAY_COMPARE() macro has been introduced which does a
three-way comparison of two integers and returns -1, 0 or 1 if the LHS is
smaller, equal or larger than the RHS
* Deprecated zend_atoi() and zend_atol(). Use ZEND_STRTOL() for general purpose
string to long conversion, or a variant of zend_ini_parse_quantity() for
parsing ini quantities.
========================
2. Build system changes

View File

@@ -0,0 +1,897 @@
--TEST--
Test parsing of quantities
--EXTENSIONS--
zend_test
--FILE--
<?php
// This test checks valid formats do not throw any warnings.
foreach (['', ' '] as $leadingWS) {
foreach (['', '+', '-'] as $sign) {
foreach (['', ' '] as $midWS) {
foreach (['', 'K', 'k', 'M', 'm', 'G', 'g'] as $exp) {
foreach (['', ' '] as $trailingWS) {
// Decimal
$setting = sprintf('%s%s1%s%s%s',
$leadingWS, $sign, $midWS, $exp, $trailingWS);
printf("# \"%s\"\n", $setting);
var_dump(zend_test_zend_ini_parse_quantity($setting));
print "\n";
if ($exp !== 'g' && $exp !== 'G') { // Would overflow
// Octal
$setting = sprintf('%s%s0123%s%s%s',
$leadingWS, $sign, $midWS, $exp, $trailingWS);
printf("# \"%s\"\n", $setting);
var_dump(zend_test_zend_ini_parse_quantity($setting));
print "\n";
}
}
}
}
}
}
--EXPECT--
# "1"
int(1)
# "0123"
int(83)
# "1 "
int(1)
# "0123 "
int(83)
# "1K"
int(1024)
# "0123K"
int(84992)
# "1K "
int(1024)
# "0123K "
int(84992)
# "1k"
int(1024)
# "0123k"
int(84992)
# "1k "
int(1024)
# "0123k "
int(84992)
# "1M"
int(1048576)
# "0123M"
int(87031808)
# "1M "
int(1048576)
# "0123M "
int(87031808)
# "1m"
int(1048576)
# "0123m"
int(87031808)
# "1m "
int(1048576)
# "0123m "
int(87031808)
# "1G"
int(1073741824)
# "1G "
int(1073741824)
# "1g"
int(1073741824)
# "1g "
int(1073741824)
# "1 "
int(1)
# "0123 "
int(83)
# "1 "
int(1)
# "0123 "
int(83)
# "1 K"
int(1024)
# "0123 K"
int(84992)
# "1 K "
int(1024)
# "0123 K "
int(84992)
# "1 k"
int(1024)
# "0123 k"
int(84992)
# "1 k "
int(1024)
# "0123 k "
int(84992)
# "1 M"
int(1048576)
# "0123 M"
int(87031808)
# "1 M "
int(1048576)
# "0123 M "
int(87031808)
# "1 m"
int(1048576)
# "0123 m"
int(87031808)
# "1 m "
int(1048576)
# "0123 m "
int(87031808)
# "1 G"
int(1073741824)
# "1 G "
int(1073741824)
# "1 g"
int(1073741824)
# "1 g "
int(1073741824)
# "+1"
int(1)
# "+0123"
int(83)
# "+1 "
int(1)
# "+0123 "
int(83)
# "+1K"
int(1024)
# "+0123K"
int(84992)
# "+1K "
int(1024)
# "+0123K "
int(84992)
# "+1k"
int(1024)
# "+0123k"
int(84992)
# "+1k "
int(1024)
# "+0123k "
int(84992)
# "+1M"
int(1048576)
# "+0123M"
int(87031808)
# "+1M "
int(1048576)
# "+0123M "
int(87031808)
# "+1m"
int(1048576)
# "+0123m"
int(87031808)
# "+1m "
int(1048576)
# "+0123m "
int(87031808)
# "+1G"
int(1073741824)
# "+1G "
int(1073741824)
# "+1g"
int(1073741824)
# "+1g "
int(1073741824)
# "+1 "
int(1)
# "+0123 "
int(83)
# "+1 "
int(1)
# "+0123 "
int(83)
# "+1 K"
int(1024)
# "+0123 K"
int(84992)
# "+1 K "
int(1024)
# "+0123 K "
int(84992)
# "+1 k"
int(1024)
# "+0123 k"
int(84992)
# "+1 k "
int(1024)
# "+0123 k "
int(84992)
# "+1 M"
int(1048576)
# "+0123 M"
int(87031808)
# "+1 M "
int(1048576)
# "+0123 M "
int(87031808)
# "+1 m"
int(1048576)
# "+0123 m"
int(87031808)
# "+1 m "
int(1048576)
# "+0123 m "
int(87031808)
# "+1 G"
int(1073741824)
# "+1 G "
int(1073741824)
# "+1 g"
int(1073741824)
# "+1 g "
int(1073741824)
# "-1"
int(-1)
# "-0123"
int(-83)
# "-1 "
int(-1)
# "-0123 "
int(-83)
# "-1K"
int(-1024)
# "-0123K"
int(-84992)
# "-1K "
int(-1024)
# "-0123K "
int(-84992)
# "-1k"
int(-1024)
# "-0123k"
int(-84992)
# "-1k "
int(-1024)
# "-0123k "
int(-84992)
# "-1M"
int(-1048576)
# "-0123M"
int(-87031808)
# "-1M "
int(-1048576)
# "-0123M "
int(-87031808)
# "-1m"
int(-1048576)
# "-0123m"
int(-87031808)
# "-1m "
int(-1048576)
# "-0123m "
int(-87031808)
# "-1G"
int(-1073741824)
# "-1G "
int(-1073741824)
# "-1g"
int(-1073741824)
# "-1g "
int(-1073741824)
# "-1 "
int(-1)
# "-0123 "
int(-83)
# "-1 "
int(-1)
# "-0123 "
int(-83)
# "-1 K"
int(-1024)
# "-0123 K"
int(-84992)
# "-1 K "
int(-1024)
# "-0123 K "
int(-84992)
# "-1 k"
int(-1024)
# "-0123 k"
int(-84992)
# "-1 k "
int(-1024)
# "-0123 k "
int(-84992)
# "-1 M"
int(-1048576)
# "-0123 M"
int(-87031808)
# "-1 M "
int(-1048576)
# "-0123 M "
int(-87031808)
# "-1 m"
int(-1048576)
# "-0123 m"
int(-87031808)
# "-1 m "
int(-1048576)
# "-0123 m "
int(-87031808)
# "-1 G"
int(-1073741824)
# "-1 G "
int(-1073741824)
# "-1 g"
int(-1073741824)
# "-1 g "
int(-1073741824)
# " 1"
int(1)
# " 0123"
int(83)
# " 1 "
int(1)
# " 0123 "
int(83)
# " 1K"
int(1024)
# " 0123K"
int(84992)
# " 1K "
int(1024)
# " 0123K "
int(84992)
# " 1k"
int(1024)
# " 0123k"
int(84992)
# " 1k "
int(1024)
# " 0123k "
int(84992)
# " 1M"
int(1048576)
# " 0123M"
int(87031808)
# " 1M "
int(1048576)
# " 0123M "
int(87031808)
# " 1m"
int(1048576)
# " 0123m"
int(87031808)
# " 1m "
int(1048576)
# " 0123m "
int(87031808)
# " 1G"
int(1073741824)
# " 1G "
int(1073741824)
# " 1g"
int(1073741824)
# " 1g "
int(1073741824)
# " 1 "
int(1)
# " 0123 "
int(83)
# " 1 "
int(1)
# " 0123 "
int(83)
# " 1 K"
int(1024)
# " 0123 K"
int(84992)
# " 1 K "
int(1024)
# " 0123 K "
int(84992)
# " 1 k"
int(1024)
# " 0123 k"
int(84992)
# " 1 k "
int(1024)
# " 0123 k "
int(84992)
# " 1 M"
int(1048576)
# " 0123 M"
int(87031808)
# " 1 M "
int(1048576)
# " 0123 M "
int(87031808)
# " 1 m"
int(1048576)
# " 0123 m"
int(87031808)
# " 1 m "
int(1048576)
# " 0123 m "
int(87031808)
# " 1 G"
int(1073741824)
# " 1 G "
int(1073741824)
# " 1 g"
int(1073741824)
# " 1 g "
int(1073741824)
# " +1"
int(1)
# " +0123"
int(83)
# " +1 "
int(1)
# " +0123 "
int(83)
# " +1K"
int(1024)
# " +0123K"
int(84992)
# " +1K "
int(1024)
# " +0123K "
int(84992)
# " +1k"
int(1024)
# " +0123k"
int(84992)
# " +1k "
int(1024)
# " +0123k "
int(84992)
# " +1M"
int(1048576)
# " +0123M"
int(87031808)
# " +1M "
int(1048576)
# " +0123M "
int(87031808)
# " +1m"
int(1048576)
# " +0123m"
int(87031808)
# " +1m "
int(1048576)
# " +0123m "
int(87031808)
# " +1G"
int(1073741824)
# " +1G "
int(1073741824)
# " +1g"
int(1073741824)
# " +1g "
int(1073741824)
# " +1 "
int(1)
# " +0123 "
int(83)
# " +1 "
int(1)
# " +0123 "
int(83)
# " +1 K"
int(1024)
# " +0123 K"
int(84992)
# " +1 K "
int(1024)
# " +0123 K "
int(84992)
# " +1 k"
int(1024)
# " +0123 k"
int(84992)
# " +1 k "
int(1024)
# " +0123 k "
int(84992)
# " +1 M"
int(1048576)
# " +0123 M"
int(87031808)
# " +1 M "
int(1048576)
# " +0123 M "
int(87031808)
# " +1 m"
int(1048576)
# " +0123 m"
int(87031808)
# " +1 m "
int(1048576)
# " +0123 m "
int(87031808)
# " +1 G"
int(1073741824)
# " +1 G "
int(1073741824)
# " +1 g"
int(1073741824)
# " +1 g "
int(1073741824)
# " -1"
int(-1)
# " -0123"
int(-83)
# " -1 "
int(-1)
# " -0123 "
int(-83)
# " -1K"
int(-1024)
# " -0123K"
int(-84992)
# " -1K "
int(-1024)
# " -0123K "
int(-84992)
# " -1k"
int(-1024)
# " -0123k"
int(-84992)
# " -1k "
int(-1024)
# " -0123k "
int(-84992)
# " -1M"
int(-1048576)
# " -0123M"
int(-87031808)
# " -1M "
int(-1048576)
# " -0123M "
int(-87031808)
# " -1m"
int(-1048576)
# " -0123m"
int(-87031808)
# " -1m "
int(-1048576)
# " -0123m "
int(-87031808)
# " -1G"
int(-1073741824)
# " -1G "
int(-1073741824)
# " -1g"
int(-1073741824)
# " -1g "
int(-1073741824)
# " -1 "
int(-1)
# " -0123 "
int(-83)
# " -1 "
int(-1)
# " -0123 "
int(-83)
# " -1 K"
int(-1024)
# " -0123 K"
int(-84992)
# " -1 K "
int(-1024)
# " -0123 K "
int(-84992)
# " -1 k"
int(-1024)
# " -0123 k"
int(-84992)
# " -1 k "
int(-1024)
# " -0123 k "
int(-84992)
# " -1 M"
int(-1048576)
# " -0123 M"
int(-87031808)
# " -1 M "
int(-1048576)
# " -0123 M "
int(-87031808)
# " -1 m"
int(-1048576)
# " -0123 m"
int(-87031808)
# " -1 m "
int(-1048576)
# " -0123 m "
int(-87031808)
# " -1 G"
int(-1073741824)
# " -1 G "
int(-1073741824)
# " -1 g"
int(-1073741824)
# " -1 g "
int(-1073741824)

View File

@@ -0,0 +1,79 @@
--TEST--
Test parsing of quantities: errors
--EXTENSIONS--
zend_test
--FILE--
<?php
// This test checks invalid formats do throw warnings.
$tests = [
'K', # No digits
'1KM', # Multiple multipliers.
'1X', # Unknown multiplier.
'1.0K', # Non integral digits.
# Null bytes
" 123\x00K",
"\x00 123K",
" \x00123K",
" 123\x00K",
" 123K\x00",
" 123\x00",
];
foreach ($tests as $setting) {
printf("# \"%s\"\n", addcslashes($setting, "\0..\37!@\177..\377"));
var_dump(zend_test_zend_ini_parse_quantity($setting));
print "\n";
}
--EXPECTF--
# "K"
Warning: Invalid quantity "K": no valid leading digits, interpreting as "0" for backwards compatibility in %s%ezend_ini_parse_quantity_error.php on line %d
int(0)
# "1KM"
Warning: Invalid quantity "1KM", interpreting as "1M" for backwards compatibility in %s%ezend_ini_parse_quantity_error.php on line %d
int(1048576)
# "1X"
Warning: Invalid quantity "1X": unknown multipler "X", interpreting as "1" for backwards compatibility in %s%ezend_ini_parse_quantity_error.php on line %d
int(1)
# "1.0K"
Warning: Invalid quantity "1.0K", interpreting as "1K" for backwards compatibility in %s%ezend_ini_parse_quantity_error.php on line %d
int(1024)
# " 123\000K"
Warning: Invalid quantity " 123\x00K", interpreting as " 123K" for backwards compatibility in %s on line %d
int(125952)
# "\000 123K"
Warning: Invalid quantity "\x00 123K": no valid leading digits, interpreting as "0" for backwards compatibility in %s on line %d
int(0)
# " \000123K"
Warning: Invalid quantity " \x00123K": no valid leading digits, interpreting as "0" for backwards compatibility in %s on line %d
int(0)
# " 123\000K"
Warning: Invalid quantity " 123\x00K", interpreting as " 123K" for backwards compatibility in %s on line %d
int(125952)
# " 123K\000"
Warning: Invalid quantity " 123K\x00": unknown multipler "\x00", interpreting as " 123" for backwards compatibility in %s on line %d
int(123)
# " 123\000"
Warning: Invalid quantity " 123\x00": unknown multipler "\x00", interpreting as " 123" for backwards compatibility in %s on line %d
int(123)

View File

@@ -0,0 +1,13 @@
--TEST--
Test ini_set() with invalid quantity
--EXTENSIONS--
zend_test
--FILE--
<?php
var_dump(ini_set("zend_test.quantity_value", "1MB"));
var_dump(ini_get("zend_test.quantity_value"));
--EXPECTF--
Warning: Invalid "zend_test.quantity_value" setting. Invalid quantity "1MB": unknown multipler "B", interpreting as "1" for backwards compatibility in %s on line %d
string(1) "0"
string(3) "1MB"

View File

@@ -0,0 +1,13 @@
--TEST--
Test ini setting with invalid quantity
--EXTENSIONS--
zend_test
--INI--
zend_test.quantity_value=1MB
--FILE--
<?php
var_dump(ini_get("zend_test.quantity_value"));
--EXPECTF--
Warning: Invalid "zend_test.quantity_value" setting. Invalid quantity "1MB": unknown multipler "B", interpreting as "1" for backwards compatibility in %s on line %d
string(3) "1MB"

View File

@@ -0,0 +1,101 @@
--TEST--
Test zend_ini_parse_quantity() overflow handling
--EXTENSIONS--
zend_test
--FILE--
<?php
function increment(string $s): string {
if (strlen($s) === 0) {
return '1';
}
$digit = intval($s[strlen($s)-1]);
$prefix = substr($s, 0, -1);
if ($digit === 9) {
return increment($prefix) . '0';
}
return $prefix . strval($digit+1);
}
function decrement(string $s): string {
assert($s[0] === '-');
return '-' . increment(substr($s, 1));
}
$tests = [
'No overflow 001' => '0',
'No overflow 002' => '1',
'No overflow 003' => '100',
'No overflow 004' => strval(PHP_INT_MAX),
'No overflow 005' => strval(PHP_INT_MIN),
'No overflow 006' => '2K',
'No overflow 007' => '-2K',
'Subject overflow 001' => increment(strval(PHP_INT_MAX)),
'Subject overflow 002' => decrement(strval(PHP_INT_MIN)),
'Multiplier overflow 001' => strval(PHP_INT_MAX).'K',
'Multiplier overflow 002' => strval(PHP_INT_MIN).'K',
];
foreach ($tests as $name => $value) {
printf("# %s: \"%s\"\n", $name, $value);
printf("%d\n", zend_test_zend_ini_parse_quantity($value));
print "\n";
print "----------\n";
}
--EXPECTF--
# No overflow 001: "0"
0
----------
# No overflow 002: "1"
1
----------
# No overflow 003: "100"
100
----------
# No overflow 004: "%d"
%d
----------
# No overflow 005: "-%d"
-%d
----------
# No overflow 006: "2K"
2048
----------
# No overflow 007: "-2K"
-2048
----------
# Subject overflow 001: "%d"
Warning: Invalid quantity "%d": value is out of range, using overflow result for backwards compatibility in %s on line %d
%s
----------
# Subject overflow 002: "-%d"
Warning: Invalid quantity "-%d": value is out of range, using overflow result for backwards compatibility in %s on line %d
%s
----------
# Multiplier overflow 001: "%dK"
Warning: Invalid quantity "%dK": value is out of range, using overflow result for backwards compatibility in %s on line %d
%s
----------
# Multiplier overflow 002: "-%dK"
Warning: Invalid quantity "-%dK": value is out of range, using overflow result for backwards compatibility in %s on line %d
%s
----------

View File

@@ -0,0 +1,117 @@
--TEST--
Test zend_ini_parse_uquantity() overflow handling
--EXTENSIONS--
zend_test
--FILE--
<?php
$tests = [
'No overflow 001' => '0',
'No overflow 002' => '1',
'No overflow 003' => '100',
'No overflow 004' => strval(PHP_INT_MAX),
'No overflow 005' => '2K',
'No overflow 006' => '-1',
'No overflow 007' => ' -1',
'No overflow 008' => '-1 ',
'No overflow 009' => ' -1 ',
'Subject overflow 001' => base_convert(str_repeat('1', PHP_INT_SIZE*8+1), 2, 10),
'Subject overflow 002' => '-'.base_convert(str_repeat('1', PHP_INT_SIZE*8+1), 2, 10),
'Subject overflow 003' => strval(PHP_INT_MIN),
'Subject overflow 004' => '-2',
'Subject overflow 005' => '-1K',
'Subject overflow 006' => '-1 K',
'Multiplier overflow 001' => strval(PHP_INT_MAX).'K',
];
foreach ($tests as $name => $value) {
printf("# %s: \"%s\"\n", $name, $value);
printf("%u\n", zend_test_zend_ini_parse_uquantity($value));
print "\n";
print "----------\n";
}
printf("# zend_test_zend_ini_parse_uquantity(\"-1\") === -1\n");
var_dump(zend_test_zend_ini_parse_uquantity("-1") === -1);
--EXPECTF--
# No overflow 001: "0"
0
----------
# No overflow 002: "1"
1
----------
# No overflow 003: "100"
100
----------
# No overflow 004: "%d"
%d
----------
# No overflow 005: "2K"
2048
----------
# No overflow 006: "-1"
%d
----------
# No overflow 007: " -1"
%d
----------
# No overflow 008: "-1 "
%d
----------
# No overflow 009: " -1 "
%d
----------
# Subject overflow 001: "%d"
Warning: Invalid quantity "%d": value is out of range, using overflow result for backwards compatibility in %s on line %d
%d
----------
# Subject overflow 002: "-%d"
Warning: Invalid quantity "-%d": value is out of range, using overflow result for backwards compatibility in %s on line %d
%d
----------
# Subject overflow 003: "-%d"
Warning: Invalid quantity "-%d": value is out of range, using overflow result for backwards compatibility in %s on line %d
%d
----------
# Subject overflow 004: "-2"
Warning: Invalid quantity "-2": value is out of range, using overflow result for backwards compatibility in %s on line %d
%d
----------
# Subject overflow 005: "-1K"
Warning: Invalid quantity "-1K": value is out of range, using overflow result for backwards compatibility in %s on line %d
%d
----------
# Subject overflow 006: "-1 K"
Warning: Invalid quantity "-1 K": value is out of range, using overflow result for backwards compatibility in %s on line %d
%d
----------
# Multiplier overflow 001: "%dK"
Warning: Invalid quantity "%dK": value is out of range, using overflow result for backwards compatibility in %s on line %d
%d
----------
# zend_test_zend_ini_parse_uquantity("-1") === -1
bool(true)

View File

@@ -146,7 +146,7 @@ static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */
{
zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name);
if (stage != ZEND_INI_STAGE_STARTUP &&
stage != ZEND_INI_STAGE_SHUTDOWN &&
@@ -176,7 +176,7 @@ static ZEND_INI_MH(OnSetExceptionStringParamMaxLen) /* {{{ */
static ZEND_INI_MH(OnUpdateFiberStackSize) /* {{{ */
{
if (new_value) {
EG(fiber_stack_size) = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
EG(fiber_stack_size) = zend_ini_parse_quantity_warn(new_value, entry->name);
} else {
EG(fiber_stack_size) = ZEND_FIBER_DEFAULT_C_STACK_SIZE;
}

View File

@@ -24,12 +24,17 @@
#include "zend_operators.h"
#include "zend_strtod.h"
#include "zend_modules.h"
#include "zend_smart_str.h"
static HashTable *registered_zend_ini_directives;
#define NO_VALUE_PLAINTEXT "no value"
#define NO_VALUE_HTML "<i>no value</i>"
static inline bool zend_is_whitespace(char c) {
return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f';
}
/*
* hash_apply functions
*/
@@ -536,6 +541,207 @@ ZEND_API bool zend_ini_parse_bool(zend_string *str)
}
}
typedef enum {
ZEND_INI_PARSE_QUANTITY_SIGNED,
ZEND_INI_PARSE_QUANTITY_UNSIGNED,
} zend_ini_parse_quantity_signed_result_t;
static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_parse_quantity_signed_result_t signed_result, zend_string **errstr) /* {{{ */
{
char *digits_end = NULL;
char *str = ZSTR_VAL(value);
char *str_end = &str[ZSTR_LEN(value)];
char *digits = str;
bool overflow = false;
zend_ulong factor;
smart_str invalid = {0};
smart_str interpreted = {0};
smart_str chr = {0};
/* Ignore leading whitespace. ZEND_STRTOL() also skips leading whitespaces,
* but we need the position of the first non-whitespace later. */
while (digits < str_end && zend_is_whitespace(*digits)) ++digits;
/* Ignore trailing whitespace */
while (digits < str_end && zend_is_whitespace(*(str_end-1))) --str_end;
if (digits == str_end) {
*errstr = NULL;
return 0;
}
zend_ulong retval;
errno = 0;
if (signed_result == ZEND_INI_PARSE_QUANTITY_SIGNED) {
retval = (zend_ulong) ZEND_STRTOL(digits, &digits_end, 0);
} else {
retval = ZEND_STRTOUL(digits, &digits_end, 0);
}
if (errno == ERANGE) {
overflow = true;
} else if (signed_result == ZEND_INI_PARSE_QUANTITY_UNSIGNED) {
/* ZEND_STRTOUL() does not report a range error when the subject starts
* with a minus sign, so we check this here. Ignore "-1" as it is
* commonly used as max value, for instance in memory_limit=-1. */
if (digits[0] == '-' && !(digits_end - digits == 2 && digits_end == str_end && digits[1] == '1')) {
overflow = true;
}
}
if (UNEXPECTED(digits_end == digits)) {
/* No leading digits */
/* Escape the string to avoid null bytes and to make non-printable chars
* visible */
smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value));
smart_str_0(&invalid);
*errstr = zend_strpprintf(0, "Invalid quantity \"%s\": no valid leading digits, interpreting as \"0\" for backwards compatibility",
ZSTR_VAL(invalid.s));
smart_str_free(&invalid);
return 0;
}
/* Allow for whitespace between integer portion and any suffix character */
while (digits_end < str_end && zend_is_whitespace(*digits_end)) ++digits_end;
/* No exponent suffix. */
if (digits_end == str_end) {
goto end;
}
switch (*(str_end-1)) {
case 'g':
case 'G':
factor = 1<<30;
break;
case 'm':
case 'M':
factor = 1<<20;
break;
case 'k':
case 'K':
factor = 1<<10;
break;
default:
/* Unknown suffix */
smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value));
smart_str_0(&invalid);
smart_str_append_escaped(&interpreted, str, digits_end - str);
smart_str_0(&interpreted);
smart_str_append_escaped(&chr, str_end-1, 1);
smart_str_0(&chr);
*errstr = zend_strpprintf(0, "Invalid quantity \"%s\": unknown multipler \"%s\", interpreting as \"%s\" for backwards compatibility",
ZSTR_VAL(invalid.s), ZSTR_VAL(chr.s), ZSTR_VAL(interpreted.s));
smart_str_free(&invalid);
smart_str_free(&interpreted);
smart_str_free(&chr);
return retval;
}
if (!overflow) {
if (signed_result == ZEND_INI_PARSE_QUANTITY_SIGNED) {
zend_long sretval = (zend_long)retval;
if (sretval > 0) {
overflow = (zend_long)retval > ZEND_LONG_MAX / (zend_long)factor;
} else {
overflow = (zend_long)retval < ZEND_LONG_MIN / (zend_long)factor;
}
} else {
overflow = retval > ZEND_ULONG_MAX / factor;
}
}
retval *= factor;
if (UNEXPECTED(digits_end != str_end-1)) {
/* More than one character in suffix */
smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value));
smart_str_0(&invalid);
smart_str_append_escaped(&interpreted, str, digits_end - str);
smart_str_0(&interpreted);
smart_str_append_escaped(&chr, str_end-1, 1);
smart_str_0(&chr);
*errstr = zend_strpprintf(0, "Invalid quantity \"%s\", interpreting as \"%s%s\" for backwards compatibility",
ZSTR_VAL(invalid.s), ZSTR_VAL(interpreted.s), ZSTR_VAL(chr.s));
smart_str_free(&invalid);
smart_str_free(&interpreted);
smart_str_free(&chr);
return retval;
}
end:
if (UNEXPECTED(overflow)) {
smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value));
smart_str_0(&invalid);
/* Not specifying the resulting value here because the caller may make
* additional conversions. Not specifying the allowed range
* because the caller may do narrower range checks. */
*errstr = zend_strpprintf(0, "Invalid quantity \"%s\": value is out of range, using overflow result for backwards compatibility",
ZSTR_VAL(invalid.s));
smart_str_free(&invalid);
smart_str_free(&interpreted);
smart_str_free(&chr);
return retval;
}
*errstr = NULL;
return retval;
}
/* }}} */
ZEND_API zend_long zend_ini_parse_quantity(zend_string *value, zend_string **errstr) /* {{{ */
{
return (zend_long) zend_ini_parse_quantity_internal(value, ZEND_INI_PARSE_QUANTITY_SIGNED, errstr);
}
/* }}} */
ZEND_API zend_ulong zend_ini_parse_uquantity(zend_string *value, zend_string **errstr) /* {{{ */
{
return zend_ini_parse_quantity_internal(value, ZEND_INI_PARSE_QUANTITY_UNSIGNED, errstr);
}
/* }}} */
ZEND_API zend_long zend_ini_parse_quantity_warn(zend_string *value, zend_string *setting) /* {{{ */
{
zend_string *errstr;
zend_long retval = zend_ini_parse_quantity(value, &errstr);
if (errstr) {
zend_error(E_WARNING, "Invalid \"%s\" setting. %s", ZSTR_VAL(setting), ZSTR_VAL(errstr));
zend_string_release(errstr);
}
return retval;
}
/* }}} */
ZEND_API zend_long zend_ini_parse_uquantity_warn(zend_string *value, zend_string *setting) /* {{{ */
{
zend_string *errstr;
zend_long retval = zend_ini_parse_uquantity(value, &errstr);
if (errstr) {
zend_error(E_WARNING, "Invalid \"%s\" setting. %s", ZSTR_VAL(setting), ZSTR_VAL(errstr));
zend_string_release(errstr);
}
return retval;
}
/* }}} */
ZEND_INI_DISP(zend_ini_boolean_displayer_cb) /* {{{ */
{
int value;
@@ -624,14 +830,14 @@ ZEND_API ZEND_INI_MH(OnUpdateBool) /* {{{ */
ZEND_API ZEND_INI_MH(OnUpdateLong) /* {{{ */
{
zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
*p = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
*p = zend_ini_parse_quantity_warn(new_value, entry->name);
return SUCCESS;
}
/* }}} */
ZEND_API ZEND_INI_MH(OnUpdateLongGEZero) /* {{{ */
{
zend_long tmp = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
zend_long tmp = zend_ini_parse_quantity_warn(new_value, entry->name);
if (tmp < 0) {
return FAILURE;
}

View File

@@ -90,6 +90,52 @@ ZEND_API char *zend_ini_string_ex(const char *name, size_t name_length, int orig
ZEND_API zend_string *zend_ini_get_value(zend_string *name);
ZEND_API bool zend_ini_parse_bool(zend_string *str);
/**
* Parses an ini quantity
*
* The value parameter must be a string in the form
*
* sign? digits ws* multipler?
*
* with
*
* sign: [+-]
* digit: [0-9]
* digits: digit+
* ws: [ \t\n\r\v\f]
* multipler: [KMG]
*
* Leading and trailing whitespaces are ignored.
*
* If the string is empty or consists only of only whitespaces, 0 is returned.
*
* Digits is parsed as decimal unless the first digit is '0', in which case
* digits is parsed as octal.
*
* The multiplier is case-insensitive. K, M, and G multiply the quantity by
* 2**10, 2**20, and 2**30, respectively.
*
* For backwards compatibility, ill-formatted values are handled as follows:
* - No leading digits: value is treated as '0'
* - Invalid multiplier: multiplier is ignored
* - Invalid characters between digits and multiplier: invalid characters are
* ignored
* - Integer overflow: The result of the overflow is returned
*
* In any of these cases an error string is stored in *errstr (caller must
* release it), otherwise *errstr is set to NULL.
*/
ZEND_API zend_long zend_ini_parse_quantity(zend_string *value, zend_string **errstr);
/**
* Unsigned variant of zend_ini_parse_quantity
*/
ZEND_API zend_ulong zend_ini_parse_uquantity(zend_string *value, zend_string **errstr);
ZEND_API zend_long zend_ini_parse_quantity_warn(zend_string *value, zend_string *setting);
ZEND_API zend_long zend_ini_parse_uquantity_warn(zend_string *value, zend_string *setting);
ZEND_API zend_result zend_ini_register_displayer(const char *name, uint32_t name_length, void (*displayer)(zend_ini_entry *ini_entry, int type));
ZEND_API ZEND_INI_DISP(zend_ini_boolean_displayer_cb);

View File

@@ -118,7 +118,7 @@ ZEND_API const unsigned char zend_toupper_map[256] = {
0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
};
@@ -136,7 +136,7 @@ ZEND_API const unsigned char zend_toupper_map[256] = {
zend_binary_strncasecmp
*/
ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len) /* {{{ */
static zend_long ZEND_FASTCALL zend_atol_internal(const char *str, size_t str_len) /* {{{ */
{
if (!str_len) {
str_len = strlen(str);
@@ -168,9 +168,14 @@ ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len) /* {
}
/* }}} */
ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len)
{
return zend_atol_internal(str, str_len);
}
ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, size_t str_len)
{
return (int) zend_atol(str, str_len);
return (int) zend_atol_internal(str, str_len);
}
/* {{{ convert_object_to_type: dst will be either ctype or UNDEF */

View File

@@ -468,8 +468,11 @@ ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable
ZEND_API int ZEND_FASTCALL zend_compare_arrays(zval *a1, zval *a2);
ZEND_API int ZEND_FASTCALL zend_compare_objects(zval *o1, zval *o2);
ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, size_t str_len);
ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len);
/** Deprecatd in favor of ZEND_STRTOL() */
ZEND_ATTRIBUTE_DEPRECATED ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, size_t str_len);
/** Deprecatd in favor of ZEND_STRTOL() */
ZEND_ATTRIBUTE_DEPRECATED ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len);
#define convert_to_null_ex(zv) convert_to_null(zv)
#define convert_to_boolean_ex(zv) convert_to_boolean(zv)

View File

@@ -62,7 +62,7 @@ ZEND_INI_MH(OnUpdateScale)
int *p;
zend_long tmp;
tmp = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
tmp = zend_ini_parse_quantity_warn(new_value, entry->name);
if (tmp < 0 || tmp > INT_MAX) {
return FAILURE;
}

View File

@@ -3,7 +3,7 @@ Bug #71843 (null ptr deref ZEND_RETURN_SPEC_CONST_HANDLER (zend_vm_execute.h:347
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=0xFFFFBFFF
opcache.optimization_level=0x7FFFBFFF
--EXTENSIONS--
opcache
--FILE--

View File

@@ -3,7 +3,7 @@ Bug #74431 - foreach infinite loop
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=0xffffffff
opcache.optimization_level=0x7fffffff
--EXTENSIONS--
opcache
--FILE--

View File

@@ -165,7 +165,7 @@ static ZEND_INI_MH(OnUpdateJit)
static ZEND_INI_MH(OnUpdateJitDebug)
{
zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name);
if (zend_jit_debug_config(*p, val, stage) == SUCCESS) {
*p = val;
@@ -176,7 +176,7 @@ static ZEND_INI_MH(OnUpdateJitDebug)
static ZEND_INI_MH(OnUpdateCounter)
{
zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name);
if (val >= 0 && val < 256) {
zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
*p = val;
@@ -188,7 +188,7 @@ static ZEND_INI_MH(OnUpdateCounter)
static ZEND_INI_MH(OnUpdateUnrollC)
{
zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name);
if (val > 0 && val < ZEND_JIT_TRACE_MAX_CALL_DEPTH) {
zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
*p = val;
@@ -201,7 +201,7 @@ static ZEND_INI_MH(OnUpdateUnrollC)
static ZEND_INI_MH(OnUpdateUnrollR)
{
zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name);
if (val >= 0 && val < ZEND_JIT_TRACE_MAX_RET_DEPTH) {
zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
*p = val;
@@ -214,7 +214,7 @@ static ZEND_INI_MH(OnUpdateUnrollR)
static ZEND_INI_MH(OnUpdateUnrollL)
{
zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name);
if (val > 0 && val < ZEND_JIT_TRACE_MAX_LOOPS_UNROLL) {
zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
*p = val;

View File

@@ -2506,8 +2506,9 @@ static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int cal
break;
}
/* entry in the form x[a]=b where x might need to be an array index */
if (!(Z_STRLEN_P(arg1) > 1 && Z_STRVAL_P(arg1)[0] == '0') && is_numeric_string(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), NULL, NULL, 0) == IS_LONG) {
zend_ulong key = (zend_ulong) zend_atol(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1));
zend_ulong key = (zend_ulong) ZEND_STRTOUL(Z_STRVAL_P(arg1), NULL, 0);
if ((find_hash = zend_hash_index_find(Z_ARRVAL_P(arr), key)) == NULL) {
array_init(&hash);
find_hash = zend_hash_index_add_new(Z_ARRVAL_P(arr), key, &hash);

View File

@@ -0,0 +1,23 @@
--TEST--
parse_ini_string with numeric entry name
--FILE--
<?php
var_dump(parse_ini_string("
1[]=1
2M[]=2
"));
--EXPECT--
array(2) {
[1]=>
array(1) {
[0]=>
string(1) "1"
}
["2M"]=>
array(1) {
[0]=>
string(1) "2"
}
}

View File

@@ -53,6 +53,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
int register_passes;
bool print_stderr_mshutdown;
zend_test_fiber *active_fiber;
zend_long quantity_value;
ZEND_END_MODULE_GLOBALS(zend_test)
extern ZEND_DECLARE_MODULE_GLOBALS(zend_test)

View File

@@ -380,6 +380,40 @@ static ZEND_FUNCTION(zend_get_unit_enum)
RETURN_OBJ_COPY(zend_enum_get_case_cstr(zend_test_unit_enum, "Foo"));
}
static ZEND_FUNCTION(zend_test_zend_ini_parse_quantity)
{
zend_string *str;
zend_string *errstr;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STR(str)
ZEND_PARSE_PARAMETERS_END();
RETVAL_LONG(zend_ini_parse_quantity(str, &errstr));
if (errstr) {
zend_error(E_WARNING, "%s", ZSTR_VAL(errstr));
zend_string_release(errstr);
}
}
static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity)
{
zend_string *str;
zend_string *errstr;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STR(str)
ZEND_PARSE_PARAMETERS_END();
RETVAL_LONG((zend_long)zend_ini_parse_uquantity(str, &errstr));
if (errstr) {
zend_error(E_WARNING, "%s", ZSTR_VAL(errstr));
zend_string_release(errstr);
}
}
static ZEND_FUNCTION(namespaced_func)
{
ZEND_PARSE_PARAMETERS_NONE();
@@ -571,6 +605,7 @@ PHP_INI_BEGIN()
STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals)
STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals)
STD_PHP_INI_BOOLEAN("zend_test.print_stderr_mshutdown", "0", PHP_INI_SYSTEM, OnUpdateBool, print_stderr_mshutdown, zend_zend_test_globals, zend_test_globals)
STD_PHP_INI_ENTRY("zend_test.quantity_value", "0", PHP_INI_ALL, OnUpdateLong, quantity_value, zend_zend_test_globals, zend_test_globals)
PHP_INI_END()
void (*old_zend_execute_ex)(zend_execute_data *execute_data);
@@ -768,7 +803,10 @@ ZEND_GET_MODULE(zend_test)
/* The important part here is the ZEND_FASTCALL. */
PHP_ZEND_TEST_API int ZEND_FASTCALL bug78270(const char *str, size_t str_len)
{
return (int) zend_atol(str, str_len);
char * copy = zend_strndup(str, str_len);
int r = (int) ZEND_ATOL(copy);
free(copy);
return r;
}
PHP_ZEND_TEST_API struct bug79096 bug79096(void)

View File

@@ -125,6 +125,9 @@ namespace {
function zend_get_current_func_name(): string {}
function zend_call_method(object|string $obj_or_class, string $method, mixed $arg1 = UNKNOWN, mixed $arg2 = UNKNOWN): mixed {}
function zend_test_zend_ini_parse_quantity(string $str): int {}
function zend_test_zend_ini_parse_uquantity(string $str): int {}
}
namespace ZendTestNS {

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 2d42ea64a5114eae618a6dfb642c2640f568f5db */
* Stub hash: 1a23b7473e5b4525352445545c6b3ab374c4e949 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
@@ -85,6 +85,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_call_method, 0, 2, IS_MIXED
ZEND_ARG_TYPE_INFO(0, arg2, IS_MIXED, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_zend_ini_parse_quantity, 0, 1, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0)
ZEND_END_ARG_INFO()
#define arginfo_zend_test_zend_ini_parse_uquantity arginfo_zend_test_zend_ini_parse_quantity
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ZendTestNS2_ZendSubNS_namespaced_func, 0, 0, _IS_BOOL, 0)
ZEND_END_ARG_INFO()
@@ -146,6 +152,8 @@ static ZEND_FUNCTION(zend_get_unit_enum);
static ZEND_FUNCTION(zend_test_parameter_with_attribute);
static ZEND_FUNCTION(zend_get_current_func_name);
static ZEND_FUNCTION(zend_call_method);
static ZEND_FUNCTION(zend_test_zend_ini_parse_quantity);
static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity);
static ZEND_FUNCTION(namespaced_func);
static ZEND_METHOD(_ZendTestClass, is_object);
static ZEND_METHOD(_ZendTestClass, __toString);
@@ -186,6 +194,8 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(zend_test_parameter_with_attribute, arginfo_zend_test_parameter_with_attribute)
ZEND_FE(zend_get_current_func_name, arginfo_zend_get_current_func_name)
ZEND_FE(zend_call_method, arginfo_zend_call_method)
ZEND_FE(zend_test_zend_ini_parse_quantity, arginfo_zend_test_zend_ini_parse_quantity)
ZEND_FE(zend_test_zend_ini_parse_uquantity, arginfo_zend_test_zend_ini_parse_uquantity)
ZEND_NS_FE("ZendTestNS2\\ZendSubNS", namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func)
ZEND_FE_END
};

View File

@@ -1277,7 +1277,7 @@ static PHP_INI_MH(OnUpdate_zlib_output_compression)
} else if (zend_string_equals_literal_ci(new_value, "on")) {
int_value = 1;
} else {
int_value = zend_atoi(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
int_value = (int) zend_ini_parse_quantity_warn(new_value, entry->name);
}
ini_value = zend_ini_string("output_handler", sizeof("output_handler"), 0);

View File

@@ -263,7 +263,7 @@ static PHP_INI_MH(OnChangeMemoryLimit)
{
size_t value;
if (new_value) {
value = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
value = zend_ini_parse_uquantity_warn(new_value, entry->name);
} else {
value = Z_L(1)<<30; /* effectively, no limit */
}