Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 295826

Warning: Invalid argument supplied for foreach() in menu_unserialize() if unserialize returns non-array value

$
0
0

Problem/Motivation

Sometimes lots of the following error is raised in function menu_unserialize():

warning: Invalid argument supplied for foreach() in .../includes/menu.inc.

This is caused by ill-programmed contrib/custom modules, that do not store the argument list in array-format (of course, mostly when there are 0 or 1 arguments).

Proposed resolution

The proposed patches in the issue queue all are trying to detect the error in on the page load.
We shouldn't do this, and a error detaction needs to be done on database-insertion.

As the originator.. I somewhat agree with "not babysitting broken code," however there is that long standing strategy of defensive coding (Kernighan & Plauger) to think about. And as will_in_wi said (http://drupal.org/node/277018#comment-1521118) it's valuable to a module developer help them work out where problems are, rather than leave them mystified.

The strategy of doing the check at the database insertion sounds far far far far better ...

Remaining tasks

Locate where the error is generated, and write a patch for that.

User interface changes

None.

API changes

None.

(A list of related issues.)

Original report by [username]

(Text of the original report, for legacy issues whose initial post was not the issue summary. Use rarely.)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.


Viewing all articles
Browse latest Browse all 295826

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>