✨ Added
- Configurable compression level for the APCu serializer (#87, 677ba80)
- New
brotli.apcu_compression_levelINI entry (defaults toBROTLI_DEFAULT_QUALITY), applied by the APCu serializer when compressing values - Out-of-range values fall back to
BROTLI_DEFAULT_QUALITY phpinfo()now emitsDISPLAY_INI_ENTRIES(), so the module's INI entries are shown- Available only when built with APCu support
- New
🐛 Fixed
- Fix build on PHP 8.6+ (#88, 522b4b5)
- Adapt to the
php-srcchange that altered the output handler API (php/php-src@7114314)
- Adapt to the
- Fix SIGSEGV in the APCu serializer callbacks on ZTS shared builds (e74345a)
- The (un)serializer callbacks are invoked from APCu's translation unit, where brotli's per-module
_tsrm_ls_cacheis not refreshed for the current thread, leaving it stale soBG()dereferenced a bad pointer - Refresh the cache with
ZEND_TSRMLS_CACHE_UPDATE()at the entry of both callbacks, mirroringphp_brotli_output_encoding()
- The (un)serializer callbacks are invoked from APCu's translation unit, where brotli's per-module
- Fix
CG(empty_string)crash in thesmart_str_extract()fallback on PHP 7.1 ZTS (02970c6)- The PHP < 7.2 fallback expanded
ZSTR_EMPTY_ALLOC()toCG(empty_string), which crashes under ZTS when evaluated inside the extension's inlined helper (reached by incremental compress/uncompress withBROTLI_PROCESSproducing empty output) - Allocate the empty string via the core
zend_string_init()symbol instead
- The PHP < 7.2 fallback expanded
- Fix heap-buffer-overflow in
php_brotli_decompress_read()inner read (#86, 0efb752)- The inner
php_stream_read()on theNEEDS_MORE_INPUTpath could write up to the caller-requested count intoinput_buf, overflowing thePHP_BROTLI_BUFFER_SIZE(1<<19) buffer when the stream chunk size exceeded it - Cap the read at
PHP_BROTLI_BUFFER_SIZE, matching the outer read, so writes intoinput_bufstay uniform over its lifetime - Regression test
tests/streams_007.phpt
- The inner
- Fix heap-use-after-free in
php_brotli_decompress_read()(#86, 1b2fc03)- The input buffer was
emalloc'd per call andefree'd at the end, butself->ctx.next_inkept pointing into it across calls, so the next entry could re-read the freed buffer - Move the input buffer onto
php_brotli_stream_data, allocate it lazily on first read, and free it inphp_brotli_decompress_close()
- The input buffer was
- Propagate failure of
brotli_uncompress_add()to the caller (#84, #85, 987ad82)- Check against
BROTLI_DECODER_RESULT_ERRORinstead of negatingBROTLI_DECODER_RESULT_SUCCESS, so thatNEEDS_MORE_INPUTis no longer misinterpreted as an error brotli_uncompress_add()now returnsfalseon hard decoder errors as documented
- Check against
- Fix UBSAN-detected undefined behavior in
brotli_uncompress_add()by switching to thesmart_strAPI (#83, a4828f5)- Previously, a
NULLsmart_string.c(on decoder failure or empty output) was passed tozend_string_init(), triggering undefined behavior in the subsequentmemcpy() - As a side benefit,
smart_stravoids reallocation, making the new code slightly faster
- Previously, a
- Restore build on PHP < 7.2 (ac13412)
📈 Improved
- CI/CD enhancements (229e1f7, 60dc5fb)
- Pin action versions to commit SHA and use native submodule checkout
- Switch the Linux workflow to
setup-phpon the ubuntu runner
New Contributors
- @ndossche made their first contribution in #83
- @pavetheway91 made their first contribution in #87
Full Changelog: 0.18.3...0.19.0