Followup for r81340:

* Allow any language code which consists entirely of valid title characters, and does not contain any path-traversal characters, to be customised via the uselang parameter. Language::isValidCode() represents this concept. 
* Add some shortcuts preventing Language and LocalisationCache from looking for localisation files for a language code which does not follow the usual form of language codes in MediaWiki, i.e. /[a-z-]*/. This concept is represented by Language::isValidBuiltInCode().
* Do not allow colon characters in file names, per Platonides' suggestion on CR.
This commit is contained in:
Tim Starling 2011-02-28 03:15:39 +00:00
parent 4431b79a68
commit 1e67922842
2 changed files with 29 additions and 4 deletions

View file

@ -343,6 +343,12 @@ class LocalisationCache {
}
$this->initialisedLangs[$code] = true;
# If the code is of the wrong form for a Messages*.php file, do a shallow fallback
if ( !Language::isValidBuiltInCode( $code ) ) {
$this->initShallowFallback( $code, 'en' );
return;
}
# Recache the data if necessary
if ( !$this->manualRecache && $this->isExpired( $code ) ) {
if ( file_exists( Language::getMessagesFileName( $code ) ) ) {

View file

@ -157,11 +157,19 @@ class Language {
// Protect against path traversal below
if ( !Language::isValidCode( $code )
|| strcspn( $code, "/\\\000" ) !== strlen( $code ) )
|| strcspn( $code, ":/\\\000" ) !== strlen( $code ) )
{
throw new MWException( "Invalid language code \"$code\"" );
}
if ( !Language::isValidBuiltInCode( $code ) ) {
// It's not possible to customise this code with class files, so
// just return a Language object. This is to support uselang= hacks.
$lang = new Language;
$lang->setCode( $code );
return $lang;
}
if ( $code == 'en' ) {
$class = 'Language';
} else {
@ -193,10 +201,21 @@ class Language {
/**
* Returns true if a language code string is of a valid form, whether or
* not it exists.
* not it exists. This includes codes which are used solely for
* customisation via the MediaWiki namespace.
*/
public static function isValidCode( $code ) {
return strcspn( $code, "/\\\000" ) === strlen( $code );
return
strcspn( $code, ":/\\\000" ) === strlen( $code )
&& !preg_match( Title::getTitleInvalidRegex(), $code );
}
/**
* Returns true if a language code is of a valid form for the purposes of
* internal customisation of MediaWiki, via Messages*.php.
*/
public static function isValidBuiltInCode( $code ) {
return preg_match( '/^[a-z0-9-]*$/', $code );
}
/**
@ -2859,7 +2878,7 @@ class Language {
static function getFileName( $prefix = 'Language', $code, $suffix = '.php' ) {
// Protect against path traversal
if ( !Language::isValidCode( $code )
|| strcspn( $code, "/\\\000" ) !== strlen( $code ) )
|| strcspn( $code, ":/\\\000" ) !== strlen( $code ) )
{
throw new MWException( "Invalid language code \"$code\"" );
}