yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.9k forks source link

Variable $roleParams not set before isset check in yii\filters\AccessRule::matchRole function #20182

Closed santilin closed 5 months ago

santilin commented 5 months ago

In the matchRole function of the AccessRule class, the variable $roleParams is not set before the isset($roleParams) condition.

The problematic code is:

if (!isset($roleParams)) {
    $roleParams = !is_array($this->roleParams) && is_callable($this->roleParams) ? call_user_func($this->roleParams, $this) : $this->roleParams;
}

This code assumes that $roleParams is already defined, but it is not set anywhere before this condition. Steps to Reproduce

Expected Behavior The matchRole function should handle the case where $this->roleParams is not an array or callable, and it should not assume that $roleParams is already defined.

Yii2 version: 2.0.50
PHP version: 8.3
rob006 commented 5 months ago

Set $this->roleParams to a non-array value (e.g., null, false, or a string) in your AccessRule configuration.

$roleParams accepts only Closure or array, if you pass null, false, or a string, then it is a configuration error.

https://www.yiiframework.com/doc/api/2.0/yii-filters-accessrule#$roleParams-detail

santilin commented 5 months ago

Yet, ¿but what is the point of testing

not isset($roleParams)

when the local variable $roleParams is not defined?

That test will always return false.

rob006 commented 5 months ago

It is inside of foreach, so it is empty for first iteration, but each next iteration will use already calculated value. In this way Closure is executed only once and only when it is actually needed.

santilin commented 5 months ago

Ah, ok, I didn't understand that. Thanks.