From d520dc7c0dd7d4f3055c1df649796609f21c6581 Mon Sep 17 00:00:00 2001
From: Pieter Frenssen <pieter@frenssen.be>
Date: Thu, 13 Sep 2012 21:59:35 +0200
Subject: [PATCH 1/2] Issue #1783704 by pfrenssen: Test that paths can be
 matched to large patterns in drupal_match_path().

---
 .../lib/Drupal/system/Tests/Path/MatchPathTest.php   | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/MatchPathTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/MatchPathTest.php
index a5cbfee..5f6d675 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Path/MatchPathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Path/MatchPathTest.php
@@ -128,4 +128,24 @@ class MatchPathTest extends WebTestBase {
       ),
     );
   }
+
+  /**
+   * Tests that paths can be matched to large patterns.
+   */
+  function testDrupalMatchPathLargePattern() {
+    // Create a large patterns string.
+    $patterns = array();
+    for ($i = 0 ; $i < 20000 ; $i++) {
+      $patterns[] = "node/$i";
+    }
+    $patterns = implode("\n", $patterns);
+
+    // Try a matching path.
+    $result = drupal_match_path('node/19999', $patterns);
+    $this->assertTrue($result, t('A matching path was found in a large patterns string.'));
+
+    // Try a non-matching path.
+    $result = drupal_match_path('node/20000', $patterns);
+    $this->assertFalse($result, t('A non-matching path was not found in a large patterns string.'));
+  }
 }
-- 
1.7.12


From 018309f975b0bc097219efa54407279227566b70 Mon Sep 17 00:00:00 2001
From: Pieter Frenssen <pieter@frenssen.be>
Date: Thu, 13 Sep 2012 22:01:30 +0200
Subject: [PATCH 2/2] Issue #1783704 by pfrenssen: Make sure
 drupal_match_path() does not fail when matching large
 patterns.

---
 core/includes/path.inc | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/core/includes/path.inc b/core/includes/path.inc
index 07aeee5..97a69b8 100644
--- a/core/includes/path.inc
+++ b/core/includes/path.inc
@@ -341,9 +341,20 @@ function drupal_match_path($path, $patterns) {
       '\1' . preg_quote(config('system.site')->get('page.front'), '/') . '\2'
     );
     $patterns_quoted = preg_quote($patterns, '/');
-    $regexps[$patterns] = '/^(' . preg_replace($to_replace, $replacements, $patterns_quoted) . ')$/';
+    $regexps[$patterns] = preg_replace($to_replace, $replacements, $patterns_quoted);
   }
-  return (bool)preg_match($regexps[$patterns], $path);
+
+  // Process large patterns in 16K chunks to prevent preg_match() from consuming
+  // too much memory.
+  $process = $regexps[$patterns];
+  do {
+    $split = strlen($process) > 16384 ? strpos($process, '|', 16384) : strlen($process);
+    if (preg_match('/^(' . substr($process, 0 , $split) . ')$/', $path)) {
+      return TRUE;
+    }
+  } while ($process = $split < strlen($process) ? substr($process, $split + 1) : FALSE);
+
+  return FALSE;
 }
 
 /**
-- 
1.7.12

