When a menu item has a negative pid, menu_rebuild() is thrown into an infinite loop. This patch is an easy fix that deletes the unnecessary while loop that causes the problem.

Comments

chx’s picture

Allie, please refer to http://drupal.org/node/42388#comment-80806 and tell us how have you achieved such a menu.

hunmonk’s picture

Status: Active » Needs work

it looks to me like we can't take out the while loop--wouldn't that cause child menu items to be missed? menu stuff isn't my strength, but it looks to me like the solution would be to move the unset($new_items[$mid]); outside of the if statement--it doesn't look like anything was being done w/ those kinds of menu items anyways, and this will empty them from the array. anyone?

merlinofchaos’s picture

Those code causes an infinite loop.

function tempcustom_menu($may_cache) {
  if ($may_cache) {
    $items[] = array(
      'path' => 'publishing/author',
      'title' => t('author dashboard'),
      'callback' => 'publishing_author_page',
      'access' => 1,
    );
    $items[] = array(
      'path' => 'publishing/editor',
      'title' => t('editor dashboard'),
      'callback' => 'publishing_editor_page',
      'access' => 1,
    );
    $items[] = array(
      'path' => 'publishing',
      'title' => t('editor dashboard'),
      'callback' => 'publishing_editor_page',
      'access' => 1,
      'type' => MENU_CALLBACK,
    );

  }
  return $items;
}

This code causes an infinite loop because:

1) publishing, the parent menu for publishing/author and publishing/editor is a MENU_CALLBACK which does not contain MENU_MODIFIABLE_BY_ADMIN. Therefore, it is not considered a 'new item', since it can't be saved to the database. However, it *is* the parent item.

2) The new items loop (line 600, menu.inc) will NOT EXIT if it can't find a saved-to-the-db parent for all items. However, since 'publishing', above, is never saved to the DB, its pid will always be negative.

Crash. Burn.

chx’s picture

Assigned: Unassigned » chx
Status: Needs work » Reviewed & tested by the community
StatusFileSize
new485 bytes

mmm, I like this, reproduce code included and Earl told me in IRC how to fix it. All I needed to do was a little coding and testing. I wish every bug report was solved this easily.

merlinofchaos’s picture

StatusFileSize
new749 bytes

I think your while loop needs to check that count($new_items) && count($new_items != $old_count).

I came up with this version to try and avoid hitting count() more than necessary.

chx’s picture

StatusFileSize
new485 bytes

Or this way.

chx’s picture

StatusFileSize
new500 bytes

Wrong version posted.

killes@www.drop.org’s picture

Status: Reviewed & tested by the community » Fixed

applied

laura s’s picture

This fixed a problem I was having with 4.7RC2. Wonderful! Thank you!

Anonymous’s picture

Status: Fixed » Closed (fixed)