}
$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 ) ) ) {
// 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 {
/**
* 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 );
}
/**
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\"" );
}