php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77828 SplFileObject::seek problems on custom stream wrappers
Submitted: 2019-03-31 22:32 UTC Modified: 2019-04-01 08:36 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: alexey dot khokhryakov at gmail dot com Assigned:
Status: Open Package: SPL related
PHP Version: 7.2.16 OS:
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: alexey dot khokhryakov at gmail dot com
New email:
PHP Version: OS:

 

 [2019-03-31 22:32 UTC] alexey dot khokhryakov at gmail dot com
Description:
------------
SplFileObject::seek() works wrong for custom stream wrappers. It should work exactly the same as for native files.

In my example I created simple stream wrapper which just proxies all calls to native fopen/fread/ftell/feof/fseek/stat functions which demonstrates the problem.

Test script:
---------------
<?php
file_put_contents($tmpFilename = tempnam(sys_get_temp_dir(), 'test'), "one line\r\n");
stream_wrapper_register('foo', FooStreamWrapper::class);

foreach ([$tmpFilename, "foo:/{$tmpFilename}"] as $filename) {
    $file = new SplFileObject($filename, 'r');
    $file->seek($file->getSize());
    var_dump($file->key());
}

class FooStreamWrapper {
    private $r;
    public function stream_open($path, $mode) { $this->r = fopen(str_replace('foo:/', '', $path), $mode); return true; }
    public function stream_read($count) { return fread($this->r, $count); }
    public function stream_tell() { return ftell($this->r); }
    public function stream_eof() { return feof($this->r); }
    public function stream_seek($offset, $whence) { return fseek($this->r, $offset, $whence) === 0; }
    public function url_stat($path) { return stat(str_replace('foo:/', '', $path)); }
}


Expected result:
----------------
int(1)
int(1)


Actual result:
--------------
int(1)
int(0)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-03-31 23:19 UTC] requinix@php.net
It's not SplFileObject but your stream wrapper. PHP's file wrapper is reading lines, yours is reading bytes. If you edit yours to read lines as well
  public function stream_read($count) { return fgets($this->r, $count); }
then it works as expected.

Not sure the best way to fix this.
 [2019-04-01 07:38 UTC] alexey dot khokhryakov at gmail dot com
requinix@php.net, I don't think so.

If wrapper::stream_read() proxies calls to fgets() then SplFileObject::fread($count) becomes inconsistent because PHP's file wrapper returns $count of data including linebreaks.
 [2019-04-01 08:12 UTC] requinix@php.net
Try the change I said, see what happens.
 [2019-04-01 08:21 UTC] alexey dot khokhryakov at gmail dot com
I tried and I see that my test script works but it breaks SplFileObject::fread() functionality as I said.

file_put_contents($tmpFilename = tempnam(sys_get_temp_dir(), 'test'), "one\r\ntwo\r\n");
stream_wrapper_register('foo', FooStreamWrapper::class);
$file = new SplFileObject("foo:/{$tmpFilename}", 'r');
var_dump($file->fread($file->getSize()));

Expected:
string(10) "one
two
"

Actual:
string(5) "one
"
 [2019-04-01 08:36 UTC] requinix@php.net
I know it's not correct. I'm saying, you can see the line reading/byte reading behavior if you switch the stream to read lines. There is a bug here.
 [2022-12-01 06:10 UTC] gallwaseborg at gmail dot com
If you truly need to say thank you ! We'd really appreciate and be thankful expecting you leave a decent report on the module page. This is the best procedure for guiding say thank you to this undertaking and sponsorship bundle. (https://www.subwayliveiq.net/)github.com
 [2024-02-14 06:28 UTC] Booker82EVail at gmail dot com
This post is very informatic for me so thank you so much for creating this topic


best regard,
(https://github.com)(https://www.dogneedsbest.com/)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC