php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #78375 stream_set_option method of stream wrapper is now called inside require()
Submitted: 2019-08-05 15:55 UTC Modified: 2019-08-08 08:20 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: mail at ciaranmcnulty dot com Assigned:
Status: Verified Package: Streams related
PHP Version: 7.4.0beta1 OS: Debian Slim (docker)
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: mail at ciaranmcnulty dot com
New email:
PHP Version: OS:

 

 [2019-08-05 15:55 UTC] mail at ciaranmcnulty dot com
Description:
------------
Any `require` that is done through a protocol with a wrapper, now calls `stream_set_option` on the stream wrapper.

Because a stream wrapper doesn't have an interface, a class could not yet implement this method and therefore cause a fatal error.

The option being set is not one of the listed constants (STREAM_OPTION_BLOCKING, STREAM_OPTION_READ_TIMEOUT, STREAM_OPTION_WRITE_BUFFER), rather it is integer 2

Test script:
---------------
class StreamWrapper
{
    public function stream_open($path, $mode, $options, &$opened_path)
    {
        return true;
    }

    public function stream_stat() { return stat(__FILE__); }

    public function stream_read($count) { return ''; }

    public function stream_eof() { return true; }
}

stream_wrapper_register('test', StreamWrapper::class);

require_once('test://foo');

Expected result:
----------------
No output

Actual result:
--------------
Warning: require_once(): StreamWrapper::stream_set_option is not implemented!

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-08-05 16:00 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2019-08-05 16:00 UTC] cmb@php.net
Confirmed: <https://3v4l.org/QjgOW>
 [2019-08-05 17:15 UTC] cmb@php.net
-Type: Bug +Type: Documentation Problem
 [2019-08-05 17:15 UTC] cmb@php.net
Well, this is a deliberate BC break caused by an optimization[1],
and as such not a bug.  However, this change is not documented in
UPGRADING, and indeed PHP_STREAM_OPTION_READ_BUFFER (the option
with value 2) is missing from the PHP manual.

[1] <http://git.php.net/?p=php-src.git;a=commit;h=a986e70991057785cd3e5f4235215cb933351b4d>
 [2019-08-06 14:21 UTC] mail at ciaranmcnulty dot com
This is indeed a docs problem! For some reason I hadn’t realised it is just a Warning
 [2019-08-08 08:20 UTC] nikic@php.net
Upgrading note added in https://github.com/php/php-src/commit/8a4171ac457c048e1b05b2d9fc9b74f4816272a0. I considered adding a special hack to hide the warning for this case, but overall I feel it would do more harm than good. Custom stream wrapper implementations aren't exactly super common, so I'd err on the side of consistent behavior here.
 [2019-10-01 14:54 UTC] mail at ciaranmcnulty dot com
Just as a note the example at https://www.php.net/manual/en/stream.streamwrapper.example-1.php doesn't implement this method
 [2020-01-08 14:52 UTC] bkfake-php at yahoo dot com
More documentation issues:

stream_set_option (https://www.php.net/manual/en/streamwrapper.stream-set-option.php)
makes no mention of STREAM_OPTION_READ_BUFFER

stream_set_option documentation doesn't describe what STREAM_BUFFER_NONE and STREAM_BUFFER_FULL designate / how they should be handled  (as the previous comment mentions there is no example implementation)

stream constants documentation (https://www.php.net/manual/en/stream.constants.php) does not list any of these constants
STREAM_OPTION_BLOCKING
STREAM_OPTION_READ_TIMEOUT
STREAM_OPTION_READ_BUFFER
STREAM_OPTION_WRITE_BUFFER
STREAM_BUFFER_NONE
STREAM_BUFFER_FULL

In my attempt to find libraries that implement read/write buffer I've found broken implementations such as

case STREAM_OPTION_WRITE_BUFFER:
    return stream_set_write_buffer($this->fp, $arg1);
case STREAM_OPTION_READ_BUFFER:
    return stream_set_read_buffer($this->fp, $arg1);

This is broken on multiple levels  (passing $arg1 rather than $arg2 / assumes that stream_set_(read|write)_buffer return boolean [they do not] / otherwise ignoring $arg1's value)


-----

possibly related?:
I'm using a streamWrapper to inject "declare(ticks=1);" on the fly for a debugger/profiler...
in php 7.4 it appears that `require` only reads the number of bytes that stream_stat reports/returns...  Even though stream_read is returning the entire buffer...  This results in "PHP Parse error:  syntax error, unexpected end of file"
increasing $stats['size'] to account for the injected string length solves this...     
Could this be READ_BUFFER NONE/FULL related
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 15:01:29 2024 UTC