menu_unserialize can throw unsightly messages if unserialize returns non-array value
| Project: | Drupal |
| Version: | 7.x-dev |
| Component: | menu system |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Jump to:
I have a partially working module and when the module is active the following message is printed multiple times
warning: Invalid argument supplied for foreach() in /home/.nurse/reikiman/davidherron.com/includes/menu.inc on line 258.Clearly the module has done something to cause this message to exist.. but ignore my module for the moment because I want to point to an issue with the above function.
At line 258 in menu.inc is the function menu_unserialize. It goes
if ($data = unserialize($data)) {
foreach ($data as $k => $v) { // line 258
...
}
}According to the unserialize documentation -- http://us3.php.net/manual/en/function.unserialize.php -- the function can succeed and return something other than an array. If the function fails FALSE is returned, and menu_unserialize would skip over the whole thing. Clearly unserialize is returning something other than FALSE and the documentation says "can be a boolean, integer, float, string, array or object".
Hmm... http://drupal.org/node/197056#comment-653073 ... that note may be applicable in my situation. In any case since unserialize can legitimately return something other than an array it would be good for menu_unserialize to be more robust about the data it receives.
If I change this to
if ($data = unserialize($data)) {
if (is_array($data)) {
foreach ($data as $k => $v) { // line 258
...
}
} else {
watchdog('menu', 'menu_unserialize problem %data', array('%data'=>$data), WATCHDOG_ERROR);
}
}In this case the unsightly error isn't printed on the page but the watchdog entries don't tell me anything useful.

#1
Actually... the comment here http://drupal.org/node/197056#comment-653073 is very applicable to my situation.
However.. a better error could be printed if the unserialize in menu_unserialize returns a non-array.
Such as:-
function menu_unserialize($data_s, $map) {if ($data = unserialize($data_s)) {
if (is_array($data)) {
foreach ($data as $k => $v) {
if (is_int($v)) {
$data[$k] = isset($map[$v]) ? $map[$v] : '';
}
}
} else {
watchdog('menu', 'unserialize returned non-array for %data', array('%data' => $data_s), WATCHDOG_ERROR);
}
return $data;
}
else {
return array();
}
}
#2
bugs need to be fixed in 7.x first