php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47152 gzseek/fseek using SEEK_END produces strange results
Submitted: 2009-01-19 18:31 UTC Modified: 2009-01-20 15:45 UTC
From: d_kelsey at uk dot ibm dot com Assigned:
Status: Closed Package: Zlib related
PHP Version: 5.2.8 OS: Windows XP
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: d_kelsey at uk dot ibm dot com
New email:
PHP Version: OS:

 

 [2009-01-19 18:31 UTC] d_kelsey at uk dot ibm dot com
Description:
------------
I have opened a .gz file using gzopen for reading.
I can pass SEEK_END with offset of 0 (which would seek to the end of the file) using either fseek or gzseek as a whence. This returns -1 (a failure), but a subsequent gztell/ftell returns false, but I can still read the stream from the position it was last in. 

The issue is
1. is a whence of SEEK_END supported for a zlib stream ? If it is then SEEK_END is very broken as it doesn't move it to the end of the stream.

2. if not supported, I should get a warning saying invalid parameter. Also a subsequent call to gztell/ftell returns false.a further read and gztell/ftell returns an incorrect value 

I couldn't find any information to say it was not a valid value so assumed that it was valid.

Reproduce code:
---------------
<?php
//004.txt.gz taken from zlib test directory
//first 20 bytes are: "When you're taught t"
$f = dirname(__FILE__)."/004.txt.gz";
$h = gzopen($f, 'r'); 
//read the first 10
var_dump(gzread($h, 10));
echo "move to the end\n";
echo "gzseek=";
var_dump(gzseek( $h, 0, SEEK_END ) );
echo "tell=";
var_dump(gztell($h));
echo "eof=";
var_dump(gzeof($h));
//read the next 10
var_dump(gzread($h, 10));
echo "tell=";
var_dump(gztell($h));
?>

Expected result:
----------------
If SEEK_END is not valid:
string(10) "When you'r"
move to the end
gzseek=
Warning: gzseek() SEEK_END not supported
tell=int(10)
eof=bool(false)
string(10) "e taught t"
tell=int(20)

if SEEK_END is valid:
string(10) "When you'r"
move to the end
gzseek=int(0)
tell=int(176)
eof=bool(true)
string(0) ""
tell=int(176)

Actual result:
--------------
string(10) "When you'r"
move to the end
gzseek=int(-1)
tell=bool(false)
eof=bool(false)
string(10) "e taught t"
tell=int(9)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-01-20 13:35 UTC] d_kelsey at uk dot ibm dot com
There is also a problem using SEEK_END when opening a file for write mode.

for example
<?php
$file = "test.txt.gz";
$h = gzopen($file, 'w');
gzwrite($h, "first sentence.");
gzseek($h, 0, SEEK_END);
var_dump(gztell($h));
gzwrite($h, "second sentence.");
var_dump(gztell($h));
gzclose($h);

$h = gzopen($file, 'r');
gzpassthru($h);
gzclose($h);
unlink($file)
?>

results in:
bool(false)
int(15)
first sentence.second sentence.

So the gztell results of bool(false)and then int(15) are both incorrect. Yet the file did get written correctly.
 [2009-01-20 13:36 UTC] d_kelsey at uk dot ibm dot com
I would expect the gzseek to fail for SEEK_END on a write as this doesn't make any sense. The file pointer should not move which is the case but it seems that the tell value has been corrupted.
 [2009-01-20 15:45 UTC] felipe@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Hi,the SEEK_END actually is not supported.
I've added a warning when it's used.

Thanks.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Mon Feb 03 15:01:31 2025 UTC