bsdiff_patch(): reject output sizes in the diff header that do not fit in memory. This fixes a heap overflow on 32-bit platforms with crafted diff files. Lengths that exceedmemory_limitthrow aBsdiffExceptioninstead of causing a fatal error; this check is best effort, so lengths very close to the limit can still cause a fatal error.bsdiff_patch(): verify that the compressed data ends exactly where the patch ends (including its CRC), so truncated diff files and diff files with trailing data are rejected.bsdiff_patch(): stop crafted diff files whose control data produces no output from running for an unbounded amount of time.- Throw an exception when an input file is a directory or a read error occurs, instead of treating it as an empty file. (Before PHP 7.4, read errors are detected for local files only, as a short read.)
bsdiff_patch(): the new file gets the permission bits of the old file without setuid/setgid/sticky bits. They are set through the file descriptor before any data is written, instead of by path after writing.bsdiff_patch(): do not change the permissions of an existing output that is not a regular file (such as/dev/null, a terminal, or a FIFO), or of a file reached through a symbolic link or with other hard links. Before, they all got the permissions of the old file, which could make another user's file world-writable.bsdiff_patch(): get the permissions of the old file from the opened stream instead of a separatestat()call, so stream wrappers andopen_basedirare respected.- Remove the partially written output file when
bsdiff_diff()orbsdiff_patch()fails, including whenbsdiff_diff()exceeds the memory limit. Only local files that the call created are removed; existing files, symbolic links, devices, and files of other stream wrappers are left in place. - Fix a memory leak of about 7.5 MB of bzip2 state when
bsdiff_diff()exceeds the memory limit.
- Use the low-level bzip2 API with
emalloc/efree, so bzip2 memory counts againstmemory_limit. - Read and write diff files through PHP streams only, so stream wrappers work for the diff file on all platforms.
- Error messages for corrupted diff data now give the reason, e.g., "The diff file is corrupted (unexpected end of data)". They replace "Failed to apply diff data".
bsdiff_patch()now reports a missing old file as "Failed to open the old file" (previously "Failed to stat the old file").- Windows: configuration fails with an error when BZip2 is not found, instead of failing later at link time.
bsdiff_patch()rejects diff files with data after the end of the bzip2 stream (e.g., an appended signature). Diff files created bybsdiff_diff()have none.bsdiff_patch()reports control data that exceeds what a valid diff can contain as "The diff file is corrupted (too much control data)".- bzip2 state now counts against
memory_limit: about 7.6 MB forbsdiff_diff()and 3.5 MB forbsdiff_patch(). Scripts that ran close to their memory limit may need a higher one;bsdiff_patch()needs amemory_limitof at least about 6 MB.
- Add
composer.jsonfor installation via [PIE] (PHP Installer for Extensions).
- Use
emalloc/efree(via wrapper function pointers) for all internal bsdiff/bspatch allocations instead of libcmalloc/free, so allocations respectmemory_limitand are visible to PHP's leak detector andmemory_get_peak_usage(). - Replace POSIX file I/O with PHP streams and consolidate cleanup.
- Open diff files with explicit
"wb"/"rb"mode flags to ensure binary-mode I/O on Windows regardless of the host's_fmodeglobal. - Improve BZip2 auto-detection in
config.m4: search common Homebrew and system paths, and emit clearer error messages when headers or libraries are not found.
- PHP 8.3, 8.4, and 8.5 added to the CI matrix (Linux, macOS, Windows).
- Add PECL configuration option
with-bz2. - Include extension and BZip2 version numbers in
phpinfo()output.
Second public release.
This release is also available in PECL.
First public release.