go to bug id or search bugs for
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.
Add a Patch
Add a Pull Request
There's some weird magic going on, alright.
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.
Related To: Bug #75708