It's possible to pollute the path mapping cache via calls to drupal_lookup_path().

Calling drupal_lookup_path('source', $alias) with a wrongly-cased $alias will result in the path cache containing the wrongly-cased alias. However, the very first time drupal_lookup_path('alias', $path) is called the path mapping cache gets completely destroyed and rebuilt; this time with the correctly-cased aliases, so the bad cache doesn't really hurt us as long as the calls are made in that order. However, if drupal_lookup_path('source', $alias) is called with a wrongly-cased $alias *after* drupal_lookup_path('alias', $path) is called then it will fail to find any matching entry in the cache (due to the case-sensitive array_search comparison) and it will end up polluting the cache with the wrongly-cased entry which will never get fixed.

Specifically, I saw this as a result of the interaction of some contrib modules. Global Redirect couldn't retrieve the correctly-cased version of the alias without clearing the path cache. See a few related issues where this problem has arisen:
#2048137: Canonical redirect breaks path cache
#2400521: Breaks path cache
#1983954: Case Sensitive URL Checking does not works when enable both boost and redirect

To reproduce:

  1. Shield and Global Redirect modules installed
  2. Configured Global Redirect to redirect all requests to the correctly-cased version of an alias
  3. Have an alias content/test
  4. Attempt to access content/tESt
  5. Page loads at content/tESt without redirecting me to the correct path (content/test)

Comments

azinck’s picture

Status: Active » Needs review
StatusFileSize
new1.76 KB
azinck’s picture

Title: Calling drupal_get_path_alias() in hook boot pollutes path cache » Path cache won't always contain the canonical alias, depending on order of calls to drupal_lookup_path()

Have looked into this a bit more. Here's the problem in a nutshell:

Calling drupal_lookup_path('source', $alias) with a wrongly-cased $alias will result in the path cache containing the wrongly-cased alias. However, the very first time drupal_lookup_path('alias', $path) is called the path mapping cache gets completely destroyed and rebuilt; this time with the correctly-cased aliases, so the bad cache doesn't really hurt us as long as the calls are made in that order. However, if drupal_lookup_path('source', $alias) is called with a wrongly-cased $alias *after* drupal_lookup_path('alias', $path) is called then it will fail to find any matching entry in the cache (due to the case-sensitive array_search comparison) and it will end up polluting the cache with the wrongly-cased entry which will never get fixed.

As far as I can tell these findings further confirm the validity of the patch in #1.

azinck’s picture

StatusFileSize
new2.29 KB
new560 bytes

Small tweak that's tangentially related to the initial issue. IMO calling drupal_get_path_alias('nOde/123') should return the same thing as drupal_get_path_alias('node/123'). We're otherwise treating the paths the same so I don't see any rationale for handling the alias lookup differently.

azinck’s picture

Issue summary: View changes
azinck’s picture

Issue summary: View changes
heddn’s picture

Can we confirm this isn't an issue in D8? With the re-done routing, this is almost certainly not an issue, but it never hurts to confirm.

jamesdevware’s picture

eugene bocharov’s picture

Encountered the same problem with boost module enabled. After some debugging came to the same approache as #1. The patch works fine, thanks.
Not sure about the addition in #3

-      elseif (!isset($cache['whitelist'][strtok($path, '/')])) {
+      elseif (!isset($cache['whitelist'][strtolower(strtok($path, '/'))])) {
         return FALSE;
       }

I think system paths not necessarily should be lowercase, maybe a custom module could provide menu item with upper letters in it.

But #1 patch is fine by me.

Status: Needs review » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.