Chad has uploaded a new change for review. https://gerrit.wikimedia.org/r/304154
Change subject: Remove support for $wgWellFormedXml=false ...................................................................... Remove support for $wgWellFormedXml=false tl;dr: Having unnessary complexity in security critical code is bad. * When PHP is built with certain versions of libpcre, can lead to XSS * Extra options add extra complexity and maintenance burden ** Thus we should only have one html output mode. well formed = false was already vetoed in T52040, so lets go with WellFormed=true. * Options which are used by very few people tend to get tested less * Escaping is an area of code where we should be very conservative * Having escaping rules depend on making assumptions about which characters various browsers consider "whitespace" is scary * $wgWellFormedXml=false has had a negative security impact in the past (Usually not directly its fault, but has made other bugs more exploitable) * Saving a couple bytes (even less bytes after gzip taken into account) is really not worth it in this context (imho). Incidentally, this backports the removal of the space before the closing '/>' of a self-closed tag from dd2d7d0ffc. Bug: T57548 Change-Id: I5c922e0980d3f9eb39adb5bb5833e158afda42ed --- M includes/DefaultSettings.php M includes/Html.php M tests/parser/parserTest.inc M tests/parser/parserTests.txt M tests/phpunit/includes/HtmlTest.php M tests/phpunit/includes/LinkerTest.php M tests/phpunit/includes/OutputPageTest.php M tests/phpunit/includes/XmlSelectTest.php M tests/phpunit/includes/XmlTest.php M tests/phpunit/includes/content/JsonContentTest.php M tests/phpunit/includes/parser/NewParserTest.php 11 files changed, 147 insertions(+), 249 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/54/304154/1 diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 7498a02..1a97dac 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -3091,24 +3091,6 @@ $wgAllowMicrodataAttributes = false; /** - * Should we try to make our HTML output well-formed XML? If set to false, - * output will be a few bytes shorter, and the HTML will arguably be more - * readable. If set to true, life will be much easier for the authors of - * screen-scraping bots, and the HTML will arguably be more readable. - * - * Setting this to false may omit quotation marks on some attributes, omit - * slashes from some self-closing tags, omit some ending tags, etc., where - * permitted by HTML5. Setting it to true will not guarantee that all pages - * will be well-formed, although non-well-formed pages should be rare and it's - * a bug if you find one. Conversely, setting it to false doesn't mean that - * all XML-y constructs will be omitted, just that they might be. - * - * Because of compatibility with screen-scraping bots, and because it's - * controversial, this is currently left to true by default. - */ -$wgWellFormedXml = true; - -/** * Permit other namespaces in addition to the w3.org default. * * Use the prefix for the key and the namespace for the value. diff --git a/includes/Html.php b/includes/Html.php index 62ae0b8..c49cca4 100644 --- a/includes/Html.php +++ b/includes/Html.php @@ -38,8 +38,6 @@ * * $wgMimeType: If this is set to an xml MIME type then output should be * valid XHTML5. - * $wgWellFormedXml: If this is set to true, then all output should be - * well-formed XML (quotes on attributes, self-closing tags, etc.). * * This class is meant to be confined to utility functions that are called from * trusted code paths. It does not do enforcement of policy like not allowing @@ -199,8 +197,7 @@ * This is quite similar to Xml::tags(), but it implements some useful * HTML-specific logic. For instance, there is no $allowShortTag * parameter: the closing tag is magically omitted if $element has an empty - * content model. If $wgWellFormedXml is false, then a few bytes will be - * shaved off the HTML output as well. + * content model. * * @param string $element The element's name, e.g., 'a' * @param array $attribs Associative array of attributes, e.g., array( @@ -211,14 +208,10 @@ * @return string Raw HTML */ public static function rawElement( $element, $attribs = array(), $contents = '' ) { - global $wgWellFormedXml; $start = self::openElement( $element, $attribs ); if ( in_array( $element, self::$voidElements ) ) { - if ( $wgWellFormedXml ) { - // Silly XML. - return substr( $start, 0, -1 ) . ' />'; - } - return $start; + // Silly XML. + return substr( $start, 0, -1 ) . '/>'; } else { return "$start$contents" . self::closeElement( $element ); } @@ -445,8 +438,6 @@ * 'http://www.mediawiki.org/' ) becomes something like * ' href="http://www.mediawiki.org"'. Again, this is like * Xml::expandAttributes(), but it implements some HTML-specific logic. - * For instance, it will omit quotation marks if $wgWellFormedXml is false, - * and will treat boolean attributes specially. * * Attributes that can contain space-separated lists ('class', 'accesskey' and 'rel') array * values are allowed as well, which will automagically be normalized @@ -481,8 +472,6 @@ * (starting with a space if at least one attribute is output) */ public static function expandAttributes( array $attribs ) { - global $wgWellFormedXml; - $ret = ''; foreach ( $attribs as $key => $value ) { // Support intuitive array( 'checked' => true/false ) form @@ -566,31 +555,10 @@ throw new MWException( "HTML attribute $key can not contain a list of values" ); } - // See the "Attributes" section in the HTML syntax part of HTML5, - // 9.1.2.3 as of 2009-08-10. Most attributes can have quotation - // marks omitted, but not all. (Although a literal " is not - // permitted, we don't check for that, since it will be escaped - // anyway.) - - // See also research done on further characters that need to be - // escaped: http://code.google.com/p/html5lib/issues/detail?id=93 - $badChars = "\\x00- '=<>`/\x{00a0}\x{1680}\x{180e}\x{180F}\x{2000}\x{2001}" - . "\x{2002}\x{2003}\x{2004}\x{2005}\x{2006}\x{2007}\x{2008}\x{2009}" - . "\x{200A}\x{2028}\x{2029}\x{202F}\x{205F}\x{3000}"; - if ( $wgWellFormedXml || $value === '' || preg_match( "![$badChars]!u", $value ) ) { - $quote = '"'; - } else { - $quote = ''; - } + $quote = '"'; if ( in_array( $key, self::$boolAttribs ) ) { - // In HTML5, we can leave the value empty. If we don't need - // well-formed XML, we can omit the = entirely. - if ( !$wgWellFormedXml ) { - $ret .= " $key"; - } else { - $ret .= " $key=\"\""; - } + $ret .= " $key=\"\""; } else { // Apparently we need to entity-encode \n, \r, \t, although the // spec doesn't mention that. Since we're doing strtr() anyway, @@ -602,22 +570,18 @@ // don't because we're stubborn and like our marginal savings on // byte size from not having to encode unnecessary quotes. // The only difference between this transform and the one by - // Sanitizer::encodeAttribute() is '<' is only encoded here if - // $wgWellFormedXml is set, and ' is not encoded. + // Sanitizer::encodeAttribute() is ' is not encoded. $map = array( '&' => '&', '"' => '"', '>' => '>', + // '<' allegedly allowed per spec + // but breaks some tools if not escaped. + "<" => '<', "\n" => ' ', "\r" => ' ', "\t" => '	' ); - if ( $wgWellFormedXml ) { - // This is allowed per spec: <http://www.w3.org/TR/xml/#NT-AttValue> - // But reportedly it breaks some XML tools? - // @todo FIXME: Is this really true? - $map['<'] = '<'; - } $ret .= " $key=$quote" . strtr( $value, $map ) . $quote; } } @@ -634,11 +598,9 @@ * @return string Raw HTML */ public static function inlineScript( $contents ) { - global $wgWellFormedXml; - $attrs = array(); - if ( $wgWellFormedXml && preg_match( '/[<&]/', $contents ) ) { + if ( preg_match( '/[<&]/', $contents ) ) { $contents = "/*<![CDATA[*/$contents/*]]>*/"; } @@ -668,9 +630,7 @@ * @return string Raw HTML */ public static function inlineStyle( $contents, $media = 'all' ) { - global $wgWellFormedXml; - - if ( $wgWellFormedXml && preg_match( '/[<&]/', $contents ) ) { + if ( preg_match( '/[<&]/', $contents ) ) { $contents = "/*<![CDATA[*/$contents/*]]>*/"; } diff --git a/tests/parser/parserTest.inc b/tests/parser/parserTest.inc index f429c30..303ef6f 100644 --- a/tests/parser/parserTest.inc +++ b/tests/parser/parserTest.inc @@ -882,7 +882,6 @@ 'wgExperimentalHtmlIds' => false, 'wgExternalLinkTarget' => false, 'wgHtml5' => true, - 'wgWellFormedXml' => true, 'wgAllowMicrodataAttributes' => true, 'wgAdaptiveMessageCache' => true, 'wgDisableLangConversion' => false, diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt index 67da1f0..8181692 100644 --- a/tests/parser/parserTests.txt +++ b/tests/parser/parserTests.txt @@ -4737,7 +4737,7 @@ !! wikitext External image: http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png !! html -<p>External image: <img src="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png" /> +<p>External image: <img src="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png"/> </p> !! end @@ -4746,7 +4746,7 @@ !! wikitext External image from https: https://meta.wikimedia.org/upload/f/f1/Ncwikicol.png !! html -<p>External image from https: <img src="https://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png" /> +<p>External image from https: <img src="https://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png"/> </p> !! end @@ -4820,7 +4820,7 @@ !! wikitext ja-style clickable images: [http://example.com http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png] !! html/php -<p>ja-style clickable images: <a rel="nofollow" class="external text" href="http://example.com"><img src="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png" /></a> +<p>ja-style clickable images: <a rel="nofollow" class="external text" href="http://example.com"><img src="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png"/></a> </p> !! html/parsoid <p>ja-style clickable images: <a rel="mw:ExtLink" href="http://example.com"><img src="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png" data-parsoid='{"type":"extlink"}'/></a></p> @@ -20499,7 +20499,7 @@ !! wikitext http://www.example.org/pic.png <-- U+3000 (vim: ^Vu3000) !! html -<p><img src="http://www.example.org/pic.png" alt="pic.png" /> <-- U+3000 (vim: ^Vu3000) +<p><img src="http://www.example.org/pic.png" alt="pic.png"/> <-- U+3000 (vim: ^Vu3000) </p> !! end diff --git a/tests/phpunit/includes/HtmlTest.php b/tests/phpunit/includes/HtmlTest.php index c5797c4..ee8452b 100644 --- a/tests/phpunit/includes/HtmlTest.php +++ b/tests/phpunit/includes/HtmlTest.php @@ -37,7 +37,6 @@ 'wgLanguageCode' => $langCode, 'wgContLang' => $langObj, 'wgLang' => $langObj, - 'wgWellFormedXml' => false, ) ); } @@ -46,7 +45,7 @@ */ public function testElementBasics() { $this->assertEquals( - '<img>', + '<img/>', Html::element( 'img', null, '' ), 'No close tag for short-tag elements' ); @@ -63,12 +62,10 @@ 'Close tag for empty element (array, string)' ); - $this->setMwGlobals( 'wgWellFormedXml', true ); - $this->assertEquals( - '<img />', + '<img/>', Html::element( 'img', null, '' ), - 'Self-closing tag for short-tag elements (wgWellFormedXml = true)' + 'Self-closing tag for short-tag elements' ); } @@ -135,22 +132,20 @@ ); $this->assertEquals( - ' selected', + ' selected=""', Html::expandAttributes( array( 'selected' => true ) ), 'Boolean attributes have no value when value is true' ); $this->assertEquals( - ' selected', + ' selected=""', Html::expandAttributes( array( 'selected' ) ), 'Boolean attributes have no value when value is true (passed as numerical array)' ); - $this->setMwGlobals( 'wgWellFormedXml', true ); - $this->assertEquals( ' selected=""', Html::expandAttributes( array( 'selected' => true ) ), - 'Boolean attributes have empty string value when value is true (wgWellFormedXml)' + 'Boolean attributes have empty string value when value is true' ); } @@ -159,12 +154,12 @@ */ public function testExpandAttributesForNumbers() { $this->assertEquals( - ' value=1', + ' value="1"', Html::expandAttributes( array( 'value' => 1 ) ), 'Integer value is cast to a string' ); $this->assertEquals( - ' value=1.1', + ' value="1.1"', Html::expandAttributes( array( 'value' => 1.1 ) ), 'Float value is cast to a string' ); @@ -175,7 +170,7 @@ */ public function testExpandAttributesForObjects() { $this->assertEquals( - ' value=stringValue', + ' value="stringValue"', Html::expandAttributes( array( 'value' => new HtmlTestValue() ) ), 'Object value is converted to a string' ); @@ -194,43 +189,21 @@ 'Empty string is always quoted' ); $this->assertEquals( - ' key=value', + ' key="value"', Html::expandAttributes( array( 'key' => 'value' ) ), 'Simple string value needs no quotes' ); $this->assertEquals( - ' one=1', + ' one="1"', Html::expandAttributes( array( 'one' => 1 ) ), 'Number 1 value needs no quotes' ); $this->assertEquals( - ' zero=0', + ' zero="0"', Html::expandAttributes( array( 'zero' => 0 ) ), 'Number 0 value needs no quotes' ); - $this->setMwGlobals( 'wgWellFormedXml', true ); - - $this->assertEquals( - ' empty_string=""', - Html::expandAttributes( array( 'empty_string' => '' ) ), - 'Attribute values are always quoted (wgWellFormedXml): Empty string' - ); - $this->assertEquals( - ' key="value"', - Html::expandAttributes( array( 'key' => 'value' ) ), - 'Attribute values are always quoted (wgWellFormedXml): Simple string' - ); - $this->assertEquals( - ' one="1"', - Html::expandAttributes( array( 'one' => 1 ) ), - 'Attribute values are always quoted (wgWellFormedXml): Number 1' - ); - $this->assertEquals( - ' zero="0"', - Html::expandAttributes( array( 'zero' => 0 ) ), - 'Attribute values are always quoted (wgWellFormedXml): Number 0' - ); } /** @@ -347,48 +320,48 @@ */ public function testNamespaceSelector() { $this->assertEquals( - '<select id=namespace name=namespace>' . "\n" . - '<option value=0>(Main)</option>' . "\n" . - '<option value=1>Talk</option>' . "\n" . - '<option value=2>User</option>' . "\n" . - '<option value=3>User talk</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . + '<select id="namespace" name="namespace">' . "\n" . + '<option value="0">(Main)</option>' . "\n" . + '<option value="1">Talk</option>' . "\n" . + '<option value="2">User</option>' . "\n" . + '<option value="3">User talk</option>' . "\n" . + '<option value="4">MyWiki</option>' . "\n" . + '<option value="5">MyWiki Talk</option>' . "\n" . + '<option value="6">File</option>' . "\n" . + '<option value="7">File talk</option>' . "\n" . + '<option value="8">MediaWiki</option>' . "\n" . + '<option value="9">MediaWiki talk</option>' . "\n" . + '<option value="10">Template</option>' . "\n" . + '<option value="11">Template talk</option>' . "\n" . + '<option value="14">Category</option>' . "\n" . + '<option value="15">Category talk</option>' . "\n" . + '<option value="100">Custom</option>' . "\n" . + '<option value="101">Custom talk</option>' . "\n" . '</select>', Html::namespaceSelector(), 'Basic namespace selector without custom options' ); $this->assertEquals( - '<label for=mw-test-namespace>Select a namespace:</label> ' . - '<select id=mw-test-namespace name=wpNamespace>' . "\n" . - '<option value=all>all</option>' . "\n" . - '<option value=0>(Main)</option>' . "\n" . - '<option value=1>Talk</option>' . "\n" . - '<option value=2 selected>User</option>' . "\n" . - '<option value=3>User talk</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . + '<label for="mw-test-namespace">Select a namespace:</label> ' . + '<select id="mw-test-namespace" name="wpNamespace">' . "\n" . + '<option value="all">all</option>' . "\n" . + '<option value="0">(Main)</option>' . "\n" . + '<option value="1">Talk</option>' . "\n" . + '<option value="2" selected="">User</option>' . "\n" . + '<option value="3">User talk</option>' . "\n" . + '<option value="4">MyWiki</option>' . "\n" . + '<option value="5">MyWiki Talk</option>' . "\n" . + '<option value="6">File</option>' . "\n" . + '<option value="7">File talk</option>' . "\n" . + '<option value="8">MediaWiki</option>' . "\n" . + '<option value="9">MediaWiki talk</option>' . "\n" . + '<option value="10">Template</option>' . "\n" . + '<option value="11">Template talk</option>' . "\n" . + '<option value="14">Category</option>' . "\n" . + '<option value="15">Category talk</option>' . "\n" . + '<option value="100">Custom</option>' . "\n" . + '<option value="101">Custom talk</option>' . "\n" . '</select>', Html::namespaceSelector( array( 'selected' => '2', 'all' => 'all', 'label' => 'Select a namespace:' ), @@ -398,24 +371,24 @@ ); $this->assertEquals( - '<label for=namespace>Select a namespace:</label> ' . - '<select id=namespace name=namespace>' . "\n" . - '<option value=0>(Main)</option>' . "\n" . - '<option value=1>Talk</option>' . "\n" . - '<option value=2>User</option>' . "\n" . - '<option value=3>User talk</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . + '<label for="namespace">Select a namespace:</label> ' . + '<select id="namespace" name="namespace">' . "\n" . + '<option value="0">(Main)</option>' . "\n" . + '<option value="1">Talk</option>' . "\n" . + '<option value="2">User</option>' . "\n" . + '<option value="3">User talk</option>' . "\n" . + '<option value="4">MyWiki</option>' . "\n" . + '<option value="5">MyWiki Talk</option>' . "\n" . + '<option value="6">File</option>' . "\n" . + '<option value="7">File talk</option>' . "\n" . + '<option value="8">MediaWiki</option>' . "\n" . + '<option value="9">MediaWiki talk</option>' . "\n" . + '<option value="10">Template</option>' . "\n" . + '<option value="11">Template talk</option>' . "\n" . + '<option value="14">Category</option>' . "\n" . + '<option value="15">Category talk</option>' . "\n" . + '<option value="100">Custom</option>' . "\n" . + '<option value="101">Custom talk</option>' . "\n" . '</select>', Html::namespaceSelector( array( 'label' => 'Select a namespace:' ) @@ -426,18 +399,18 @@ public function testCanFilterOutNamespaces() { $this->assertEquals( - '<select id=namespace name=namespace>' . "\n" . - '<option value=2>User</option>' . "\n" . - '<option value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . + '<select id="namespace" name="namespace">' . "\n" . + '<option value="2">User</option>' . "\n" . + '<option value="4">MyWiki</option>' . "\n" . + '<option value="5">MyWiki Talk</option>' . "\n" . + '<option value="6">File</option>' . "\n" . + '<option value="7">File talk</option>' . "\n" . + '<option value="8">MediaWiki</option>' . "\n" . + '<option value="9">MediaWiki talk</option>' . "\n" . + '<option value="10">Template</option>' . "\n" . + '<option value="11">Template talk</option>' . "\n" . + '<option value="14">Category</option>' . "\n" . + '<option value="15">Category talk</option>' . "\n" . '</select>', Html::namespaceSelector( array( 'exclude' => array( 0, 1, 3, 100, 101 ) ) @@ -448,23 +421,23 @@ public function testCanDisableANamespaces() { $this->assertEquals( - '<select id=namespace name=namespace>' . "\n" . - '<option disabled value=0>(Main)</option>' . "\n" . - '<option disabled value=1>Talk</option>' . "\n" . - '<option disabled value=2>User</option>' . "\n" . - '<option disabled value=3>User talk</option>' . "\n" . - '<option disabled value=4>MyWiki</option>' . "\n" . - '<option value=5>MyWiki Talk</option>' . "\n" . - '<option value=6>File</option>' . "\n" . - '<option value=7>File talk</option>' . "\n" . - '<option value=8>MediaWiki</option>' . "\n" . - '<option value=9>MediaWiki talk</option>' . "\n" . - '<option value=10>Template</option>' . "\n" . - '<option value=11>Template talk</option>' . "\n" . - '<option value=14>Category</option>' . "\n" . - '<option value=15>Category talk</option>' . "\n" . - '<option value=100>Custom</option>' . "\n" . - '<option value=101>Custom talk</option>' . "\n" . + '<select id="namespace" name="namespace">' . "\n" . + '<option disabled="" value="0">(Main)</option>' . "\n" . + '<option disabled="" value="1">Talk</option>' . "\n" . + '<option disabled="" value="2">User</option>' . "\n" . + '<option disabled="" value="3">User talk</option>' . "\n" . + '<option disabled="" value="4">MyWiki</option>' . "\n" . + '<option value="5">MyWiki Talk</option>' . "\n" . + '<option value="6">File</option>' . "\n" . + '<option value="7">File talk</option>' . "\n" . + '<option value="8">MediaWiki</option>' . "\n" . + '<option value="9">MediaWiki talk</option>' . "\n" . + '<option value="10">Template</option>' . "\n" . + '<option value="11">Template talk</option>' . "\n" . + '<option value="14">Category</option>' . "\n" . + '<option value="15">Category talk</option>' . "\n" . + '<option value="100">Custom</option>' . "\n" . + '<option value="101">Custom talk</option>' . "\n" . '</select>', Html::namespaceSelector( array( 'disable' => array( 0, 1, 2, 3, 4 ) @@ -479,9 +452,9 @@ */ public function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) { $this->assertEquals( - '<input type=' . $HTML5InputType . '>', + '<input type="' . $HTML5InputType . '"/>', Html::element( 'input', array( 'type' => $HTML5InputType ) ), - 'In HTML5, HTML::element() should accept type="' . $HTML5InputType . '"' + 'In HTML5, Html::element() should accept type="' . $HTML5InputType . '"' ); } @@ -528,15 +501,15 @@ # Will be mapped to Html::element() $cases = array(); - ### Generic cases, match $attribDefault static array - $cases[] = array( '<area>', + # ## Generic cases, match $attribDefault static array + $cases[] = array( '<area/>', 'area', array( 'shape' => 'rect' ) ); - $cases[] = array( '<button type=submit></button>', + $cases[] = array( '<button type="submit"></button>', 'button', array( 'formaction' => 'GET' ) ); - $cases[] = array( '<button type=submit></button>', + $cases[] = array( '<button type="submit"></button>', 'button', array( 'formenctype' => 'application/x-www-form-urlencoded' ) ); @@ -554,7 +527,7 @@ 'canvas', array( 'width' => 300 ) ); - $cases[] = array( '<command>', + $cases[] = array( '<command/>', 'command', array( 'type' => 'command' ) ); @@ -568,18 +541,18 @@ 'form', array( 'enctype' => 'application/x-www-form-urlencoded' ) ); - $cases[] = array( '<input>', + $cases[] = array( '<input/>', 'input', array( 'formaction' => 'GET' ) ); - $cases[] = array( '<input>', + $cases[] = array( '<input/>', 'input', array( 'type' => 'text' ) ); - $cases[] = array( '<keygen>', + $cases[] = array( '<keygen/>', 'keygen', array( 'keytype' => 'rsa' ) ); - $cases[] = array( '<link>', + $cases[] = array( '<link/>', 'link', array( 'media' => 'all' ) ); @@ -602,47 +575,47 @@ 'textarea', array( 'wrap' => 'soft' ) ); - ### SPECIFIC CASES + # ## SPECIFIC CASES # <link type="text/css"> - $cases[] = array( '<link>', + $cases[] = array( '<link/>', 'link', array( 'type' => 'text/css' ) ); # <input> specific handling - $cases[] = array( '<input type=checkbox>', + $cases[] = array( '<input type="checkbox"/>', 'input', array( 'type' => 'checkbox', 'value' => 'on' ), 'Default value "on" is stripped of checkboxes', ); - $cases[] = array( '<input type=radio>', + $cases[] = array( '<input type="radio"/>', 'input', array( 'type' => 'radio', 'value' => 'on' ), 'Default value "on" is stripped of radio buttons', ); - $cases[] = array( '<input type=submit value=Submit>', + $cases[] = array( '<input type="submit" value="Submit"/>', 'input', array( 'type' => 'submit', 'value' => 'Submit' ), 'Default value "Submit" is kept on submit buttons (for possible l10n issues)', ); - $cases[] = array( '<input type=color>', + $cases[] = array( '<input type="color"/>', 'input', array( 'type' => 'color', 'value' => '' ), ); - $cases[] = array( '<input type=range>', + $cases[] = array( '<input type="range"/>', 'input', array( 'type' => 'range', 'value' => '' ), ); # <button> specific handling # see remarks on http://msdn.microsoft.com/en-us/library/ie/ms535211%28v=vs.85%29.aspx - $cases[] = array( '<button type=submit></button>', + $cases[] = array( '<button type="submit"></button>', 'button', array( 'type' => 'submit' ), 'According to standard the default type is "submit". ' . 'Depending on compatibility mode IE might use "button", instead.', ); # <select> specific handling - $cases[] = array( '<select multiple></select>', + $cases[] = array( '<select multiple=""></select>', 'select', array( 'size' => '4', 'multiple' => true ), ); # .. with numeric value - $cases[] = array( '<select multiple></select>', + $cases[] = array( '<select multiple=""></select>', 'select', array( 'size' => 4, 'multiple' => true ), ); $cases[] = array( '<select></select>', @@ -694,7 +667,7 @@ 'Blacklist form validation attributes.' ); $this->assertEquals( - ' step=any', + ' step="any"', Html::expandAttributes( array( 'min' => 1, @@ -710,12 +683,12 @@ public function testWrapperInput() { $this->assertEquals( - '<input type=radio value=testval name=testname>', + '<input type="radio" value="testval" name="testname"/>', Html::input( 'testname', 'testval', 'radio' ), 'Input wrapper with type and value.' ); $this->assertEquals( - '<input name=testname>', + '<input name="testname"/>', Html::input( 'testname' ), 'Input wrapper with all default values.' ); @@ -723,17 +696,17 @@ public function testWrapperCheck() { $this->assertEquals( - '<input type=checkbox value=1 name=testname>', + '<input type="checkbox" value="1" name="testname"/>', Html::check( 'testname' ), 'Checkbox wrapper unchecked.' ); $this->assertEquals( - '<input checked type=checkbox value=1 name=testname>', + '<input checked="" type="checkbox" value="1" name="testname"/>', Html::check( 'testname', true ), 'Checkbox wrapper checked.' ); $this->assertEquals( - '<input type=checkbox value=testval name=testname>', + '<input type="checkbox" value="testval" name="testname"/>', Html::check( 'testname', false, array( 'value' => 'testval' ) ), 'Checkbox wrapper with a value override.' ); @@ -741,17 +714,17 @@ public function testWrapperRadio() { $this->assertEquals( - '<input type=radio value=1 name=testname>', + '<input type="radio" value="1" name="testname"/>', Html::radio( 'testname' ), 'Radio wrapper unchecked.' ); $this->assertEquals( - '<input checked type=radio value=1 name=testname>', + '<input checked="" type="radio" value="1" name="testname"/>', Html::radio( 'testname', true ), 'Radio wrapper checked.' ); $this->assertEquals( - '<input type=radio value=testval name=testname>', + '<input type="radio" value="testval" name="testname"/>', Html::radio( 'testname', false, array( 'value' => 'testval' ) ), 'Radio wrapper with a value override.' ); @@ -759,7 +732,7 @@ public function testWrapperLabel() { $this->assertEquals( - '<label for=testid>testlabel</label>', + '<label for="testid">testlabel</label>', Html::label( 'testlabel', 'testid' ), 'Label wrapper' ); diff --git a/tests/phpunit/includes/LinkerTest.php b/tests/phpunit/includes/LinkerTest.php index a3efbb8..e09dc67 100644 --- a/tests/phpunit/includes/LinkerTest.php +++ b/tests/phpunit/includes/LinkerTest.php @@ -13,7 +13,6 @@ public function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) { $this->setMwGlobals( array( 'wgArticlePath' => '/wiki/$1', - 'wgWellFormedXml' => true, ) ); $this->assertEquals( $expected, @@ -110,7 +109,6 @@ $this->setMwGlobals( array( 'wgScript' => '/wiki/index.php', 'wgArticlePath' => '/wiki/$1', - 'wgWellFormedXml' => true, 'wgCapitalLinks' => true, 'wgConf' => $conf, ) ); @@ -273,7 +271,6 @@ $this->setMwGlobals( array( 'wgScript' => '/wiki/index.php', 'wgArticlePath' => '/wiki/$1', - 'wgWellFormedXml' => true, 'wgCapitalLinks' => true, 'wgConf' => $conf, ) ); diff --git a/tests/phpunit/includes/OutputPageTest.php b/tests/phpunit/includes/OutputPageTest.php index f0d905e..920f170 100644 --- a/tests/phpunit/includes/OutputPageTest.php +++ b/tests/phpunit/includes/OutputPageTest.php @@ -148,14 +148,14 @@ array( // Don't condition wrap raw modules (like the startup module) array( 'test.raw', ResourceLoaderModule::TYPE_SCRIPTS ), - '<script async src="http://127.0.0.1:8080/w/load.php?debug=false&lang=en&modules=test.raw&only=scripts&skin=fallback"></script>' + '<script async="" src="http://127.0.0.1:8080/w/load.php?debug=false&lang=en&modules=test.raw&only=scripts&skin=fallback"></script>' ), // Load module styles only // This also tests the order the modules are put into the url array( array( array( 'test.baz', 'test.foo', 'test.bar' ), ResourceLoaderModule::TYPE_STYLES ), - '<link rel=stylesheet href="http://127.0.0.1:8080/w/load.php?debug=false&lang=en&modules=test.bar%2Cbaz%2Cfoo&only=styles&skin=fallback">' + '<link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?debug=false&lang=en&modules=test.bar%2Cbaz%2Cfoo&only=styles&skin=fallback"/>' ), // Load private module (only=scripts) array( @@ -180,7 +180,7 @@ // noscript group array( array( 'test.noscript', ResourceLoaderModule::TYPE_STYLES ), - '<noscript><link rel=stylesheet href="http://127.0.0.1:8080/w/load.php?debug=false&lang=en&modules=test.noscript&only=styles&skin=fallback"></noscript>' + '<noscript><link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?debug=false&lang=en&modules=test.noscript&only=styles&skin=fallback"/></noscript>' ), // Load two modules in separate groups array( @@ -208,8 +208,6 @@ $this->setMwGlobals( array( 'wgResourceLoaderDebug' => false, 'wgLoadScript' => 'http://127.0.0.1:8080/w/load.php', - // Affects whether CDATA is inserted - 'wgWellFormedXml' => false, ) ); $class = new ReflectionClass( 'OutputPage' ); $method = $class->getMethod( 'makeResourceLoaderLink' ); diff --git a/tests/phpunit/includes/XmlSelectTest.php b/tests/phpunit/includes/XmlSelectTest.php index 0e03add..531ed41 100644 --- a/tests/phpunit/includes/XmlSelectTest.php +++ b/tests/phpunit/includes/XmlSelectTest.php @@ -12,9 +12,6 @@ protected function setUp() { parent::setUp(); - $this->setMwGlobals( array( - 'wgWellFormedXml' => true, - ) ); $this->select = new XmlSelect(); } diff --git a/tests/phpunit/includes/XmlTest.php b/tests/phpunit/includes/XmlTest.php index bea338d..d8049b7 100644 --- a/tests/phpunit/includes/XmlTest.php +++ b/tests/phpunit/includes/XmlTest.php @@ -30,7 +30,6 @@ $this->setMwGlobals( array( 'wgLang' => $langObj, - 'wgWellFormedXml' => true, ) ); } @@ -152,7 +151,7 @@ $this->assertEquals( '<label for="year">From year (and earlier):</label> ' . - '<input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> ' . + '<input id="year" maxlength="4" size="7" type="number" value="2011" name="year"/> ' . '<label for="month">From month (and earlier):</label> ' . '<select name="month" id="month" class="mw-month-selector">' . '<option value="-1">all</option>' . "\n" . @@ -173,7 +172,7 @@ ); $this->assertEquals( '<label for="year">From year (and earlier):</label> ' . - '<input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> ' . + '<input id="year" maxlength="4" size="7" type="number" value="2011" name="year"/> ' . '<label for="month">From month (and earlier):</label> ' . '<select name="month" id="month" class="mw-month-selector">' . '<option value="-1">all</option>' . "\n" . @@ -207,7 +206,7 @@ $this->assertEquals( '<label for="year">From year (and earlier):</label> ' . - '<input id="year" maxlength="4" size="7" type="number" name="year" /> ' . + '<input id="year" maxlength="4" size="7" type="number" name="year"/> ' . '<label for="month">From month (and earlier):</label> ' . '<select name="month" id="month" class="mw-month-selector">' . '<option value="-1">all</option>' . "\n" . diff --git a/tests/phpunit/includes/content/JsonContentTest.php b/tests/phpunit/includes/content/JsonContentTest.php index 8a9d2ab..3023538 100644 --- a/tests/phpunit/includes/content/JsonContentTest.php +++ b/tests/phpunit/includes/content/JsonContentTest.php @@ -6,12 +6,6 @@ */ class JsonContentTest extends MediaWikiLangTestCase { - protected function setUp() { - parent::setUp(); - - $this->setMwGlobals( 'wgWellFormedXml', true ); - } - public static function provideValidConstruction() { return array( array( 'foo', false, null ), diff --git a/tests/phpunit/includes/parser/NewParserTest.php b/tests/phpunit/includes/parser/NewParserTest.php index d95e922..b298ef1 100644 --- a/tests/phpunit/includes/parser/NewParserTest.php +++ b/tests/phpunit/includes/parser/NewParserTest.php @@ -100,7 +100,6 @@ $tmpGlobals['wgUseImageResize'] = true; $tmpGlobals['wgAllowExternalImages'] = true; $tmpGlobals['wgRawHtml'] = false; - $tmpGlobals['wgWellFormedXml'] = true; $tmpGlobals['wgAllowMicrodataAttributes'] = true; $tmpGlobals['wgExperimentalHtmlIds'] = false; $tmpGlobals['wgAdaptiveMessageCache'] = true; -- To view, visit https://gerrit.wikimedia.org/r/304154 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5c922e0980d3f9eb39adb5bb5833e158afda42ed Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: REL1_26 Gerrit-Owner: Chad <ch...@wikimedia.org> Gerrit-Reviewer: Brian Wolff <bawolff...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits