ksort( $query );
$url = wfAppendQuery( $wgLoadScript, $query );
+ // Prevent the IE6 extension check from being triggered (bug 28840)
+ // by appending a character that's invalid in Windows extensions ('*')
+ $url .= '&*';
if ( $useESI && $wgResourceLoaderUseESI ) {
$esi = Xml::element( 'esi:include', array( 'src' => $url ) );
if ( $only == ResourceLoaderModule::TYPE_STYLES ) {
} else {
// Automatically select style/script elements
if ( $only === ResourceLoaderModule::TYPE_STYLES ) {
- $link = Html::linkedStyle( wfAppendQuery( $wgLoadScript, $query ) );
+ $link = Html::linkedStyle( $url );
} else {
- $link = Html::linkedScript( wfAppendQuery( $wgLoadScript, $query ) );
+ $link = Html::linkedScript( $url );
}
}
public function isPathInfoBad() {
global $wgScriptExtension;
- if ( isset( $_SERVER['QUERY_STRING'] )
- && preg_match( '/\.[^\\/:*?"<>|%]+(#|\?|$)/i', $_SERVER['QUERY_STRING'] ) )
+ if ( isset( $_SERVER['QUERY_STRING'] ) )
{
// Bug 28235
- // Block only Internet Explorer, and requests with missing UA
- // headers that could be IE users behind a privacy proxy.
- if ( !isset( $_SERVER['HTTP_USER_AGENT'] )
- || preg_match( '/; *MSIE/', $_SERVER['HTTP_USER_AGENT'] ) )
- {
- return true;
- }
+ return strval( self::findIE6Extension( $_SERVER['QUERY_STRING'] ) ) !== '';
}
if ( !isset( $_SERVER['PATH_INFO'] ) ) {
$ext = substr( $pi, $dotPos );
return !in_array( $ext, array( $wgScriptExtension, '.php', '.php5' ) );
}
+
+ /**
+ * Determine what extension IE6 will infer from a certain query string.
+ * If the URL has an extension before the question mark, IE6 will use
+ * that and ignore the query string, but per the comment at
+ * isPathInfoBad() we don't have a reliable way to determine the URL,
+ * so isPathInfoBad() just passes in the query string for $url.
+ * All entry points have safe extensions (php, php5) anyway, so
+ * checking the query string is possibly overly paranoid but never
+ * insecure.
+ *
+ * The criteria for finding an extension are as follows:
+ * * a possible extension is a dot followed by one or more characters not in <>\"/:|?.#
+ * * if we find a possible extension followed by the end of the string or a #, that's our extension
+ * * if we find a possible extension followed by a ?, that's our extension
+ * ** UNLESS it's exe, dll or cgi, in which case we ignore it and continue searching for another possible extension
+ * * if we find a possible extension followed by a dot or another illegal character, we ignore it and continue searching
+ *
+ * @param $url string URL
+ * @return mixed Detected extension (string), or false if none found
+ */
+ public static function findIE6Extension( $url ) {
+ $remaining = $url;
+ while ( $remaining !== '' ) {
+ // Skip ahead to the next dot
+ $pos = strcspn( $remaining, '.' );
+ if ( $pos === strlen( $remaining ) || $remaining[$pos] === '#' ) {
+ // End of string, we're done
+ return false;
+ }
+
+ // We found a dot. Skip past it
+ $remaining = substr( $remaining, $pos + 1 );
+ // Check for illegal characters in our prospective extension,
+ // or for another dot, or for a hash sign
+ $pos = strcspn( $remaining, "<>\\\"/:|?*.#" );
+ if ( $pos === strlen( $remaining ) ) {
+ // No illegal character or next dot or hash
+ // We have our extension
+ return $remaining;
+ }
+ if ( $remaining[$pos] === '#' ) {
+ // We've found a legal extension followed by a hash
+ // Trim the hash and everything after it, then return that
+ return substr( $remaining, 0, $pos );
+ }
+ if ( $remaining[$pos] === '?' ) {
+ // We've found a legal extension followed by a question mark
+ // If the extension is NOT exe, dll or cgi, return it
+ $extension = substr( $remaining, 0, $pos );
+ if ( strcasecmp( $extension, 'exe' ) && strcasecmp( $extension, 'dll' ) &&
+ strcasecmp( $extension, 'cgi' ) )
+ {
+ return $extension;
+ }
+ // Else continue looking
+ }
+ // We found an illegal character or another dot
+ // Skip to that character and continue the loop
+ $remaining = substr( $remaining, $pos );
+ }
+ return false;
+ }
/**
* Parse the Accept-Language header sent by the client into an array
* Convert an array of module names to a packed query string.
*
* For example, array( 'foo.bar', 'foo.baz', 'bar.baz', 'bar.quux' )
- * becomes 'foo!bar,baz|bar!baz,quux'
- * The ! is for IE6 being stupid with extensions.
+ * becomes 'foo.bar,baz|bar.baz,quux'
* @param $modules array of module names (strings)
* @return string Packed query string
*/
$arr[] = $p . implode( ',', $suffixes );
}
$str = implode( '|', $arr );
- return str_replace( ".", "!", $str ); # bug 28840
+ return $str;
}
/**
/**
* Expand a string of the form jquery.foo,bar|jquery.ui.baz,quux to
* an array of module names like array( 'jquery.foo', 'jquery.bar',
- * 'jquery.ui.baz', 'jquery.ui.quux' ) Also translating ! to .
+ * 'jquery.ui.baz', 'jquery.ui.quux' )
* @param $modules String Packed module name list
* @return array of module names
*/
public static function expandModuleNames( $modules ) {
$retval = array();
- $modules = str_replace( "!", ".", $modules ); # bug 28840 - IE is stupid.
$exploded = explode( '|', $modules );
foreach ( $exploded as $group ) {
if ( strpos( $group, ',' ) === false ) {