php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79984 Stream filter is not called with closing arg on php://temp streams
Submitted: 2020-08-17 08:28 UTC Modified: 2020-08-17 16:19 UTC
From: gehrig at teqneers dot de Assigned: cmb (profile)
Status: Duplicate Package: Streams related
PHP Version: 7.4.9 OS: Official Docker Image
Private report: No CVE-ID: None
 [2020-08-17 08:28 UTC] gehrig at teqneers dot de
Description:
------------
As seen in script https://3v4l.org/egsEi a simple stream filter is created. It outputs some debug information on php_user_filter::onCreate, php_user_filter::onClose and on each call to php_user_filter::filter.

The stream filter is then attached to streams based on 

a) tmpfile()
b) a php://temp stream
c) a php://memory stream

While a) and c) produce the correct result in all PHP versions, b) behaves differently on PHP 7.2.0 - 7.2.33, 7.3.0 - 7.3.21, 7.4.0 - 7.4.9, 8.0.0alpha1 - beta1 (according to https://3v4l.org). 

As seen from the output the stream filter attached to the php://temp stream is only called twice (b) while in the other examples it's called three times (a and c) - with 0 bytes left to consume but $closing = true on the last call. The "$closing = true" call is missing when using a php://temp (b). 
Older versions of PHP (5.5.21 - 5.5.38, 5.6.5 - 5.6.40, 7.0.0 - 7.0.33, 7.1.0 - 7.1.33) do not show this kind of behaviour, while even older ones (5.3.29, 5.4.19 - 5.4.45, 5.5.1 - 5.5.20, 5.6.0 - 5.6.4) show the same behaviour even on php://memory streams (c). 

I'm not sure but this one may be related to #68948 (https://bugs.php.net/bug.php?id=68948) and it might even be a duplicate of #77069 (https://bugs.php.net/bug.php?id=77069).

Test script:
---------------
https://3v4l.org/egsEi

Expected result:
----------------
tmpfile()
filter onCreate
filtered 8192 bytes.
filtered 128 bytes.
filtered 0 bytes and closing.
A...A // shortened - 8320 bytes
filter onClose


php://temp
filter onCreate
filtered 8192 bytes.
filtered 128 bytes.
filtered 0 bytes and closing.
A...A // shortened - 8320 bytes
filter onClose


php://memory
filter onCreate
filtered 8192 bytes.
filtered 128 bytes.
filtered 0 bytes and closing.
A...A // shortened - 8320 bytes
filter onClose


Actual result:
--------------
tmpfile()
filter onCreate
filtered 8192 bytes.
filtered 128 bytes.
filtered 0 bytes and closing.
A...A // shortened - 8320 bytes
filter onClose


php://temp
filter onCreate
filtered 8192 bytes.
filtered 128 bytes.
A...A // shortened - 8320 bytes
filter onClose


php://memory
filter onCreate
filtered 8192 bytes.
filtered 128 bytes.
filtered 0 bytes and closing.
A...A // shortened - 8320 bytes
filter onClose


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-08-17 15:07 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2020-08-17 15:07 UTC] cmb@php.net
Yes, indeed this is a duplicate of bug #77069.

I have just filed PR #6001[1] which would fix the given tests
script in a slightly different way; instead of

    filtered 128 bytes.
    filtered 0 bytes and closing.

it would output

    filtered 128 bytes and closing.

Would that be an issue?

[1] <https://github.com/php/php-src/pull/6001>
 [2020-08-17 15:12 UTC] gehrig at teqneers dot de
@cmb@php.net:

Absolutely not. That'd be the output I'd actually expect to start with. I just didn't bother with the fact that the filter is called a last time with 0 bytes to be consumed and $closing = true.
 [2020-08-17 16:19 UTC] cmb@php.net
-Status: Feedback +Status: Duplicate
 [2020-08-17 16:19 UTC] cmb@php.net
Great!  So I'm closing this as duplicate (and also have to work on
the PR, because it breaks a SOAP test case).
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Sat Sep 18 04:03:36 2021 UTC