Please, see attached patch.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Dries’s picture

Status: Reviewed & tested by the community » Needs review

How to reproduce?

markus_petrux’s picture

Not sure how to reproduce, if it was possible you would get a SQL error, because the IN() clausule in the query would be empty. Note that $account->roles is used to build the query, hence the check (which is what's wrong here).

moshe weitzman’s picture

Status: Needs review » Closed (works as designed)

i don't get the problem here. please reopen if it really exists and give more detailed explanation.

jvandyk’s picture

Status: Closed (works as designed) » Needs review
FileSize
766 bytes

I think markus_petrux is saying that in the event that a $user is passed in the optional $account parameter of user_access, the check for roles should be done on $account (that is, the $user whose access is being checked) and not for $user.

But I'm unsure of the significance of the presence of the roles attribute and why the check is being made.

And I think the patch submitted as backwards. See attached.

markus_petrux’s picture

Status: Needs review » Reviewed & tested by the community

Please, examine this code snippet in user_access():

  if (is_null($account)) {
    $account = $user;
  }

Ok, this is because user_access defaults to check permissions for current user, if no account object has been passed in the second argument. Hence, from this point on, $user is not needed. It is all about $account.

Now, examine this:

  // To reduce the number of SQL queries, we cache the user's permissions
  // in a static variable.
  if (!isset($perm[$account->uid]) && count($user->roles)) {
    $result = db_query("SELECT DISTINCT(p.perm) FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid WHERE r.rid IN (%s)", implode(',', array_keys($account->roles)));

    $perm[$account->uid] = '';
    while ($row = db_fetch_object($result)) {
      $perm[$account->uid] .= "$row->perm, ";
    }
  }

Note the WHERE condition is built from $account->roles, hence the if condition should check for it, rather than checking for $user->roles. Otherwise, if $account->roles was empty you would get a SQL error.

However, you will never see this error because "roles" is never empty. In fact, checking for count() is somehow redundant, which may lead then to remove it from the IF expression, so the attached patch would have to be re-worked. I felt it was safer to check for the proper property rather than removing the check.

In other words, checking for count($user->roles) makes no sense. On the other hand, checking for count($account->roles) would avoid an SQL error, if the array was empty.

markus_petrux’s picture

Yep! jvandyk, you're right. My patch was wrong. Thanks

moshe weitzman’s picture

Assigned: Unassigned » moshe weitzman
FileSize
933 bytes

ah, i get it now. you are correct ... my recent user roles patch made it impossible that a user have no roles so lets just get rid of that clause. patch attached.

Dries’s picture

Thanks for the extra research. That certainly helped me understand the problem. Committed to HEAD. Thanks.

Dries’s picture

Status: Reviewed & tested by the community » Fixed
markus_petrux’s picture

Status: Fixed » Active

http://drupal.org/node/46239

It seems there are places where $account->roles is empty.

markus_petrux’s picture

Status: Active » Fixed
Anonymous’s picture

Status: Fixed » Closed (fixed)