Hi,
This week we noticed a new warning on our dev server this week:
Warning: array_fill() [function.array-fill]: Number of elements must be positive in db_placeholders() (line 276 of /var/www/sitename/includes/database.inc).
User warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1 query: SELECT p.perm FROM role r INNER JOIN permission p ON p.rid = r.rid WHERE r.rid IN () in _db_query() (line 169 of /var/www/sitename/includes/database.mysqli.inc).
Digging down I found this is caused in a call to user_access where the account variable was being set to 'administer users'.
function user_access($string, $account = NULL, $reset = FALSE)
This happens because _menu_check_access calls user_access like this:
if ($callback == 'user_access') {
$item['access'] = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]);
}
arguments[1] in this case should be the user, but instead it's the text string 'administer users' - arguments[0] is also 'administer users'.
The second entry in our case comes from views_menu_alter. The first comes from the user module hook_menu itself.
$callbacks[$path]['access arguments'][] = $item['access arguments'][0];
In the database this creates the following menu_router table entry:
*************************** 1. row ***************************
path: admin/user/user/create
load_functions:
to_arg_functions:
access_callback: user_access
access_arguments: a:2:{i:0;s:16:"administer users";i:1;s:16:"administer users";}
page_callback: user_admin
page_arguments: a:2:{i:0;s:6:"create";i:1;a:1:{i:0;s:8:"system_1";}}
fit: 15
number_parts: 4
tab_parent: admin/user/user
tab_root: admin/user/user
title: Add user
title_callback: t
title_arguments:
type: 128
block_callback:
description: List, add, and edit users.
position:
weight: 0
file: modules/user/user.admin.inc
I've attached a patch that checks to see if the access argument already exists before trying to add it. This may not be the best approach but it's fixed the issue for us. Feedback welcome.
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | access_arguments-1809412-4.patch | 853 bytes | deciphered |
| #2 | views-menu_alter_access_arguments_double-1809412-2.patch | 927 bytes | serenecloud |
| views_menu_alter_access_arguments_double.patch | 970 bytes | serenecloud |
Comments
Comment #2
serenecloud commentedPatch re-rolled in a better format
Comment #3
serenecloud commentedNeeds review
Comment #4
decipheredStill an issue in 7.x-3.8. Colleague used Admin Views and possibly cloned them or similar which made some views, including a view for 'admin/people', but upon rebuilding the menu via whatever method (installing certain modules, manually triggering, etc) a second argument would be added to the router item which messes with the expected arguments for the 'user_access()' function making the system pages inaccessible.... not good.
Re-rolled patch attached. Essentially the same patch, but for D7 and meets coding standards.
Comment #5
recrit commentedI ran into this same issue recently where views_menu_alter() would get triggered 2x and then end up with 2 perm strings in the views access arguments. This leads to the error "Trying to get property of non-object in user_access()" when the string is used as the account object in the access callback.
The patch in 4 worked for me to contain the error. Obviously, there is another bug that is causing the hook_menu to get triggered 2x but that is caused by custom or contrib modules. This patch at least mitigates the exposure if a contrib module is added to the system which does trigger this error.
Comment #6
JvE commentedThis is a duplicate of #1771140: view_menu_alter() adding to existing "access arguments" causes user_access() error.
Also, the patches in this issue do not take into account the situation where two views with the same path specifiy different permissions.
If view1 wants permission 'access content overview' on path 'admin/content' and view2 wants permission 'administer nodes' on path 'admin/content' then the patches here will cause a call of user_access('access content overview', 'administer nodes').