# Allow any attribute beginning with "data-"
# However:
- # * data-ooui is reserved for ooui
- # * data-mw and data-parsoid are reserved for parsoid
- # * data-mw-<name here> is reserved for extensions (or core) if
- # they need to communicate some data to the client and want to be
- # sure that it isn't coming from an untrusted user.
+ # * Disallow data attributes used by MediaWiki code
# * Ensure that the attribute is not namespaced by banning
# colons.
- if ( !preg_match( '/^data-(?!ooui|mw|parsoid)[^:]*$/i', $attribute )
+ if ( !preg_match( '/^data-[^:]*$/i', $attribute )
&& !isset( $whitelist[$attribute] )
+ || self::isReservedDataAttribute( $attribute )
) {
continue;
}
return $out;
}
+ /**
+ * Given an attribute name, checks whether it is a reserved data attribute
+ * (such as data-mw-foo) which is unavailable to user-generated HTML so MediaWiki
+ * core and extension code can safely use it to communicate with frontend code.
+ * @param string $attr Attribute name.
+ * @return bool
+ */
+ public static function isReservedDataAttribute( $attr ) {
+ // data-ooui is reserved for ooui.
+ // data-mw and data-parsoid are reserved for parsoid.
+ // data-mw-<name here> is reserved for extensions (or core) if
+ // they need to communicate some data to the client and want to be
+ // sure that it isn't coming from an untrusted user.
+ // We ignore the possibility of namespaces since user-generated HTML
+ // can't use them anymore.
+ return (bool)preg_match( '/^data-(ooui|mw|parsoid)/i', $attr );
+ }
+
/**
* Merge two sets of HTML attributes. Conflicting items in the second set
* will override those in the first, except for 'class' attributes which