Skip to content
Draft
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
10 changes: 8 additions & 2 deletions Zend/zend_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ static zend_always_inline zend_string *ZSTR_KNOWN(size_t idx) {

#define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1)

/* ALIGN(n * m + header + l + 1). The "+ ALIGNMENT - 1" of the rounding is
* done inside the overflow check, so the final "& MASK" can only shrink
* the value and can not wrap. */
#define _ZSTR_SAFE_STRUCT_SIZE(n, m, l) \
(zend_safe_address_guarded(n, m, _ZSTR_STRUCT_SIZE(l) + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)

#define ZSTR_MAX_OVERHEAD (ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1))
#define ZSTR_MAX_LEN (SIZE_MAX - ZSTR_MAX_OVERHEAD)

Expand Down Expand Up @@ -198,7 +204,7 @@ static zend_always_inline zend_string *zend_string_alloc(size_t len, bool persis

static zend_always_inline zend_string *zend_string_safe_alloc(size_t n, size_t m, size_t l, bool persistent)
{
zend_string *ret = (zend_string *)safe_pemalloc(n, m, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(l)), persistent);
zend_string *ret = (zend_string *)pemalloc(_ZSTR_SAFE_STRUCT_SIZE(n, m, l), persistent);

GC_SET_REFCOUNT(ret, 1);
GC_TYPE_INFO(ret) = GC_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << GC_FLAGS_SHIFT);
Expand Down Expand Up @@ -325,7 +331,7 @@ static zend_always_inline zend_string *zend_string_safe_realloc(zend_string *s,

if (!ZSTR_IS_INTERNED(s)) {
if (GC_REFCOUNT(s) == 1) {
ret = (zend_string *)safe_perealloc(s, n, m, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(l)), persistent);
ret = (zend_string *)perealloc(s, _ZSTR_SAFE_STRUCT_SIZE(n, m, l), persistent);
ZSTR_LEN(ret) = (n * m) + l;
zend_string_forget_hash_val(ret);
return ret;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ var_dump(chunk_split($a,$b,$c));
--EXPECTF--
*** Testing chunk_split() : unexpected large 'end' string argument variation 2 ***

Fatal error: Possible integer overflow in memory allocation (65537 * 65537 + %r65556|65560%r) in %s on line %d
Fatal error: Possible integer overflow in memory allocation (65537 * 65537 + %r65557|65561%r) in %s on line %d
Loading