From 2f9c1bc3047b0b66469efa7137e530702cdf0c91 Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole Date: Mon, 22 Sep 2014 12:33:26 +0100 Subject: [PATCH] Issue #1860594 by penyaskito, damiankloip, xjm, alexpott, sun: Ensure that randomString() always returns a character that needs to be escaped for HTML. --- core/modules/simpletest/src/TestBase.php | 21 +++++++++++++++---- .../tests/src/Unit/TestBaseTest.php | 17 +++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php index a4cfe98c518..171df78443d 100644 --- a/core/modules/simpletest/src/TestBase.php +++ b/core/modules/simpletest/src/TestBase.php @@ -1283,22 +1283,35 @@ abstract class TestBase { } /** - * Generates a unique random string of ASCII characters of codes 32 to 126. + * Generates a pseudo-random string of ASCII characters of codes 32 to 126. * * Do not use this method when special characters are not possible (e.g., in * machine or file names that have already been validated); instead, use - * \Drupal\simpletest\TestBase::randomMachineName(). + * \Drupal\simpletest\TestBase::randomMachineName(). If $length is greater + * than 2 the random string will include at least one ampersand ('&') + * character to ensure coverage for special characters and avoid the + * introduction of random test failures. * * @param int $length * Length of random string to generate. * * @return string - * Randomly generated unique string. + * Pseudo-randomly generated unique string including special characters. * * @see \Drupal\Component\Utility\Random::string() */ public function randomString($length = 8) { - return $this->getRandomGenerator()->string($length, TRUE, array($this, 'randomStringValidate')); + if ($length < 3) { + return $this->getRandomGenerator()->string($length, TRUE, array($this, 'randomStringValidate')); + } + + // To prevent the introduction of random test failures, ensure that the + // returned string contains a character that needs to be escaped in HTML by + // injecting an ampersand into it. + $replacement_pos = floor($length / 2); + // Remove 1 from the length to account for the ampersand character. + $string = $this->getRandomGenerator()->string($length - 1, TRUE, array($this, 'randomStringValidate')); + return substr_replace($string, '&', $replacement_pos, 0); } /** diff --git a/core/modules/simpletest/tests/src/Unit/TestBaseTest.php b/core/modules/simpletest/tests/src/Unit/TestBaseTest.php index bce3a83409f..9bac4fc39bb 100644 --- a/core/modules/simpletest/tests/src/Unit/TestBaseTest.php +++ b/core/modules/simpletest/tests/src/Unit/TestBaseTest.php @@ -63,4 +63,21 @@ class TestBaseTest extends UnitTestCase { $this->assertEquals($expected, $actual); } + /** + * Tests that the random string contains a non-alphanumeric character. + * + * @see \Drupal\simpletest\TestBase::randomString(). + * + * @covers ::randomString + */ + public function testRandomString() { + $string = $this->stub->randomString(8); + $this->assertEquals(8, strlen($string)); + $this->assertContains('&', $string); + + // Ensure that we can generate random strings with a length of 1. + $string = $this->stub->randomString(1); + $this->assertEquals(1, strlen($string)); + } + }