Skip to content

Commit 27733dd

Browse files
frederikpytiluuu1994
authored andcommitted
Fix GH-17951: Addition of max_memory_limit INI
1 parent 659f55a commit 27733dd

14 files changed

+209
-2
lines changed

main/main.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,35 @@ static PHP_INI_MH(OnChangeMemoryLimit)
330330
if (new_value) {
331331
value = zend_ini_parse_uquantity_warn(new_value, entry->name);
332332
} else {
333-
value = Z_L(1)<<30; /* effectively, no limit */
333+
value = Z_L(1) << 30; /* effectively, no limit */
334334
}
335+
336+
/* If max_memory_limit is not set to unlimited, verify change */
337+
if (PG(max_memory_limit) != -1) {
338+
if (value == -1) {
339+
zend_error(
340+
E_WARNING,
341+
"Failed to set memory_limit to unlimited. memory_limit (currently: " ZEND_LONG_FMT " bytes) cannot be set to unlimited if max_memory_limit (" ZEND_LONG_FMT " bytes) is not unlimited",
342+
PG(memory_limit),
343+
PG(max_memory_limit)
344+
);
345+
346+
return FAILURE;
347+
}
348+
349+
if (value > PG(max_memory_limit)) {
350+
zend_error(
351+
E_WARNING,
352+
"Failed to set memory_limit to %zd bytes. memory_limit (currently: " ZEND_LONG_FMT " bytes) cannot exceed max_memory_limit (" ZEND_LONG_FMT " bytes)",
353+
value,
354+
PG(memory_limit),
355+
PG(max_memory_limit)
356+
);
357+
358+
return FAILURE;
359+
}
360+
}
361+
335362
if (zend_set_memory_limit(value) == FAILURE) {
336363
/* When the memory limit is reset to the original level during deactivation, we may be
337364
* using more memory than the original limit while shutdown is still in progress.
@@ -347,6 +374,26 @@ static PHP_INI_MH(OnChangeMemoryLimit)
347374
}
348375
/* }}} */
349376

377+
static PHP_INI_MH(OnChangeMaxMemoryLimit)
378+
{
379+
size_t value;
380+
if (new_value) {
381+
value = zend_ini_parse_uquantity_warn(new_value, entry->name);
382+
} else {
383+
value = Z_L(1) << 30; /* effectively, no limit */
384+
}
385+
386+
if (zend_set_memory_limit(value) == FAILURE) {
387+
zend_error(E_ERROR, "Failed to set memory limit to %zd bytes (Current memory usage is %zd bytes)", value, zend_memory_usage(true));
388+
return FAILURE;
389+
}
390+
391+
PG(memory_limit) = value;
392+
PG(max_memory_limit) = value;
393+
394+
return SUCCESS;
395+
}
396+
350397
/* {{{ PHP_INI_MH */
351398
static PHP_INI_MH(OnSetLogFilter)
352399
{
@@ -810,7 +857,10 @@ PHP_INI_BEGIN()
810857
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)
811858
STD_PHP_INI_ENTRY("mail.log", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMailLog, mail_log, php_core_globals, core_globals)
812859
PHP_INI_ENTRY("browscap", NULL, PHP_INI_SYSTEM, OnChangeBrowscap)
813-
PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit)
860+
861+
PHP_INI_ENTRY("max_memory_limit", "-1", PHP_INI_SYSTEM, OnChangeMaxMemoryLimit)
862+
PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit)
863+
814864
PHP_INI_ENTRY("precision", "14", PHP_INI_ALL, OnSetPrecision)
815865
PHP_INI_ENTRY("sendmail_from", NULL, PHP_INI_ALL, NULL)
816866
PHP_INI_ENTRY("sendmail_path", DEFAULT_SENDMAIL_PATH, PHP_INI_SYSTEM, NULL)

main/php_globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct _php_core_globals {
7272
zend_long serialize_precision;
7373

7474
zend_long memory_limit;
75+
zend_long max_memory_limit;
7576
zend_long max_input_time;
7677

7778
char *error_log;

php.ini-development

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ max_input_time = 60
436436
; Maximum amount of memory a script may consume
437437
; https://php.net/memory-limit
438438
memory_limit = 128M
439+
max_memory_limit = -1
439440

440441
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
441442
; Error handling and logging ;

php.ini-production

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ max_input_time = 60
438438
; Maximum amount of memory a script may consume
439439
; https://php.net/memory-limit
440440
memory_limit = 128M
441+
max_memory_limit = -1
441442

442443
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
443444
; Error handling and logging ;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-17951 INI Parse 1
3+
--CREDITS--
4+
Frederik Milling Pytlick
5+
6+
--INI--
7+
memory_limit=128M
8+
max_memory_limit=-1
9+
--FILE--
10+
<?php
11+
echo ini_get('max_memory_limit') . PHP_EOL;
12+
echo ini_get('memory_limit') . PHP_EOL;
13+
--EXPECT--
14+
-1
15+
128M
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-17951 INI Parse 2
3+
--CREDITS--
4+
Frederik Milling Pytlick
5+
6+
--INI--
7+
memory_limit=-1
8+
max_memory_limit=-1
9+
--FILE--
10+
<?php
11+
echo ini_get('max_memory_limit') . PHP_EOL;
12+
echo ini_get('memory_limit') . PHP_EOL;
13+
--EXPECT--
14+
-1
15+
-1
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-17951 INI Parse 3
3+
--CREDITS--
4+
Frederik Milling Pytlick
5+
6+
--INI--
7+
memory_limit=128M
8+
max_memory_limit=256M
9+
--FILE--
10+
<?php
11+
echo ini_get('max_memory_limit') . PHP_EOL;
12+
echo ini_get('memory_limit') . PHP_EOL;
13+
--EXPECT--
14+
256M
15+
128M
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
GH-17951 INI Parse 4
3+
--CREDITS--
4+
Frederik Milling Pytlick
5+
6+
--INI--
7+
memory_limit=-1
8+
max_memory_limit=128M
9+
--FILE--
10+
<?php
11+
echo ini_get('max_memory_limit') . PHP_EOL;
12+
echo ini_get('memory_limit') . PHP_EOL;
13+
--EXPECTF--
14+
Warning: Failed to set memory_limit to unlimited. memory_limit (currently: %d bytes) cannot be set to unlimited if max_memory_limit (%d bytes) is not unlimited in %s
15+
128M
16+
128M
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
GH-17951 INI Parse 5
3+
--CREDITS--
4+
Frederik Milling Pytlick
5+
6+
--INI--
7+
memory_limit=256M
8+
max_memory_limit=128M
9+
--FILE--
10+
<?php
11+
echo ini_get('max_memory_limit') . PHP_EOL;
12+
echo ini_get('memory_limit') . PHP_EOL;
13+
--EXPECTF--
14+
Warning: Failed to set memory_limit to %d bytes. memory_limit (currently: %d bytes) cannot exceed max_memory_limit (%d bytes) in %s
15+
128M
16+
128M
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
GH-17951 Runtime Change 1
3+
--CREDITS--
4+
Frederik Milling Pytlick
5+
6+
--INI--
7+
memory_limit=128M
8+
max_memory_limit=512M
9+
--FILE--
10+
<?php
11+
ini_set('memory_limit', '256M');
12+
echo ini_get('memory_limit') . PHP_EOL . PHP_EOL;
13+
--EXPECT--
14+
256M

0 commit comments

Comments
 (0)