Whitelist additional WAI-ARIA attributes, and all role values
Adds the attributes aria-describedby, aria-flowto, aria-label, aria-labelledby, and aria-owns to the attribute whitelist for all elements. Adds Sanitizer::escapeIdReferenceList() to escape attributes containing space delimited HTML id lists, in the same manner as Sanitizer::escapeId(). Removes the role="presentation" restriction. Allows all values for the role attribute. Bug: T26659 Change-Id: I3a29d727c61f46ac115ca2e50fcb14deeea34418
This commit is contained in:
parent
7c4bd85d21
commit
1397863569
3 changed files with 75 additions and 36 deletions
|
|
@ -146,6 +146,10 @@ production.
|
|||
* Added MWRestrictions as a class to check restrictions on a WebRequest, e.g.
|
||||
to assert that the request comes from a particular IP range.
|
||||
* Added bot passwords, a rights-restricted login mechanism for API-using bots.
|
||||
* Whitelisted the following HTML attributes for all elements in wikitext:
|
||||
aria-describedby, aria-flowto, aria-label, aria-labelledby, aria-owns.
|
||||
* Removed "presentation" restriction on the HTML role attribute in wikitext.
|
||||
All values are now allowed for the role attribute.
|
||||
|
||||
=== External library changes in 1.27 ===
|
||||
|
||||
|
|
|
|||
|
|
@ -721,7 +721,7 @@ class Sanitizer {
|
|||
* Take an array of attribute names and values and normalize or discard
|
||||
* illegal values for the given whitelist.
|
||||
*
|
||||
* - Discards attributes not the given whitelist
|
||||
* - Discards attributes not on the given whitelist
|
||||
* - Unsafe style attributes are discarded
|
||||
* - Invalid id attributes are re-encoded
|
||||
*
|
||||
|
|
@ -770,18 +770,18 @@ class Sanitizer {
|
|||
$value = Sanitizer::checkCss( $value );
|
||||
}
|
||||
|
||||
# Escape HTML id attributes
|
||||
if ( $attribute === 'id' ) {
|
||||
$value = Sanitizer::escapeId( $value, 'noninitial' );
|
||||
}
|
||||
|
||||
# WAI-ARIA
|
||||
# http://www.w3.org/TR/wai-aria/
|
||||
# http://www.whatwg.org/html/elements.html#wai-aria
|
||||
# For now we only support role="presentation" until we work out what roles should be
|
||||
# usable by content and we ensure that our code explicitly rejects patterns that
|
||||
# violate HTML5's ARIA restrictions.
|
||||
if ( $attribute === 'role' && $value !== 'presentation' ) {
|
||||
continue;
|
||||
# Escape HTML id reference lists
|
||||
if ( $attribute === 'aria-describedby'
|
||||
|| $attribute === 'aria-flowto'
|
||||
|| $attribute === 'aria-labelledby'
|
||||
|| $attribute === 'aria-owns'
|
||||
) {
|
||||
$value = Sanitizer::escapeIdReferenceList( $value, 'noninitial' );
|
||||
}
|
||||
|
||||
// RDFa and microdata properties allow URLs, URIs and/or CURIs.
|
||||
|
|
@ -1163,6 +1163,39 @@ class Sanitizer {
|
|||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a string containing a space delimited list of ids, escape each id
|
||||
* to match ids escaped by the escapeId() function.
|
||||
*
|
||||
* @since 1.27
|
||||
*
|
||||
* @param string $referenceString Space delimited list of ids
|
||||
* @param string|array $options String or array of strings (default is array()):
|
||||
* 'noninitial': This is a non-initial fragment of an id, not a full id,
|
||||
* so don't pay attention if the first character isn't valid at the
|
||||
* beginning of an id. Only matters if $wgExperimentalHtmlIds is
|
||||
* false.
|
||||
* 'legacy': Behave the way the old HTML 4-based ID escaping worked even
|
||||
* if $wgExperimentalHtmlIds is used, so we can generate extra
|
||||
* anchors and links won't break.
|
||||
* @return string
|
||||
*/
|
||||
static function escapeIdReferenceList( $referenceString, $options = array() ) {
|
||||
# Explode the space delimited list string into an array of tokens
|
||||
$references = preg_split( '/\s+/', "{$referenceString}", -1, PREG_SPLIT_NO_EMPTY );
|
||||
|
||||
# Escape each token as an id
|
||||
foreach ( $references as &$ref ) {
|
||||
$ref = Sanitizer::escapeId( $ref, $options );
|
||||
}
|
||||
|
||||
# Merge the array back to a space delimited list string
|
||||
# If the array is empty, the result will be an empty string ('')
|
||||
$referenceString = implode( ' ', $references );
|
||||
|
||||
return $referenceString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a value, escape it so that it can be used as a CSS class and
|
||||
* return it.
|
||||
|
|
@ -1546,6 +1579,11 @@ class Sanitizer {
|
|||
'title',
|
||||
|
||||
# WAI-ARIA
|
||||
'aria-describedby',
|
||||
'aria-flowto',
|
||||
'aria-label',
|
||||
'aria-labelledby',
|
||||
'aria-owns',
|
||||
'role',
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -317,33 +317,6 @@ class SanitizerTest extends MediaWikiTestCase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for support or lack of support for specific attributes in the attribute whitelist.
|
||||
*/
|
||||
public static function provideAttributeSupport() {
|
||||
/** array( <attributes>, <expected>, <message> ) */
|
||||
return array(
|
||||
array(
|
||||
'div',
|
||||
' role="presentation"',
|
||||
' role="presentation"',
|
||||
'Support for WAI-ARIA\'s role="presentation".'
|
||||
),
|
||||
array( 'div', ' role="main"', '', "Other WAI-ARIA roles are currently not supported." ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideAttributeSupport
|
||||
* @covers Sanitizer::fixTagAttributes
|
||||
*/
|
||||
public function testAttributeSupport( $tag, $attributes, $expected, $message ) {
|
||||
$this->assertEquals( $expected,
|
||||
Sanitizer::fixTagAttributes( $attributes, $tag ),
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideEscapeHtmlAllowEntities
|
||||
* @covers Sanitizer::escapeHtmlAllowEntities
|
||||
|
|
@ -363,4 +336,28 @@ class SanitizerTest extends MediaWikiTestCase {
|
|||
array( '<script>foo</script>', '<script>foo</script>' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test escapeIdReferenceList for consistency with escapeId
|
||||
*
|
||||
* @dataProvider provideEscapeIdReferenceList
|
||||
* @covers Sanitizer::escapeIdReferenceList
|
||||
*/
|
||||
public function testEscapeIdReferenceList( $referenceList, $id1, $id2 ) {
|
||||
$this->assertEquals(
|
||||
Sanitizer::escapeIdReferenceList( $referenceList, 'noninitial' ),
|
||||
Sanitizer::escapeId( $id1, 'noninitial' )
|
||||
. ' '
|
||||
. Sanitizer::escapeId( $id2, 'noninitial' )
|
||||
);
|
||||
}
|
||||
|
||||
public static function provideEscapeIdReferenceList() {
|
||||
/** array( <reference list>, <individual id 1>, <individual id 2> ) */
|
||||
return array(
|
||||
array( 'foo bar', 'foo', 'bar' ),
|
||||
array( '#1 #2', '#1', '#2' ),
|
||||
array( '+1 +2', '+1', '+2' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue