|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
[2016-01-16 00:27 UTC] salsi at icosaedro dot it
[2018-08-20 17:37 UTC] cmb@php.net
-Package: Filter related
+Package: Streams related
[2020-04-17 08:35 UTC] cmb@php.net
-Summary: fread() does not detects decoding errors from filter
bzip2.decompress
+Summary: fread() does not report bzip2.decompress errors
[2020-04-17 08:35 UTC] cmb@php.net
[2020-04-17 12:13 UTC] cmb@php.net
[2020-04-17 13:37 UTC] cmb@php.net
-Summary: fread() does not report bzip2.decompress
errors
+Summary: fread() does not report decompression errors
-Status: Open
+Status: Verified
-Assigned To:
+Assigned To: cmb
[2020-04-17 13:37 UTC] cmb@php.net
[2020-04-17 13:39 UTC] cmb@php.net
-Summary: fread() does not report decompression errors
+Summary: fread() does not report bzip2.decompress errors
[2020-04-17 13:39 UTC] cmb@php.net
[2020-04-20 12:22 UTC] cmb@php.net
[2020-04-20 12:22 UTC] cmb@php.net
-Status: Verified
+Status: Closed
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 18:00:01 2025 UTC |
Description: ------------ When the bzip2.decompress filter is applied to a stream, the fread() function does not detect decoding errors on a corrupted file and keeps instead returning the empty string or garbage. The following script illustrates 3 distinct cases. Checking what really happens inside the php_bz2_decompress_filter() function, in 2 of the 3 cases this function correctly detects an error in the corrupted file and returns PSFS_ERR_FATAL, but in the script the fread() function always succeeds. In one case the php_bz2_decompress_filter() function does not detect anything, but fread() succeeds and returns the empty string. In my opinion, if a decoding error is detected it is just like reading from a damaged file and fread() should return FALSE and triggering E_WARNING (which this script would map to ErrorException). I've tested on PHP 7.0-dev, but I don't think the PHP version does really matters here. Unsure if this bug is in some way related to #17651. Test script: --------------- <?php // Bug report: bzip2.decompress fails to detect corrupted data. // Set a safe environment: error_reporting(-1); ini_set("track_errors", "1"); /** * Maps errors to ErrorException. * @access private * @param int $errno * @param string $message * @return boolean * @throws ErrorException */ function my_error_handler($errno, $message /*, $filename, $lineno, $context */) { throw new ErrorException($message); } set_error_handler("my_error_handler"); /** * Testing reading corrupted BZIP2 file using bzip2.decompress filter. * @throws ErrorException */ function main() { $plain = "The quick brown fox jumps over the lazy dog."; $fn = "test.bz2"; $compressed = (string) bzcompress($plain); echo "Compressed len = ", strlen($compressed), "\n"; // Set a random byte in the middle of the compressed data // --> php_bz2_decompress_filter() detects fatal error // --> fread() displays empty string then garbage, no errors detected: $compressed[strlen($compressed) - 15] = 'X'; // Truncate the compressed data // --> php_bz2_decompress_filter() does not detect errors, // --> fread() displays the empty string: // $compressed = substr($compressed, 0, strlen($compressed) - 20); // Corrupted final CRC // --> php_bz2_decompress_filter() detects fatal error // --> fread() displays an empty string, then the correct plain text, no error detected: // $compressed[strlen($compressed)-2] = 'X'; file_put_contents($fn, $compressed); $r = fopen($fn, "r"); stream_filter_append($r, 'bzip2.decompress', STREAM_FILTER_READ); while( ! feof($r) ){ $s = fread($r, 100); echo "read: "; var_dump($s); } fclose($r); unlink($fn); } main(); ?> Expected result: ---------------- Compressed len = 81 Fatal error: Uncaught ErrorException: fread() I/O error in /home/salsi/BZIP2-bug-report.php:24 (or possibly a more descriptive error message, although it might be difficult to do due to the limitations of the filter interface) Actual result: -------------- Compressed len = 81 read: string(0) "" read: string(43) "bthes ohe rpujumr.bthes ohe rpujumr.bthes o"