Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions Zend/zend_ini.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,16 @@ ZEND_API zend_result zend_register_ini_entries_ex(const zend_ini_entry_def *ini_
zend_unregister_ini_entries_ex(module_number, module_type);
return FAILURE;
}

zend_string *prev_value = p->value;

if (((default_value = zend_get_configuration_directive(p->name)) != NULL) &&
(!p->on_modify || p->on_modify(p, Z_STR_P(default_value), p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP) == SUCCESS)) {

p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value)));
/* Skip assigning the value if the handler has already done so. */
if (p->value == prev_value) {
p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value)));
}
} else {
p->value = ini_entry->value ?
zend_string_init_interned(ini_entry->value, ini_entry->value_length, 1) : NULL;
Expand Down Expand Up @@ -389,14 +395,20 @@ ZEND_API zend_result zend_alter_ini_entry_ex(zend_string *name, zend_string *new
zend_hash_add_ptr(EG(modified_ini_directives), ini_entry->name, ini_entry);
}

zend_string *prev_value = ini_entry->value;
duplicate = zend_string_copy(new_value);

if (!ini_entry->on_modify
|| ini_entry->on_modify(ini_entry, duplicate, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage) == SUCCESS) {
if (modified && ini_entry->orig_value != ini_entry->value) { /* we already changed the value, free the changed value */
zend_string_release(ini_entry->value);
if (modified && ini_entry->orig_value != prev_value) { /* we already changed the value, free the changed value */
zend_string_release(prev_value);
}
/* Skip assigning the value if the handler has already done so. */
if (ini_entry->value == prev_value) {
ini_entry->value = duplicate;
} else {
zend_string_release(duplicate);
}
ini_entry->value = duplicate;
} else {
zend_string_release(duplicate);
return FAILURE;
Expand Down
41 changes: 40 additions & 1 deletion main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,22 @@ static PHP_INI_MH(OnChangeMemoryLimit)
} else {
value = Z_L(1)<<30; /* effectively, no limit */
}

/* If memory_limit exceeds max_memory_limit, warn and set to max_memory_limit instead. */
if (value > PG(max_memory_limit)) {
if (value != -1) {
zend_error(E_WARNING,
"Failed to set memory_limit to %zd bytes. Setting to max_memory_limit instead (currently: " ZEND_LONG_FMT " bytes)",
value, PG(max_memory_limit));
}

zend_ini_entry *max_mem_limit_ini = zend_hash_str_find_ptr(EG(ini_directives), ZEND_STRL("max_memory_limit"));
entry->value = zend_string_copy(max_mem_limit_ini->value);
PG(memory_limit) = PG(max_memory_limit);

return SUCCESS;
}

if (zend_set_memory_limit(value) == FAILURE) {
/* When the memory limit is reset to the original level during deactivation, we may be
* using more memory than the original limit while shutdown is still in progress.
Expand All @@ -347,6 +363,26 @@ static PHP_INI_MH(OnChangeMemoryLimit)
}
/* }}} */

static PHP_INI_MH(OnChangeMaxMemoryLimit)
{
size_t value;
if (new_value) {
value = zend_ini_parse_uquantity_warn(new_value, entry->name);
} else {
value = Z_L(1) << 30; /* effectively, no limit */
}

if (zend_set_memory_limit(value) == FAILURE) {
zend_error(E_ERROR, "Failed to set memory limit to %zd bytes (Current memory usage is %zd bytes)", value, zend_memory_usage(true));
return FAILURE;
}

PG(memory_limit) = value;
PG(max_memory_limit) = value;

return SUCCESS;
}

/* {{{ PHP_INI_MH */
static PHP_INI_MH(OnSetLogFilter)
{
Expand Down Expand Up @@ -810,7 +846,10 @@ PHP_INI_BEGIN()
STD_PHP_INI_BOOLEAN("mail.mixed_lf_and_crlf", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, mail_mixed_lf_and_crlf, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("mail.log", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMailLog, mail_log, php_core_globals, core_globals)
PHP_INI_ENTRY("browscap", NULL, PHP_INI_SYSTEM, OnChangeBrowscap)
PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit)

PHP_INI_ENTRY("max_memory_limit", "-1", PHP_INI_SYSTEM, OnChangeMaxMemoryLimit)
PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit)

PHP_INI_ENTRY("precision", "14", PHP_INI_ALL, OnSetPrecision)
PHP_INI_ENTRY("sendmail_from", NULL, PHP_INI_ALL, NULL)
PHP_INI_ENTRY("sendmail_path", DEFAULT_SENDMAIL_PATH, PHP_INI_SYSTEM, NULL)
Expand Down
1 change: 1 addition & 0 deletions main/php_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ struct _php_core_globals {
zend_long serialize_precision;

zend_long memory_limit;
zend_long max_memory_limit;
zend_long max_input_time;

char *error_log;
Expand Down
1 change: 1 addition & 0 deletions php.ini-development
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ max_input_time = 60
; Maximum amount of memory a script may consume
; https://php.net/memory-limit
memory_limit = 128M
max_memory_limit = -1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Error handling and logging ;
Expand Down
1 change: 1 addition & 0 deletions php.ini-production
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ max_input_time = 60
; Maximum amount of memory a script may consume
; https://php.net/memory-limit
memory_limit = 128M
max_memory_limit = -1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Error handling and logging ;
Expand Down
15 changes: 15 additions & 0 deletions tests/basic/gh17951_ini_parse_1.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
GH-17951 INI Parse 1
--CREDITS--
Frederik Milling Pytlick ([email protected])
--INI--
memory_limit=128M
max_memory_limit=-1
--FILE--
<?php
echo ini_get('max_memory_limit') . PHP_EOL;
echo ini_get('memory_limit') . PHP_EOL;
?>
--EXPECT--
-1
128M
15 changes: 15 additions & 0 deletions tests/basic/gh17951_ini_parse_2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
GH-17951 INI Parse 2
--CREDITS--
Frederik Milling Pytlick ([email protected])
--INI--
memory_limit=-1
max_memory_limit=-1
--FILE--
<?php
echo ini_get('max_memory_limit') . PHP_EOL;
echo ini_get('memory_limit') . PHP_EOL;
?>
--EXPECT--
-1
-1
15 changes: 15 additions & 0 deletions tests/basic/gh17951_ini_parse_3.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
GH-17951 INI Parse 3
--CREDITS--
Frederik Milling Pytlick ([email protected])
--INI--
memory_limit=128M
max_memory_limit=256M
--FILE--
<?php
echo ini_get('max_memory_limit') . PHP_EOL;
echo ini_get('memory_limit') . PHP_EOL;
?>
--EXPECT--
256M
128M
15 changes: 15 additions & 0 deletions tests/basic/gh17951_ini_parse_4.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
GH-17951 INI Parse 4
--CREDITS--
Frederik Milling Pytlick ([email protected])
--INI--
memory_limit=-1
max_memory_limit=128M
--FILE--
<?php
echo ini_get('max_memory_limit') . PHP_EOL;
echo ini_get('memory_limit') . PHP_EOL;
?>
--EXPECT--
128M
128M
16 changes: 16 additions & 0 deletions tests/basic/gh17951_ini_parse_5.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--TEST--
GH-17951 INI Parse 5
--CREDITS--
Frederik Milling Pytlick ([email protected])
--INI--
memory_limit=256M
max_memory_limit=128M
--FILE--
<?php
echo ini_get('max_memory_limit') . PHP_EOL;
echo ini_get('memory_limit') . PHP_EOL;
?>
--EXPECT--
Warning: Failed to set memory_limit to 268435456 bytes. Setting to max_memory_limit instead (currently: 134217728 bytes) in Unknown on line 0
128M
128M
14 changes: 14 additions & 0 deletions tests/basic/gh17951_runtime_change_1.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
GH-17951 Runtime Change 1
--CREDITS--
Frederik Milling Pytlick ([email protected])
--INI--
memory_limit=128M
max_memory_limit=512M
--FILE--
<?php
ini_set('memory_limit', '256M');
echo ini_get('memory_limit') . PHP_EOL;
?>
--EXPECT--
256M
14 changes: 14 additions & 0 deletions tests/basic/gh17951_runtime_change_2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
GH-17951 Runtime Change 2
--CREDITS--
Frederik Milling Pytlick ([email protected])
--INI--
memory_limit=128M
max_memory_limit=512M
--FILE--
<?php
ini_set('memory_limit', '512M');
echo ini_get('memory_limit') . PHP_EOL;
?>
--EXPECT--
512M
15 changes: 15 additions & 0 deletions tests/basic/gh17951_runtime_change_3.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
GH-17951 Runtime Change 3
--CREDITS--
Frederik Milling Pytlick ([email protected])
--INI--
memory_limit=128M
max_memory_limit=512M
--FILE--
<?php
ini_set('memory_limit', '1024M');
echo ini_get('memory_limit');
?>
--EXPECTF--
Warning: Failed to set memory_limit to 1073741824 bytes. Setting to max_memory_limit instead (currently: 536870912 bytes) in %s on line %d
512M
14 changes: 14 additions & 0 deletions tests/basic/gh17951_runtime_change_4.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
GH-17951 Runtime Change 4
--CREDITS--
Frederik Milling Pytlick ([email protected])
--INI--
memory_limit=128M
max_memory_limit=512M
--FILE--
<?php
ini_set('memory_limit', '-1');
echo ini_get('memory_limit');
?>
--EXPECT--
512M
19 changes: 19 additions & 0 deletions tests/basic/gh17951_runtime_change_5.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
GH-17951 Runtime Change 5
--CREDITS--
Frederik Milling Pytlick ([email protected])
--INI--
memory_limit=128M
max_memory_limit=512M
--FILE--
<?php
var_dump(ini_set('max_memory_limit', '128M'));
var_dump(ini_set('max_memory_limit', '256M'));
var_dump(ini_set('max_memory_limit', '512M'));
var_dump(ini_set('max_memory_limit', '-1'));
?>
--EXPECT--
bool(false)
bool(false)
bool(false)
bool(false)