diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.h b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.h index 6abc042ff09b..e71737318bf7 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.h +++ b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.h @@ -170,6 +170,9 @@ static inline zend_result mb_convert_buf_ensure(mb_convert_buf *buf, unsigned ch size_t newsize = oldsize + MAX(oldsize >> 1, needed); zend_string *newstr = safe_ferealloc((buf)->str, 1, newsize, _ZSTR_STRUCT_SIZE(0), /* fallible */ true); if (!newstr) { + /* An earlier growth may have moved the buffer. */ + buf->out = *out; + buf->limit = *limit; return FAILURE; } *out = (unsigned char*)ZSTR_VAL(newstr) + (*out - (unsigned char*)ZSTR_VAL((buf)->str)); diff --git a/ext/mbstring/tests/oom_buf_growth.phpt b/ext/mbstring/tests/oom_buf_growth.phpt new file mode 100644 index 000000000000..04f563a6d3a2 --- /dev/null +++ b/ext/mbstring/tests/oom_buf_growth.phpt @@ -0,0 +1,17 @@ +--TEST-- +mbstring stores conversion-buffer pointers when growth fails +--EXTENSIONS-- +mbstring +--INI-- +memory_limit=8M +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of 8388608 bytes exhausted %S(tried to allocate %d bytes) in %s on line %d