? d7menutest.kpf
? menutest.patch
? sites/all/modules
? sites/default/files
? sites/default/settings.php
Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.279
diff -u -p -r1.279 menu.inc
--- includes/menu.inc	1 Jul 2008 20:36:40 -0000	1.279
+++ includes/menu.inc	3 Jul 2008 07:58:22 -0000
@@ -2272,6 +2272,10 @@ function _menu_router_build($callbacks) 
             $match = TRUE;
           }
         }
+        // If no match was found, and particularly if neither the _load or the
+        // _to_arg functions exist, skip this item and don't record any entry
+        // for it in the menu_router table.
+        if (!$match) { continue 2; }
       }
       if ($match) {
         $parts[$k] = '%';
Index: includes/tests/menu.test
===================================================================
RCS file: includes/tests/menu.test
diff -N includes/tests/menu.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/tests/menu.test	3 Jul 2008 07:58:22 -0000
@@ -0,0 +1,40 @@
+<?php
+
+class MenuRouterTestCase extends DrupalWebTestCase {
+
+  /**
+   * Implementation of getInfo().
+   */
+  function getInfo() {
+    return array(
+      'name' => t('Menu router loader test'),
+      'description' => t('Try building the {menu_router} table with non-existent argument load functions and prove that they do not result in router items being saved.'),
+      'group' => t('System')
+    );
+  }
+  
+  /**
+   * Menu items that have load handlers shouldn't get saved during rebuild if
+   * the load handler function doesn't exist.
+   * See http://drupal.org/node/277849
+   */
+  function testMissingLoader() {
+    // There is no foo_load.
+    $callbacks['something/%foo'] = array();
+    // node_load exits.
+    $callbacks['something/%node/else'] = array();
+    // Build the router items.
+    _menu_router_build($callbacks);
+    // Paths like 'something/%foo', where %foo doesn't get reduced to %, should never get put into the 
+    // menu_router table.
+    $count = db_result(db_query("SELECT count(*) FROM {menu_router} WHERE path = '%s'", 'something/%foo'));
+    $this->assertFalse(drupal_function_exists('foo_load'), "Function foo_load doesn't exit");
+    $this->assertFalse($count, "Menu router path something/%foo is not allowed because the function foo_load doesn't exist");
+    $count = db_result(db_query("SELECT count(*) FROM {menu_router} WHERE path = '%s'", 'something/%'));
+    $this->assertFalse($count, "Menu router path something/% is not allowed because the function foo_load doesn't exist");
+    $count = db_result(db_query("SELECT count(*) FROM {menu_router} WHERE path = 'something/%/else'"));
+    $this->assertTrue(drupal_function_exists('node_load'), 'Function node_load exists');
+    $this->assertTrue($count, "$count Menu router path something/%/else is allowed because the function node_load does exist");
+  }
+}
+
