github kjdev/php-ext-brotli 0.19.0

11 hours ago

✨ Added

  • Configurable compression level for the APCu serializer (#87, 677ba80)
    • New brotli.apcu_compression_level INI entry (defaults to BROTLI_DEFAULT_QUALITY), applied by the APCu serializer when compressing values
    • Out-of-range values fall back to BROTLI_DEFAULT_QUALITY
    • phpinfo() now emits DISPLAY_INI_ENTRIES(), so the module's INI entries are shown
    • Available only when built with APCu support

🐛 Fixed

  • Fix build on PHP 8.6+ (#88, 522b4b5)
  • 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_cache is not refreshed for the current thread, leaving it stale so BG() dereferenced a bad pointer
    • Refresh the cache with ZEND_TSRMLS_CACHE_UPDATE() at the entry of both callbacks, mirroring php_brotli_output_encoding()
  • Fix CG(empty_string) crash in the smart_str_extract() fallback on PHP 7.1 ZTS (02970c6)
    • The PHP < 7.2 fallback expanded ZSTR_EMPTY_ALLOC() to CG(empty_string), which crashes under ZTS when evaluated inside the extension's inlined helper (reached by incremental compress/uncompress with BROTLI_PROCESS producing empty output)
    • Allocate the empty string via the core zend_string_init() symbol instead
  • Fix heap-buffer-overflow in php_brotli_decompress_read() inner read (#86, 0efb752)
    • The inner php_stream_read() on the NEEDS_MORE_INPUT path could write up to the caller-requested count into input_buf, overflowing the PHP_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 into input_buf stay uniform over its lifetime
    • Regression test tests/streams_007.phpt
  • Fix heap-use-after-free in php_brotli_decompress_read() (#86, 1b2fc03)
    • The input buffer was emalloc'd per call and efree'd at the end, but self->ctx.next_in kept 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 in php_brotli_decompress_close()
  • Propagate failure of brotli_uncompress_add() to the caller (#84, #85, 987ad82)
    • Check against BROTLI_DECODER_RESULT_ERROR instead of negating BROTLI_DECODER_RESULT_SUCCESS, so that NEEDS_MORE_INPUT is no longer misinterpreted as an error
    • brotli_uncompress_add() now returns false on hard decoder errors as documented
  • Fix UBSAN-detected undefined behavior in brotli_uncompress_add() by switching to the smart_str API (#83, a4828f5)
    • Previously, a NULL smart_string.c (on decoder failure or empty output) was passed to zend_string_init(), triggering undefined behavior in the subsequent memcpy()
    • As a side benefit, smart_str avoids reallocation, making the new code slightly faster
  • 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-php on the ubuntu runner

New Contributors

Full Changelog: 0.18.3...0.19.0

Don't miss a new php-ext-brotli release

NewReleases is sending notifications on new releases.