php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71417 fread() does not report zlib.inflate errors
Submitted: 2016-01-20 02:57 UTC Modified: 2020-04-17 14:22 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: salsi at icosaedro dot it Assigned: cmb (profile)
Status: Closed Package: Streams related
PHP Version: master-Git-2016-01-20 (Git) OS: Slackware 14.1
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: salsi at icosaedro dot it
New email:
PHP Version: OS:

 

 [2016-01-20 02:57 UTC] salsi at icosaedro dot it
Description:
------------
When the zlib.inflate filter is applied to a gzip 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:

1. data corrupted
2. file truncated (commented away)
3. invalid CRC    (commented away)
4. invalid length (commented away)

For comparison, the comments in the script also report what the 'gzip' command tells about these corrupted files.
Also the gzdecode() function works properly and always triggers error "data error".

In all the 4 cases above, no errors nor exceptions are generated, although the data read are either corrupted or truncated.

Unsure if this bug is in some way related to bug #71263 (same issues with the bzip2.decompress filter).


Test script:
---------------
<?php
// Bug report: zlib.inflate fails to detect corrupted data.

// Set a safe environment:
error_reporting(-1);

// Maps errors to ErrorException.
function my_error_handler($errno, $message)
{ 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-zlib-inflate.gz";
	$compressed = (string) gzencode($plain);
	
	// 0. No corruption.
	// $ php test-zlib-inflate.php
	// --> read: string(44) "The quick brown fox jumps over the lazy dog."
	// $ gzip test-zlib-inflate.gz
	// (generates the file test-zlib-inflate with correct content)
	
	// 1. Set a random byte in the middle of the compressed data.
	// $ php test-zlib-inflate.php
	// --> read: string(0) ""
	// --> read: string(44) "The quick brown fox jumps over the lazx8dog."
	// $ gzip test-zlib-inflate.gz
	// gzip: test-zlib-inflate.gz: invalid compressed data--crc error
//	$compressed[strlen($compressed) - 15] = 'X';
	
	// 2. Truncate the compressed data.
	// $ php test-zlib-inflate.php
	// --> read: string(32) "The quick brown fox jumps over t"
	// $ gzip test-zlib-inflate.gz
	// gzip: test-zlib-inflate.gz: unexpected end of file
//	$compressed = substr($compressed, 0, strlen($compressed) - 20);
	
	// 3. Corrupted final CRC.
	// $ php test-zlib-inflate.php
	// --> read: string(0) ""
	// --> read: string(44) "The quick brown fox jumps over the lazy dog."
	// $ gzip test-zlib-inflate.gz
	// gzip: test-zlib-inflate.gz: invalid compressed data--crc error
//	$compressed[strlen($compressed)-5] = 'X';
	
	// 4. Corrupted final length.
	// $ php test-zlib-inflate.phpread: string(0) ""
	// read: string(44) "The quick brown fox jumps over the lazy dog."
	// $ gunzip test-zlib-inflate.gz 
	// gzip: test-zlib-inflate.gz: invalid compressed data--length error
	$compressed[strlen($compressed)-2] = 'X';
	
	// The gzdecode() function applied to the corrupted compressed data always
	// detects the error:
	// --> gzdecode(): PHP Fatal error:  Uncaught ErrorException: gzdecode(): data error in ...
//	echo "gzdecode(): ", rawurldecode(gzdecode($compressed)), "\n";

	file_put_contents($fn, $compressed);
	
	$r = fopen($fn, "r");
	stream_filter_append($r, 'zlib.inflate', STREAM_FILTER_READ, array('window' => 15+16));
	while( ! feof($r) ){
		$s = fread($r, 100);
		echo "read: "; var_dump($s);
	}
	fclose($r);
//	unlink($fn);
}

main();
?>

Expected result:
----------------
Fatal error: Uncaught ErrorException: fread() I/O error in ...

(or possibly a more descriptive error message similar to one of those returned by the gzip command)


Actual result:
--------------
read: string(0) ""
read: string(44) "The quick brown fox jumps over the lazx8dog."


Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-01-20 11:06 UTC] salsi at icosaedro dot it
...and in general errors that are certainly generated internally to the zlib library are not reported to the user's application, resulting in missing or no data read at all.

This happens, for example, when an highly compressible stream (say, a source program at least 40 KB long) that was compressed with a large window (window=15+16), is then decompressed with a smaller window (window=9+16). In this case fread() simply returns the empty string before the feof() (source code available).

At this point these issues seem more related to the general implementation of the stream filters that to a specific filter, but I don't know enough of the internals stuff to tell for sure.

FIX: in the test script above any reference to "bzip2" in the comments should be read "zlib" :->
 [2017-12-09 11:02 UTC] salsi at icosaedro dot it
Probably related to bug #71384 -- see for the general discussion about missing error propagation in the streams layer.
 [2020-04-17 14:22 UTC] cmb@php.net
-Summary: fread() does not detect decoding errors from filter zlib.inflate +Summary: fread() does not report zlib.inflate errors -Status: Open +Status: Verified -Assigned To: +Assigned To: cmb
 [2020-04-17 14:22 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #71417: fread() does not report zlib.inflate errors
On GitHub:  https://github.com/php/php-src/pull/5408
Patch:      https://github.com/php/php-src/pull/5408.patch
 [2020-04-20 14:49 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=3d1b730c11a4e37884d25bf8af0d5726834986c4
Log: Fix #71417: fread() does not report zlib.inflate errors
 [2020-04-20 14:49 UTC] cmb@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 03 17:01:29 2024 UTC