From a0125369e151d63566cfa23832db31cd67a916b3 Mon Sep 17 00:00:00 2001
From: Alexander Stehlik <alexander.stehlik@gmail.com>
Date: Fri, 27 Feb 2015 20:13:53 +0100
Subject: [PATCH] [BUGFIX] Escape regex chars when building sWordRegEx

The submitted sword_list GET parameters are parsed through
preg_quote() when loaded into  TSFE->sWordRegEx to prevent
invalid regular expressions.

The initialization is moved to a seperate method
PageGenerator::initializeSearchWordDataInTsfe() and unit
tests are added.

Releases: master, 6.2
Resolves: #41728
Change-Id: Id96fd5e201c25b06001f7e1c7811d6c38239aafa
Reviewed-on: http://review.typo3.org/37328
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
---
 .../frontend/Classes/Page/PageGenerator.php   | 32 +++++++----
 .../Page/Fixtures/PageGeneratorFixture.php    |  6 +++
 .../Tests/Unit/Page/PageGeneratorTest.php     | 53 +++++++++++++++++++
 3 files changed, 80 insertions(+), 11 deletions(-)

diff --git a/typo3/sysext/frontend/Classes/Page/PageGenerator.php b/typo3/sysext/frontend/Classes/Page/PageGenerator.php
index e228368928b9..fc1c4f33e9ed 100644
--- a/typo3/sysext/frontend/Classes/Page/PageGenerator.php
+++ b/typo3/sysext/frontend/Classes/Page/PageGenerator.php
@@ -106,17 +106,7 @@ class PageGenerator {
 		if ($GLOBALS['TSFE']->config['config']['setJS_openPic']) {
 			$GLOBALS['TSFE']->setJS('openPic');
 		}
-		$GLOBALS['TSFE']->sWordRegEx = '';
-		$GLOBALS['TSFE']->sWordList = GeneralUtility::_GP('sword_list');
-		if (is_array($GLOBALS['TSFE']->sWordList)) {
-			$space = !empty($GLOBALS['TSFE']->config['config']['sword_standAlone']) ? '[[:space:]]' : '';
-			foreach ($GLOBALS['TSFE']->sWordList as $val) {
-				if (trim($val) !== '') {
-					$GLOBALS['TSFE']->sWordRegEx .= $space . quotemeta($val) . $space . '|';
-				}
-			}
-			$GLOBALS['TSFE']->sWordRegEx = preg_replace('/\\|$/', '', $GLOBALS['TSFE']->sWordRegEx);
-		}
+		static::initializeSearchWordDataInTsfe();
 		// linkVars
 		$GLOBALS['TSFE']->calculateLinkVars();
 		// dtdAllowsFrames indicates whether to use the target attribute in links
@@ -1200,4 +1190,24 @@ class PageGenerator {
 		return $metaTags;
 	}
 
+	/**
+	 * Fills the sWordList property and builds the regular expression in TSFE that can be used to split
+	 * strings by the submitted search words.
+	 *
+	 * @see \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::sWordList
+	 * @see \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::sWordRegEx
+	 */
+	static protected function initializeSearchWordDataInTsfe() {
+		$GLOBALS['TSFE']->sWordRegEx = '';
+		$GLOBALS['TSFE']->sWordList = GeneralUtility::_GP('sword_list');
+		if (is_array($GLOBALS['TSFE']->sWordList)) {
+			$space = !empty($GLOBALS['TSFE']->config['config']['sword_standAlone']) ? '[[:space:]]' : '';
+			foreach ($GLOBALS['TSFE']->sWordList as $val) {
+				if (trim($val) !== '') {
+					$GLOBALS['TSFE']->sWordRegEx .= $space . preg_quote($val, '/') . $space . '|';
+				}
+			}
+			$GLOBALS['TSFE']->sWordRegEx = rtrim($GLOBALS['TSFE']->sWordRegEx, '|');
+		}
+	}
 }
diff --git a/typo3/sysext/frontend/Tests/Unit/Page/Fixtures/PageGeneratorFixture.php b/typo3/sysext/frontend/Tests/Unit/Page/Fixtures/PageGeneratorFixture.php
index 85e837b8b3c2..0d96f4e9ca18 100644
--- a/typo3/sysext/frontend/Tests/Unit/Page/Fixtures/PageGeneratorFixture.php
+++ b/typo3/sysext/frontend/Tests/Unit/Page/Fixtures/PageGeneratorFixture.php
@@ -36,4 +36,10 @@ class PageGeneratorFixture extends PageGenerator {
 		return self::generateMetaTagHtml($metaTagTypoScript, $xhtml, $cObj);
 	}
 
+	/**
+	 * Public accessor for the initializeSearchWordDataInTsfe() method.
+	 */
+	public function callInitializeSearchWordDataInTsfe() {
+		static::initializeSearchWordDataInTsfe();
+	}
 }
\ No newline at end of file
diff --git a/typo3/sysext/frontend/Tests/Unit/Page/PageGeneratorTest.php b/typo3/sysext/frontend/Tests/Unit/Page/PageGeneratorTest.php
index d638ffee9a10..6fffa656c9d2 100644
--- a/typo3/sysext/frontend/Tests/Unit/Page/PageGeneratorTest.php
+++ b/typo3/sysext/frontend/Tests/Unit/Page/PageGeneratorTest.php
@@ -146,4 +146,57 @@ class PageGeneratorTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 		$this->assertSame($expectedTags, $result);
 	}
 
+	/**
+	 * @return array
+	 */
+	public function initializeSearchWordDataInTsfeBuildsCorrectRegexDataProvider() {
+		return array(
+			'one simple search word' => array(
+				array('test'),
+				FALSE,
+				'test',
+			),
+			'one simple search word with standalone words' => array(
+				array('test'),
+				TRUE,
+				'[[:space:]]test[[:space:]]',
+			),
+			'two simple search words' => array(
+				array('test', 'test2'),
+				FALSE,
+				'test|test2',
+			),
+			'two simple search words with standalone words' => array(
+				array('test', 'test2'),
+				TRUE,
+				'[[:space:]]test[[:space:]]|[[:space:]]test2[[:space:]]',
+			),
+			'word with regex chars' => array(
+				array('A \\ word with / a bunch of [] regex () chars .*'),
+				FALSE,
+				'A  word with \\/ a bunch of \\[\\] regex \\(\\) chars \\.\\*',
+			),
+		);
+	}
+
+	/**
+	 * @test
+	 * @dataProvider initializeSearchWordDataInTsfeBuildsCorrectRegexDataProvider
+	 *
+	 * @param array $searchWordGetParameters The values that should be loaded in the sword_list GET parameter.
+	 * @param bool $enableStandaloneSearchWords If TRUE the sword_standAlone option will be enabled.
+	 * @param string $expectedRegex The expected regex after processing the search words.
+	 */
+	public function initializeSearchWordDataInTsfeBuildsCorrectRegex(array $searchWordGetParameters, $enableStandaloneSearchWords, $expectedRegex) {
+
+		$_GET['sword_list'] = $searchWordGetParameters;
+
+		$GLOBALS['TSFE'] = new \stdClass();
+		if ($enableStandaloneSearchWords) {
+			$GLOBALS['TSFE']->config = array('config' => array('sword_standAlone' => 1));
+		}
+
+		$this->pageGeneratorFixture->callInitializeSearchWordDataInTsfe();
+		$this->assertEquals($GLOBALS['TSFE']->sWordRegEx, $expectedRegex);
+	}
 }
-- 
GitLab