previousLocaleSetting = null; } protected function tearDown(): void { parent::tearDown(); // If a test sets the locale, reset it on teardown if ($this->previousLocaleSetting) { setlocale(LC_CTYPE, $this->previousLocaleSetting); } } /** * Tests {@link Convert::raw2att()} */ public function testRaw2Att() { $val1 = ''; $this->assertEquals( '<input type="text">', Convert::raw2att($val1), 'Special characters are escaped' ); $val2 = 'This is some normal text.'; $this->assertEquals( 'This is some normal text.', Convert::raw2att($val2), 'Normal text is not escaped' ); } /** * Tests {@link Convert::raw2htmlatt()} */ public function testRaw2HtmlAtt() { $val1 = ''; $this->assertEquals( '<input type="text">', Convert::raw2htmlatt($val1), 'Special characters are escaped' ); $val2 = 'This is some normal text.'; $this->assertEquals( 'This is some normal text.', Convert::raw2htmlatt($val2), 'Normal text is not escaped' ); } /** * Tests {@link Convert::html2raw()} */ public function testHtml2raw() { $val1 = 'This has a strong tag.'; $this->assertEquals( 'This has a *strong tag*.', Convert::html2raw($val1), 'Strong tags are replaced with asterisks' ); $val1 = 'This has a b tag with attributes.'; $this->assertEquals( 'This has a *b tag with attributes*.', Convert::html2raw($val1), 'B tags with attributes are replaced with asterisks' ); $val2 = 'This has a strong tag with attributes.'; $this->assertEquals( 'This has a *strong tag with attributes*.', Convert::html2raw($val2), 'Strong tags with attributes are replaced with asterisks' ); $val3 = ''; $this->assertEquals( '', Convert::html2raw($val3), 'Script tags are completely removed' ); $val4 = ''; $this->assertEquals( '', Convert::html2raw($val4), 'Style tags are completely removed' ); $val5 = ""; $this->assertEquals( '', Convert::html2raw($val5), 'Multiline script tags are completely removed' ); $val6 = ""; $this->assertEquals( '', Convert::html2raw($val6), 'Multiline style tags are completely removed' ); $val7 = '

That's absolutely correct

'; $this->assertEquals( "That's absolutely correct", Convert::html2raw($val7), 'Single quotes are decoded correctly' ); $val8 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ' . 'incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud ' . 'exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute ' . 'irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla ' . 'pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia ' . 'deserunt mollit anim id est laborum.'; $this->assertEquals($val8, Convert::html2raw($val8), 'Test long text is unwrapped'); $this->assertEquals( <<assertEquals( '<input type="text">', Convert::raw2xml($val1), 'Special characters are escaped' ); $val2 = 'This is some normal text.'; $this->assertEquals( 'This is some normal text.', Convert::raw2xml($val2), 'Normal text is not escaped' ); $val3 = "This is test\nNow on a new line."; $this->assertEquals( "This is test\nNow on a new line.", Convert::raw2xml($val3), 'Newlines are retained. They should not be replaced with
as it is not XML valid' ); } /** * Tests {@link Convert::raw2htmlid()} */ public function testRaw2HtmlID() { $val1 = 'test test 123'; $this->assertEquals('test_test_123', Convert::raw2htmlid($val1)); $val2 = 'test[test][123]'; $this->assertEquals('test_test_123', Convert::raw2htmlid($val2)); $val3 = '[test[[test]][123]]'; $this->assertEquals('test_test_123', Convert::raw2htmlid($val3)); $val4 = 'A\\Namespaced\\Class'; $this->assertEquals('A_Namespaced_Class', Convert::raw2htmlid($val4)); } /** * Tests {@link Convert::xml2raw()} */ public function testXml2Raw() { $val1 = '<input type="text">'; $this->assertEquals('', Convert::xml2raw($val1), 'Special characters are escaped'); $val2 = 'This is some normal text.'; $this->assertEquals('This is some normal text.', Convert::xml2raw($val2), 'Normal text is not escaped'); } /** * Tests {@link Convert::testRaw2URL()} * * @todo test toASCII() */ public function testRaw2URL() { URLSegmentFilter::config()->set('default_allow_multibyte', false); $this->assertEquals('foo', Convert::raw2url('foo')); $this->assertEquals('foo-and-bar', Convert::raw2url('foo & bar')); $this->assertEquals('foo-and-bar', Convert::raw2url('foo & bar!')); $this->assertEquals('foos-bar-2', Convert::raw2url('foo\'s [bar] (2)')); } /** * Helper function for comparing characters with significant whitespaces * * @param string $expected * @param string $actual */ protected function assertEqualsQuoted($expected, $actual) { $message = sprintf( 'Expected "%s" but given "%s"', addcslashes($expected ?? '', "\r\n"), addcslashes($actual ?? '', "\r\n") ); $this->assertEquals($expected, $actual, $message); } /** * Tests {@link Convert::nl2os()} */ public function testNL2OS() { foreach (["\r\n", "\r", "\n"] as $nl) { // Base case: no action $this->assertEqualsQuoted( 'Base case', Convert::nl2os('Base case', $nl) ); // Mixed formats $this->assertEqualsQuoted( "Test{$nl}Text{$nl}Is{$nl}{$nl}Here{$nl}.", Convert::nl2os("Test\rText\r\nIs\n\rHere\r\n.", $nl) ); // Test that multiple runs are non-destructive $expected = "Test{$nl}Text{$nl}Is{$nl}{$nl}Here{$nl}."; $this->assertEqualsQuoted( $expected, Convert::nl2os($expected, $nl) ); // Check repeated sequence behaves correctly $expected = "{$nl}{$nl}{$nl}{$nl}{$nl}{$nl}{$nl}{$nl}"; $input = "\r\r\n\r\r\n\n\n\n\r"; $this->assertEqualsQuoted( $expected, Convert::nl2os($input, $nl) ); } } /** * Tests {@link Convert::raw2js()} */ public function testRaw2JS() { // Test attempt to break out of string $this->assertEquals( '\\"; window.location=\\"http://www.google.com', Convert::raw2js('"; window.location="http://www.google.com') ); $this->assertEquals( '\\\'; window.location=\\\'http://www.google.com', Convert::raw2js('\'; window.location=\'http://www.google.com') ); // Test attempt to close script tag $this->assertEquals( '\\"; \\x3c/script\\x3e\\x3ch1\\x3eHa \\x26amp; Ha\\x3c/h1\\x3e\\x3cscript\\x3e', Convert::raw2js('";

Ha & Ha