Skip to content

[5.1] Fix getting an inaccessible properties from the request when isset() or empty() is called #10431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from

Conversation

kneipp
Copy link
Contributor

@kneipp kneipp commented Sep 30, 2015

Get an input element from the request when isset() or empty() is called on inaccessible properties.

More details:
#10403 (comment)
https://gist.github.com/kneipp/aee5802d08505d605676
http://php.net/manual/en/language.oop5.overloading.php#object.isset

@kneipp kneipp changed the title Fix bug when getting inaccessible property from the request [5.1] Fix bug when getting inaccessible property from the request Sep 30, 2015
@kneipp kneipp changed the title [5.1] Fix bug when getting inaccessible property from the request [5.1] Fix bug get an inaccessible properties from the request when isset() or empty() is called Sep 30, 2015
@kneipp kneipp changed the title [5.1] Fix bug get an inaccessible properties from the request when isset() or empty() is called [5.1] Fix getting an inaccessible properties from the request when isset() or empty() is called Sep 30, 2015
@rentalhost
Copy link
Contributor

I think that you should create some tests.
Check first it'll fail and then try apply your fix.

Thanks for your help!

@kneipp
Copy link
Contributor Author

kneipp commented Sep 30, 2015

For sure, but i need some help to start it.

On /tests where is the correct class to inset my assertions? Laravel doesn't have Request tests?

@taylorotwell
Copy link
Member

__isset is supposed to return a boolean value, but you appear to be returning other types of values?

@kneipp
Copy link
Contributor Author

kneipp commented Sep 30, 2015

Yeah, you're right i haven't check return type from __isset before. I'' fix it.

bool isset ( mixed $var [, mixed $... ] ) http://php.net/isset

public bool __isset ( string $name ) http://php.net/manual/en/language.oop5.overloading.php

@rentalhost
Copy link
Contributor

@kneipp current commit will not check exactly if $key isset. Currently it'll always returns true because you are testing if a existent paramenter exists.

You should check from where __get() get data, then check if the container isset on __isset().

I'll tell more in next...

@rentalhost
Copy link
Contributor

    /**
     * Get an input element from the request.
     *
     * @param  string  $key
     * @return mixed
     */
    public function __get($key)
    {
        $all = $this->all();
        if (array_key_exists($key, $all)) {
            return $all[$key];
        } else {
            return $this->route($key);
        }
    }

It call first $this->all(), then it check if $key exists in $all, else, it'll returns the $this->route($key). This last one will be the problem here.

In first case, you can use the __get() implementation like:

    public function __isset($key)
    {
        $all = $this->all();
        if (array_key_exists($key, $all)) {
            return true; // modified
        } else {
            // ... need do something more here...
            return ...;
        }

        return false; // added
    }

@kneipp
Copy link
Contributor Author

kneipp commented Sep 30, 2015

@rentalhost I have tested current commit with $request->title on controller:
var_dump($request->title) => string(4) "adaa"
var_dump(empty($request->title)) => bool(false)
var_dump(empty($request->title2)) => bool(true) // Dont exists

@kneipp kneipp closed this Sep 30, 2015
@kneipp kneipp reopened this Sep 30, 2015
@rentalhost
Copy link
Contributor

@kneipp For original commit it'll works, but not was implemented correctly, basically you copy/paste the __get(), but currently it'll fail. Note: it'll works for empty(), because __isset() will always returns true, but it'll fail if you do: isset($request->title2) (should returns false, but will returns true, instead).

@kneipp
Copy link
Contributor Author

kneipp commented Sep 30, 2015

@rentalhost does this make sense or can be broken?

    public function __isset($key)
    {
        $all = $this->all();

        if (array_key_exists($key, $all)) {
            return true;
        }
        return false;
    }

/**
* Get an input element from the request when isset() or empty() is called on inaccessible properties.
*
* @param $key
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incorrect

@rentalhost
Copy link
Contributor

@kneipp It make sense in this specific case, but you can't ignore that __get() does too, it'll call $this->route() and you need check what it mean. I really don't know.

*/
public function __isset($key)
{
return isset($key);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will ALWAYS return true...

@rentalhost
Copy link
Contributor

I'm working on this fix. When I get at home I do a pull request.

@kneipp
Copy link
Contributor Author

kneipp commented Sep 30, 2015

I guess it's ok now.

@rentalhost
Copy link
Contributor

You forget to check the route parameters that can be returned by __get too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants