Index: trunk/phase3/includes/LocalisationCache.php |
— | — | @@ -343,6 +343,12 @@ |
344 | 344 | } |
345 | 345 | $this->initialisedLangs[$code] = true; |
346 | 346 | |
| 347 | + # If the code is of the wrong form for a Messages*.php file, do a shallow fallback |
| 348 | + if ( !Language::isValidBuiltInCode( $code ) ) { |
| 349 | + $this->initShallowFallback( $code, 'en' ); |
| 350 | + return; |
| 351 | + } |
| 352 | + |
347 | 353 | # Recache the data if necessary |
348 | 354 | if ( !$this->manualRecache && $this->isExpired( $code ) ) { |
349 | 355 | if ( file_exists( Language::getMessagesFileName( $code ) ) ) { |
Index: trunk/phase3/languages/Language.php |
— | — | @@ -157,11 +157,19 @@ |
158 | 158 | |
159 | 159 | // Protect against path traversal below |
160 | 160 | if ( !Language::isValidCode( $code ) |
161 | | - || strcspn( $code, "/\\\000" ) !== strlen( $code ) ) |
| 161 | + || strcspn( $code, ":/\\\000" ) !== strlen( $code ) ) |
162 | 162 | { |
163 | 163 | throw new MWException( "Invalid language code \"$code\"" ); |
164 | 164 | } |
165 | 165 | |
| 166 | + if ( !Language::isValidBuiltInCode( $code ) ) { |
| 167 | + // It's not possible to customise this code with class files, so |
| 168 | + // just return a Language object. This is to support uselang= hacks. |
| 169 | + $lang = new Language; |
| 170 | + $lang->setCode( $code ); |
| 171 | + return $lang; |
| 172 | + } |
| 173 | + |
166 | 174 | if ( $code == 'en' ) { |
167 | 175 | $class = 'Language'; |
168 | 176 | } else { |
— | — | @@ -193,13 +201,24 @@ |
194 | 202 | |
195 | 203 | /** |
196 | 204 | * Returns true if a language code string is of a valid form, whether or |
197 | | - * not it exists. |
| 205 | + * not it exists. This includes codes which are used solely for |
| 206 | + * customisation via the MediaWiki namespace. |
198 | 207 | */ |
199 | 208 | public static function isValidCode( $code ) { |
200 | | - return strcspn( $code, "/\\\000" ) === strlen( $code ); |
| 209 | + return |
| 210 | + strcspn( $code, ":/\\\000" ) === strlen( $code ) |
| 211 | + && !preg_match( Title::getTitleInvalidRegex(), $code ); |
201 | 212 | } |
202 | 213 | |
203 | 214 | /** |
| 215 | + * Returns true if a language code is of a valid form for the purposes of |
| 216 | + * internal customisation of MediaWiki, via Messages*.php. |
| 217 | + */ |
| 218 | + public static function isValidBuiltInCode( $code ) { |
| 219 | + return preg_match( '/^[a-z0-9-]*$/', $code ); |
| 220 | + } |
| 221 | + |
| 222 | + /** |
204 | 223 | * Get the LocalisationCache instance |
205 | 224 | * |
206 | 225 | * @return LocalisationCache |
— | — | @@ -2859,7 +2878,7 @@ |
2860 | 2879 | static function getFileName( $prefix = 'Language', $code, $suffix = '.php' ) { |
2861 | 2880 | // Protect against path traversal |
2862 | 2881 | if ( !Language::isValidCode( $code ) |
2863 | | - || strcspn( $code, "/\\\000" ) !== strlen( $code ) ) |
| 2882 | + || strcspn( $code, ":/\\\000" ) !== strlen( $code ) ) |
2864 | 2883 | { |
2865 | 2884 | throw new MWException( "Invalid language code \"$code\"" ); |
2866 | 2885 | } |