CB 2.5.0 and PHP 7.3 potential bug

3 years 3 weeks ago - 3 years 3 weeks ago #324076 by Quark Zimmerman
CB 2.5.0 and PHP 7.3 potential bug was created by Quark Zimmerman
Hi guys,

I am using CB 2.5.0 on Joomla 3.9.25 running PHP 7.3.22 .

And I think I hit the bug with the CB code.

The problem is that in admin interface of Joomla I am getting following error:

Argument 2 passed to GuzzleHttp\Adapter\StreamAdapter::createResponseObject() must be of the type array, null given, called in <>\libraries\CBLib\GuzzleHttp\Adapter\StreamAdapter.php on line 67


(TypeException is what throw to be exact)

I di some resurch/debugging and it appears that this error is result of CB code combined with PHP 7.3+ parameters checking behavior.

The problem is that in "/libraries/CBLib/GuzzleHttp/Adapter/StreamAdapter.php" , there is a following function:
private function createResponseObject(
        RequestInterface $request,
        array $headers,
        TransactionInterface $transaction,
        StreamInterface $stream
    )    private function createResponseObject(
        RequestInterface $request,
        array $headers,
        TransactionInterface $transaction,
        StreamInterface $stream
    ) 

as you can see the function here accepts "array $headers" as a 2nd parameter, however if we look the code "above the stack", we see:
private function createResponse(TransactionInterface $transaction)
    {
        $request = $transaction->getRequest();
        $stream = $this->createStream($request, $http_response_header);
        $this->createResponseObject(
            $request,
            $http_response_header,
            $transaction,
            new Stream($stream)
        );
    }

The problem here is that while "$this->createStream($request, $http_response_header);" recieves "http_response_header" by reference - nothing inside "createStream" changes it !
 private function createStream(
        RequestInterface $request,
        &$http_response_header
    ) {
        static $methods;
        if (!$methods) {
            $methods = array_flip(get_class_methods(__CLASS__));
        }

        $params = array();
        $options = $this->getDefaultOptions($request);
        foreach ($request->getConfig()->toArray() as $key => $value) {
            $method = "add_{$key}";
            if (isset($methods[$method])) {
                $this->{$method}($request, $options, $value, $params);
            }
        }

        $this->applyCustomOptions($request, $options);
        $context = $this->createStreamContext($request, $options, $params);

        return $this->createStreamResource(
            $request,
            $options,
            $context,
            $http_response_header
        );
    }

 private function createStreamResource(
        RequestInterface $request,
        array $options,
        $context,
        &$http_response_header
    ) {
        $url = $request->getUrl();

        return $this->createResource(
            function () use ($url, &$http_response_header, $context) {
                if (false === strpos($url, 'http')) {
                    trigger_error("URL is invalid: {$url}", E_USER_WARNING);
                    return null;
                }
                return fopen($url, 'r', null, $context);
            },
            $request,
            $options
        );
    }


[code]

As result the "$http_response_header" remains [b]null[/b] , NOT [b]array[/b] and thats what triggers the TypeException is PHP.

So , of course it's possible to disable PHP type checking in PHP config, but one way or another it's looks like a bug, so it should either be created as empty array, returned as empty artray.

Something like:
[code]
 private function createStreamResource(
        RequestInterface $request,
        array $options,
        $context,
        &$http_response_header
    ) {
        $url = $request->getUrl();

        return $this->createResource(
            function () use ($url, &$http_response_header, $context) {
                if (false === strpos($url, 'http')) {
                    trigger_error("URL is invalid: {$url}", E_USER_WARNING);
                    return null;
                }
	        $http_response_header = array();
                return fopen($url, 'r', null, $context);
            },
            $request,
            $options
        );
    }

Changing "createResponseObject" signature should be changed to something like this:
private function createResponseObject(
        RequestInterface $request,
        [b]?array[/b] $headers,
        TransactionInterface $transaction,
        StreamInterface $stream
    )    private function createResponseObject(
        RequestInterface $request,
        array $headers,
        TransactionInterface $transaction,
        StreamInterface $stream
    ) 
is WRONG as we will get simulart exceptions down the path.

Please Log in to join the conversation.

3 years 3 weeks ago #324090 by krileon
Replied by krileon on topic CB 2.5.0 and PHP 7.3 potential bug
We don't develop or maintain Guzzle. We just use it. It's a dependency. As for why that's happening in Guzzle it's because cURL isn't setup correctly. Below topic goes into detail about what's going on.

www.joomlapolis.com/forum/255-developer-members-support/233685-solved-cb-configuration-crash?start=0


Kyle (Krileon)
Community Builder Team Member
Before posting on forums: Read FAQ thoroughly + Read our Documentation + Search the forums
CB links: Documentation - Localization - CB Quickstart - CB Paid Subscriptions - Add-Ons - Forge
--
If you are a Professional, Developer, or CB Paid Subscriptions subscriber and have a support issue please always post in your respective support forums for best results!
--
If I've missed your support post with a delay of 3 days or greater and are a Professional, Developer, or CBSubs subscriber please send me a private message with your thread and will reply when possible!
--
Please note I am available Monday - Friday from 8:00 AM CST to 4:00 PM CST. I am away on weekends (Saturday and Sunday) and if I've missed your post on or before a weekend after business hours please wait for the next following business day (Monday) and will get to your issue as soon as possible, thank you.
--
My role here is to provide guidance and assistance. I cannot provide custom code for each custom requirement. Please do not inquire me about custom development.

Please Log in to join the conversation.

Moderators: beatnantkrileon
Time to create page: 0.407 seconds

Facebook Twitter LinkedIn