flysystem-stream-wrapper icon indicating copy to clipboard operation
flysystem-stream-wrapper copied to clipboard

Call to move_uploaded_file() always returns true

Open dandjo opened this issue 6 years ago • 13 comments

When uploading a file with php forms using $_FILES and calling move_uploaded_file() with a stream wrapper as destination, the return value of writeStream is ignored.

dandjo avatar May 27 '19 17:05 dandjo

It seems to be a bug in PHP ignoring the return value of the method stream_flush in stream wrappers. https://bugs.php.net/bug.php?id=78077

dandjo avatar May 28 '19 09:05 dandjo

Would you be able to reproduce a test case or script to demonstrate?

Lewiscowles1986 avatar Feb 14 '20 19:02 Lewiscowles1986

Of course, like written in the PHP Bug above:

class MyStreamWrapper
{

    public function stream_write($data)
    {
        return 1;
    }

    public function stream_flush()
    {
        return false;
    }

}

stream_wrapper_register('my-wrapper', \MyStreamWrapper::class, 0);
$res = move_uploaded_file($_FILES['uploaded_file']['tmp_name'], 'my-wrapper://' . basename($_FILES['uploaded_file']['name']));
stream_wrapper_unregister('my-wrapper');
echo $res ? 'true' : 'false';

Expected result: 'false' Actual result: 'true'

dandjo avatar Feb 17 '20 15:02 dandjo

Right, but that's how PHP the language works and seems devoid of anything related to this wrapper.

Lewiscowles1986 avatar Feb 18 '20 02:02 Lewiscowles1986

To be even more clear https://github.com/php/php-src/blob/16f194c75e05381628ae2b9468fb8004dec9e176/ext/standard/basic_functions.c#L3282-L3333 shows no reference to flush being called at all. If the failure is encapsulated elsewhere, unless that function returns false (it seems there are only rename and copy then rm semantics), then this needs to be attributed to those.

Lewiscowles1986 avatar Feb 18 '20 02:02 Lewiscowles1986

looking at https://github.com/php/php-src/blob/9a76a2a0329aae203e6f27be40f2977a8d7e223f/ext/standard/file.c#L1644-L1733 it seems this is where stat is checked for copy-case it likewise does not flush

Lewiscowles1986 avatar Feb 18 '20 02:02 Lewiscowles1986

Is this really a matter of "how PHP works"? In my opinion it's a severe bug or concept glitch. In combination with streamwrappers you will never know whether the upload succeeded or not. You won't even get a useful feedback. We ended up patching Drupal to use our own move_uploaded_file().

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21File%21FileSystem.php/function/FileSystem%3A%3AmoveUploadedFile/8.2.x

https://www.drupal.org/files/issues/2019-06-03/3057565-6-move-uploaded-file-streamwrapper.patch

dandjo avatar Feb 19 '20 11:02 dandjo

Ultimately, what you've encountered is a bug in move_uploaded_file itself, so yes, it's a PHP bug, rather than a stream wrapper bug.

danhunsaker avatar Feb 20 '20 17:02 danhunsaker

@dandjo I guess congrats on getting something that works for you.

@danhunsaker should this be closed or marked with descriptive labels in-case someone else encounters? Technically since it's not part of this library, I suppose it's not a problem to close? IDK

Also thanks for writing this library. Very cool concept to make filesystem easier

Lewiscowles1986 avatar Feb 20 '20 23:02 Lewiscowles1986

Oh, I didn't write it. I just follow issues for it since I wrote a lib for Laravel that automatically pulls this one in and sets it up for configured drives.

danhunsaker avatar Feb 21 '20 07:02 danhunsaker

Link please 😉

Lewiscowles1986 avatar Feb 22 '20 10:02 Lewiscowles1986

https://github.com/danhunsaker/laravel-flysystem-others

danhunsaker avatar Feb 23 '20 07:02 danhunsaker

Ultimately, what you've encountered is a bug in move_uploaded_file itself, so yes, it's a PHP bug, rather than a stream wrapper bug.

Yes, fully d'accord. I'm thinking about writing either a polyfill to overload the behaviour or sending a pull request to patch the Flysystem to handle this issue. I've no hope the PHP guys will patch this over the next few years. :-)

dandjo avatar Feb 23 '20 12:02 dandjo