Issues

ZF-5700: Warning thrown in Zend_Acl when using "allow all roles access to X" scenario

Issue Type: Bug Created: 2009-02-05T13:55:01.000+0000 Last Updated: 2009-09-18T13:20:04.000+0000 Status: Resolved Fix version(s): - 1.9.3 (22/Sep/09)

Reporter: Artur Bodera (joust) Assignee: Ralph Schindler (ralph) Tags: - Zend_Acl

Related issues: Attachments: - ZF-5700.diff

Description

Warning: Undefined index: byRoleId Line 201: Zend_Acl.php

Happens when we define rule like this:

<pre class="highlight">
$acl->allow(null,'SomeResource','Someaction');

... and the rule is the only rule for this resource.

The error is in this snippet:

<pre class="highlight">
        foreach ($this->_rules['byResourceId'] as $resourceIdCurrent => $visitor) {
            foreach ($visitor['byRoleId'] as $roleIdCurrent => $rules) {
                if ($roleId === $roleIdCurrent) {
                    unset($this->_rules['byResourceId'][$resourceIdCurrent]['byRoleId'][$roleIdCurrent]);
                }
            }
        }

Comments

Posted by Roger Hunwicks (rhunwicks) on 2009-08-03T06:01:12.000+0000

The error is in Zend_Acl::removeRole (on line 201 in Zend Framework 1.8.4).

If we have a resource that only has privileges for all users, then the $visitor array looks like:

<pre class="literal">
$visitor    Array [1]   
    allRoles    Array [1]   
        byPrivilegeId   Array [1]   
            Index   Array [2]   
                type    (string:10) TYPE_ALLOW  
                assert  null    

I.e. there is no byRoleId key in the $visitor array and so the foreach generates the Undefined Index warning.

Note that removeRole() loops through rules for every resource looking for privileges granted to the role being removed. This means that if there is a Resource that only has privileges for all users, the error occurs regardless of which role is being removed.

This error can be fixed by checking for the byRoleId array key before looping through the roles. I.e. instead of:

<pre class="highlight">
        foreach ($this->_rules['byResourceId'] as $resourceIdCurrent => $visitor) {
            foreach ($visitor['byRoleId'] as $roleIdCurrent => $rules) {
                if ($roleId === $roleIdCurrent) {
                    unset($this->_rules['byResourceId'][$resourceIdCurrent]['byRoleId'][$roleIdCurrent]);
                }
            }
        }

we have

<pre class="highlight">
        foreach ($this->_rules['byResourceId'] as $resourceIdCurrent => $visitor) {
            if (array_key_exists('byRoleId', $visitor)) {
                foreach ($visitor['byRoleId'] as $roleIdCurrent => $rules) {
                    if ($roleId === $roleIdCurrent) {
                        unset($this->_rules['byResourceId'][$resourceIdCurrent]['byRoleId'][$roleIdCurrent]);
                    }
                }
            }
        }

Posted by Keith Pope (mute) on 2009-09-18T07:48:38.000+0000

Adding patch for this issue

Posted by Matthew Weier O'Phinney (matthew) on 2009-09-18T13:20:04.000+0000

Patch applied to trunk and 1.9 release branch -- thanks!

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts