Skip to content

Commit 324ad2f

Browse files
committed
Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4: Fixed bug #81070 This is a non-trivial merge. To avoid an ABI break, a new zend_set_memory_limit_ex() function is added.
2 parents 108105b + 1b3b5c9 commit 324ad2f

File tree

5 files changed

+34
-4
lines changed

5 files changed

+34
-4
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ PHP NEWS
99
. Fixed bug #76359 (open_basedir bypass through adding ".."). (cmb)
1010
. Fixed bug #81090 (Typed property performance degradation with .= operator).
1111
(Nikita)
12+
. Fixed bug #81070 (Integer underflow in memory limit comparison).
13+
(Peter van Dommelen)
1214

1315
- OCI8:
1416
. Fixed bug #81088 (error in regression test for oci_fetch_object() and

Zend/tests/bug81070.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
--TEST--
2+
Bug #81070 Setting memory limit to below current usage
3+
--FILE--
4+
<?php
5+
$a = str_repeat("0", 5 * 1024 * 1024);
6+
ini_set("memory_limit", "3M");
7+
?>
8+
--EXPECTF--
9+
Warning: Failed to set memory limit to 3145728 bytes (Current memory usage is %d bytes) in %s on line %d

Zend/zend_alloc.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2657,11 +2657,24 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length)
26572657
return p;
26582658
}
26592659

2660+
ZEND_API zend_result zend_set_memory_limit_ex(size_t memory_limit)
2661+
{
2662+
#if ZEND_MM_LIMIT
2663+
if (memory_limit < ZEND_MM_CHUNK_SIZE) {
2664+
memory_limit = ZEND_MM_CHUNK_SIZE;
2665+
}
2666+
if (UNEXPECTED(memory_limit < AG(mm_heap)->real_size)) {
2667+
return FAILURE;
2668+
}
2669+
AG(mm_heap)->limit = memory_limit;
2670+
#endif
2671+
return SUCCESS;
2672+
}
26602673

26612674
ZEND_API void zend_set_memory_limit(size_t memory_limit)
26622675
{
26632676
#if ZEND_MM_LIMIT
2664-
AG(mm_heap)->limit = (memory_limit >= ZEND_MM_CHUNK_SIZE) ? memory_limit : ZEND_MM_CHUNK_SIZE;
2677+
AG(mm_heap)->limit = memory_limit >= ZEND_MM_CHUNK_SIZE ? memory_limit : ZEND_MM_CHUNK_SIZE;
26652678
#endif
26662679
}
26672680

Zend/zend_alloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ ZEND_API void * __zend_realloc(void *p, size_t len) ZEND_ATTRIBUTE_ALLOC_SIZE(2)
220220
#define pestrdup_rel(s, persistent) ((persistent)?strdup(s):estrdup_rel(s))
221221

222222
ZEND_API void zend_set_memory_limit(size_t memory_limit);
223+
ZEND_API zend_result zend_set_memory_limit_ex(size_t memory_limit);
223224

224225
ZEND_API void start_memory_manager(void);
225226
ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown);

main/main.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,17 @@ static PHP_INI_MH(OnSetSerializePrecision)
265265
/* {{{ PHP_INI_MH */
266266
static PHP_INI_MH(OnChangeMemoryLimit)
267267
{
268+
size_t value;
268269
if (new_value) {
269-
PG(memory_limit) = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
270+
value = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
270271
} else {
271-
PG(memory_limit) = Z_L(1)<<30; /* effectively, no limit */
272+
value = Z_L(1)<<30; /* effectively, no limit */
272273
}
273-
zend_set_memory_limit(PG(memory_limit));
274+
if (zend_set_memory_limit_ex(value) == FAILURE) {
275+
zend_error(E_WARNING, "Failed to set memory limit to %zd bytes (Current memory usage is %zd bytes)", value, zend_memory_usage(true));
276+
return FAILURE;
277+
}
278+
PG(memory_limit) = value;
274279
return SUCCESS;
275280
}
276281
/* }}} */

0 commit comments

Comments
 (0)