?
avatar sprague3351
sprague3351
9 May 2016

Steps to reproduce the issue

Do a HEAD operation on the site.
$method at com_user/models/login.php line 62 will be NULL which causes the following "if" to error out.

Expected result

Should behave as if there was no "return" value on the URL or POST entry.

Actual result

Server error 500, or worse.

System information (as much as possible)

Possible Fix

Add an if test on $method to avoid the IF on line 62 when the returned $method is null.

Additional comments

This occurs when caching web-browsers to the HEAD operation to see if they actually need to do a GET to obtain the page again.
Actually any operation (like FILES, DELETE, PUT, TRACE) other than the GET and POST operations have the same problem of returning a NULL from $input->getMethod()

avatar sprague3351 sprague3351 - open - 9 May 2016
avatar mbabker
mbabker - comment - 9 May 2016

If $input->getMethod() returns NULL then a combination of PHP and the web server aren't setting $_SERVER['REQUEST_METHOD'] correctly and that's beyond the scope of Joomla to be able to accommodate. That also isn't the issue; the issue is that $input->$method (which equates to $input->{$input->getMethod()} based on the other variable's assignment) is null.

At best, JInput can be patched to go from allowing a PHP Fatal Error to throwing an Exception when a data object that isn't supported is requested from the magic getter (and no it shouldn't return a default object IMO because in essence you're requesting an invalid data object).

The "fix" proposed at #7826 (comment) is invalid because it goes from looking for a value from the requested HTTP method to allowing a value from the $_REQUEST superglobal (right now for POST requests it only allows the value to be in $_POST and ignores if the value is in $_GET for example).

So long and short, JInput could be patched to raise an error instead of return a null, and com_users should check the method is actually valid for what it's trying to do (login AFAIK can't be supported on a HEAD request so it should gracefully error).

avatar zero-24
zero-24 - comment - 9 May 2016

@mbabker maybe i don't get the point but should it not be fixed with this code?

    protected function loadFormData()
    {
        // Check the session for previously entered login form data.
        $app    = JFactory::getApplication();
        $data   = $app->getUserState('users.login.form.data', array());
        $input  = $app->input;
        $method = $input->getMethod();
        $return = false;

        if ($method != '')
        {
            // Check for return URL from the request first
            $return = $input->$method->get('return', '', 'BASE64');
        }

        if ($return)
        {
            $data['return'] = base64_decode($return);

            if (!JUri::isInternal($data['return']))
            {
                $data['return'] = '';
            }
        }

        // Set the return URL if empty.
        if (!isset($data['return']) || empty($data['return']))
        {
            $data['return'] = 'index.php?option=com_users&view=profile';
        }

        $app->setUserState('users.login.form.data', $data);

        $this->preprocessData('com_users.login', $data);

        return $data;
    }
avatar mbabker
mbabker - comment - 9 May 2016

That fixes that one case. But if I'm not mistaken the path leading up to that calls on the login function and the underlying code will again try to access $input->$method after that data is set. IMO instead of addressing it that way, the login function should check that it's been requested on a HTTP request it can process and abort if it's not supported (seriously, why should the login function handle a HTTP PUT or DELETE request?).

avatar sprague3351
sprague3351 - comment - 9 May 2016

When I look at libraries/legacy/request/request.php line 364 The switch() does not include "HEAD" nor have a default case.
Hence $_REQUEST is never getting set.
Isn't this where Joomla is setting the value? Or is it getting set somewhere else?
Meanwhile the get function (line 423) and getVar (line 100) does have a default value which gets $_REQUEST which I think was never set.

Please note that the comments (line 74 and 400) claim that HEAD will work :-)


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/10365.

avatar mbabker
mbabker - comment - 9 May 2016

The JRequest class doesn't get used by core anymore and has a lot of different logic than JInput.

avatar sprague3351
sprague3351 - comment - 9 May 2016

Now I understand. Thank you very much for you assistance.
In my case the server is in fact returning 'HEAD' as should be expected.
The $input-> function can't handle the HEAD only GET so it is failing.

I can't test for NULL because $method is actually 'HEAD'
If I understand the standard correctly HEAD can act like GET when HEAD isn't supported.
Possibly reasonable since the login page should only be accessed from a GET anyway.
I've added (in my code) at line 62 (with appropriate comments):
if ($method=='HEAD') $method='GET' ;
And everything works.

avatar brianteeman
brianteeman - comment - 9 May 2016

So can this be closed?

avatar sprague3351
sprague3351 - comment - 9 May 2016

I still think it should be fixed (somehow) so that it does not error out.
But, yes, it can be closed.

avatar brianteeman brianteeman - close - 9 May 2016
avatar brianteeman brianteeman - change - 9 May 2016
Status New Closed
Closed_Date 0000-00-00 00:00:00 2016-05-09 22:28:42
Closed_By brianteeman
avatar brianteeman brianteeman - close - 9 May 2016
avatar brianteeman brianteeman - change - 13 May 2016
Labels Added: ?

Add a Comment

Login with GitHub to post a comment