php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72561 5.2.2 regressed with incorrect seeking in stream wrappers
Submitted: 2016-07-08 01:33 UTC Modified: 2016-07-08 08:16 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: nazar at mokrynskyi dot com Assigned:
Status: Verified Package: Streams related
PHP Version: 7.1.0alpha1 OS: Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2016-07-08 01:33 UTC] nazar at mokrynskyi dot com
Description:
------------
When doing reading/seeking on stream wrapper, PHP does interesting magic under the hood (for instance, reading 3 bytes results in 8192 bytes actually tried to be read in ::stream_read()).
This is all fine until it works as expected.

Here is demo: https://3v4l.org/3RG7r

PHP 5.1.4 - 5.2.1 have expected correct output.

hhvm-3.9.1 - 3.12.0 seems to also have optimizations under the hood, but result is correct anyway.

PHP 5.2.2+ (including latest 7.1.0-alpha2) regressed and does incorrect seeking which results in wrong position eventually.

I believe this should be fixed and backported to stable versions, since I do not see any good workaround here, input in ::stream_seek() is already incorrect.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-07-08 08:16 UTC] requinix@php.net
-Status: Open +Status: Verified -Package: Filesystem function related +Package: Streams related
 [2016-07-08 08:16 UTC] requinix@php.net
There's some weird magic going on, alright.

https://3v4l.org/0oYBR#v550

1. stream_read gets called with the full 8192, implying PHP is automatically buffering the stream. This could be intentional (probably is) and may simply be an issue of documentation, but as a developer I would prefer PHP didn't do that for me. And I'll bet that 99% of stream wrapper code out there expects the method to be called with the specific length instead of the maximum length.

2. stream_tell is not being called. At all. The docs say it should be called when using fseek(), and one would expect it to be called with ftell() but apparently that's not the case, however it looks like PHP is managing the pointer position all by itself.

3. read 3 seek -1 results in ftell()=3 when it should be =2. Then later the read 2 results in ftell()=5 (should be =4). Seems that the relative seek isn't updating the internal pointer?

> I believe this should be fixed and backported to stable versions,
So we're clear, that would be 5.6.x, 7.0.y, and 7.1.z. Because 5.5 is dead and there's no way any changes would get into versions earlier than that.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC