=== modified file 'includes/path.inc' --- includes/path.inc 2009-05-26 09:12:28 +0000 +++ includes/path.inc 2009-05-31 00:29:03 +0000 @@ -66,8 +66,16 @@ function drupal_lookup_path($action, $pa $count = NULL; $system_paths = array(); $no_aliases = array(); + + $whitelist = drupal_path_alias_whitelist_rebuild(); + variable_set('path_alias_whitelist', $whitelist); } elseif ($count > 0 && $path != '') { + // Retrieve the path alias whitelist + $whitelist = variable_get('path_alias_whitelist', array()); + // And derive the top level component of the path + $top_level = strtok($path, '/'); + if ($action == 'alias') { // During the first call to drupal_lookup_path() per language, load the // expected system paths for the page from cache. @@ -93,6 +101,12 @@ function drupal_lookup_path($action, $pa if (isset($map[$path_language][$path])) { return $map[$path_language][$path]; } + elseif (!isset($whitelist[$top_level])) { + // Check the path whitelist, if the top_level part before the first / + // is not in the list, then there is no need to do anything further, + // it is not in the database + return FALSE; + } // For system paths which were not cached, query aliases individually. else if (!isset($no_aliases[$path_language][$path])) { // Get the most fitting result falling back with alias without language @@ -347,3 +361,23 @@ function drupal_match_path($path, $patte function current_path() { return $_GET['q']; } + +/** + * Rebuild the path alias white list. + * + * @return + * An array containing a white list of path aliases. + */ +function drupal_path_alias_whitelist_rebuild() { + $whitelist = array(); + $query = db_select('url_alias', 'u'); + $query->addField('u', 'src'); + $query->range(0, 1); + while ($result = $query->execute()->fetchField()) { + $part = strtok($result, '/'); + $whitelist[$part] = TRUE; + $query->condition('src', "$part/%", 'NOT LIKE'); + $query->condition('src', $part, '<>'); + } + return $whitelist; +} === modified file 'modules/path/path.test' --- modules/path/path.test 2009-05-16 19:07:02 +0000 +++ modules/path/path.test 2009-05-31 00:45:40 +0000 @@ -235,3 +235,32 @@ class PathLanguageTestCase extends Drupa } } +class PathWhiteListTestCase extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => t('Path aliases whitelist'), + 'description' => t('Confirm that the whitelist is built correctly.'), + 'group' => t('Path'), + ); + } + + function setUp() { + parent::setUp('path'); + } + + function testWhiteList() { + // Lets create a bunch of aliases. + for ($i = 0; $i < 3; $i++) { + $prefix = $this->randomName(); + $prefixes[] = $prefix; + path_set_alias($prefix, $this->randomName()); + for ($j = 0; $j < 3; $j++) { + path_set_alias($prefix ."/$j", $this->randomName()); + } + } + sort($prefixes); + $whitelist = array_keys(drupal_path_alias_whitelist_rebuild()); + sort($whitelist); + $this->assertIdentical($prefixes, $whitelist, t('Whitelist functionality OK')); + } +} \ No newline at end of file