menu_unserialize can throw unsightly messages if unserialize returns non-array value

reikiman - July 1, 2008 - 02:32
Project:Drupal
Version:7.x-dev
Component:menu system
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active
Description

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

reikiman - July 1, 2008 - 02:39
Title:menu_unserialize can throw unsightly messages if there's an unserialization problem» menu_unserialize can throw unsightly messages if unserialize returns non-array value

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

pwolanin - July 1, 2008 - 13:07
Version:6.2» 7.x-dev

bugs need to be fixed in 7.x first

 
 

Drupal is a registered trademark of Dries Buytaert.