Matthias Mullie has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/337854 )

Change subject: Disallow wikitext creation of invalid filenames in NS_FILE
......................................................................

Disallow wikitext creation of invalid filenames in NS_FILE

Bug: T153864
Change-Id: I6a9a26d6ddd2ae4940a60cfd5a3424e735ca918c
---
M includes/EditPage.php
M includes/specials/SpecialUpload.php
2 files changed, 94 insertions(+), 56 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/54/337854/1

diff --git a/includes/EditPage.php b/includes/EditPage.php
index 34062c0..27c7688 100644
--- a/includes/EditPage.php
+++ b/includes/EditPage.php
@@ -1760,15 +1760,29 @@
                        return $status;
                }
 
-               # Check image redirect
-               if ( $this->mTitle->getNamespace() == NS_FILE &&
-                       $textbox_content->isRedirect() &&
-                       !$wgUser->isAllowed( 'upload' )
-               ) {
+               if ( $this->mTitle->getNamespace() === NS_FILE ) {
+                       if ( $textbox_content->isRedirect() && 
!$wgUser->isAllowed( 'upload' ) ) {
+                               # Check image redirect
                                $code = $wgUser->isAnon() ? 
self::AS_IMAGE_REDIRECT_ANON : self::AS_IMAGE_REDIRECT_LOGGED;
                                $status->setResult( false, $code );
 
                                return $status;
+                       } else {
+                               # Check image filename
+                               # Initialize a bogus upload by this name, to 
utilize its
+                               # filename validation code
+                               $request = new WebRequestUpload( $wgRequest, 
'null' );
+                               $upload = new UploadFromFile();
+                               $upload->initialize( $this->mTitle->getDBkey(), 
$request );
+
+                               $validate = $upload->validateName();
+                               if ( $validate !== true ) {
+                                       $html = 
SpecialUpload::getVerificationErrorMessage( $validate );
+                                       $message = new RawMessage( $html );
+                                       $status->fatal( $message );
+                                       return $status;
+                               }
+                       }
                }
 
                # Check for spam
diff --git a/includes/specials/SpecialUpload.php 
b/includes/specials/SpecialUpload.php
index c5a1f27..8d044aa 100644
--- a/includes/specials/SpecialUpload.php
+++ b/includes/specials/SpecialUpload.php
@@ -675,73 +675,27 @@
         * @throws MWException
         */
        protected function processVerificationError( $details ) {
-               switch ( $details['status'] ) {
+               $error = $this->getVerificationErrorMessage( $details );
 
+               switch ( $details['status'] ) {
                        /** Statuses that only require name changing **/
                        case UploadBase::MIN_LENGTH_PARTNAME:
-                               $this->showRecoverableUploadError( $this->msg( 
'minlength1' )->escaped() );
-                               break;
                        case UploadBase::ILLEGAL_FILENAME:
-                               $this->showRecoverableUploadError( $this->msg( 
'illegalfilename',
-                                       $details['filtered'] )->parse() );
-                               break;
                        case UploadBase::FILENAME_TOO_LONG:
-                               $this->showRecoverableUploadError( $this->msg( 
'filename-toolong' )->escaped() );
-                               break;
                        case UploadBase::FILETYPE_MISSING:
-                               $this->showRecoverableUploadError( $this->msg( 
'filetype-missing' )->parse() );
-                               break;
                        case UploadBase::WINDOWS_NONASCII_FILENAME:
-                               $this->showRecoverableUploadError( $this->msg( 
'windows-nonascii-filename' )->parse() );
+                               $this->showRecoverableUploadError( $error );
                                break;
 
                        /** Statuses that require reuploading **/
                        case UploadBase::EMPTY_FILE:
-                               $this->showUploadError( $this->msg( 'emptyfile' 
)->escaped() );
-                               break;
                        case UploadBase::FILE_TOO_LARGE:
-                               $this->showUploadError( $this->msg( 
'largefileserver' )->escaped() );
-                               break;
                        case UploadBase::FILETYPE_BADTYPE:
-                               $msg = $this->msg( 'filetype-banned-type' );
-                               if ( isset( $details['blacklistedExt'] ) ) {
-                                       $msg->params( 
$this->getLanguage()->commaList( $details['blacklistedExt'] ) );
-                               } else {
-                                       $msg->params( $details['finalExt'] );
-                               }
-                               $extensions = array_unique( 
$this->getConfig()->get( 'FileExtensions' ) );
-                               $msg->params( $this->getLanguage()->commaList( 
$extensions ),
-                                       count( $extensions ) );
-
-                               // Add PLURAL support for the first parameter. 
This results
-                               // in a bit unlogical parameter sequence, but 
does not break
-                               // old translations
-                               if ( isset( $details['blacklistedExt'] ) ) {
-                                       $msg->params( count( 
$details['blacklistedExt'] ) );
-                               } else {
-                                       $msg->params( 1 );
-                               }
-
-                               $this->showUploadError( $msg->parse() );
-                               break;
                        case UploadBase::VERIFICATION_ERROR:
-                               unset( $details['status'] );
-                               $code = array_shift( $details['details'] );
-                               $this->showUploadError( $this->msg( $code, 
$details['details'] )->parse() );
-                               break;
                        case UploadBase::HOOK_ABORTED:
-                               if ( is_array( $details['error'] ) ) { # allow 
hooks to return error details in an array
-                                       $args = $details['error'];
-                                       $error = array_shift( $args );
-                               } else {
-                                       $error = $details['error'];
-                                       $args = null;
-                               }
-
-                               $this->showUploadError( $this->msg( $error, 
$args )->parse() );
+                               $error = $this->getVerificationErrorMessage( 
$details );
+                               $this->showUploadError( $error );
                                break;
-                       default:
-                               throw new MWException( __METHOD__ . ": Unknown 
value `{$details['status']}`" );
                }
        }
 
@@ -767,6 +721,76 @@
        /*** Functions for formatting warnings ***/
 
        /**
+        * Formats a result of UploadBase::verifyUpload as HTML
+        *
+        * @param array $details The result of UploadBase::verifyUpload
+        * @return string
+        * @throws MWException
+        */
+       public static function getVerificationErrorMessage( $details ) {
+               $context = RequestContext::getMain();
+               $language = $context->getLanguage();
+               $config = $context->getConfig();
+
+               switch ( $details['status'] ) {
+                       /** Statuses that only require name changing **/
+                       case UploadBase::MIN_LENGTH_PARTNAME:
+                               return wfMessage( 'minlength1' )->escaped();
+                       case UploadBase::ILLEGAL_FILENAME:
+                               return wfMessage( 'illegalfilename', 
$details['filtered'] )->parse();
+                       case UploadBase::FILENAME_TOO_LONG:
+                               return wfMessage( 'filename-toolong' 
)->escaped();
+                       case UploadBase::FILETYPE_MISSING:
+                               return wfMessage( 'filetype-missing' )->parse();
+                       case UploadBase::WINDOWS_NONASCII_FILENAME:
+                               return wfMessage( 'windows-nonascii-filename' 
)->parse();
+
+                       /** Statuses that require reuploading **/
+                       case UploadBase::EMPTY_FILE:
+                               return wfMessage( 'emptyfile' )->escaped();
+                       case UploadBase::FILE_TOO_LARGE:
+                               return wfMessage( 'largefileserver' 
)->escaped();
+                       case UploadBase::FILETYPE_BADTYPE:
+                               $msg = wfMessage( 'filetype-banned-type' );
+                               if ( isset( $details['blacklistedExt'] ) ) {
+                                       $msg->params( $language->commaList( 
$details['blacklistedExt'] ) );
+                               } else {
+                                       $msg->params( $details['finalExt'] );
+                               }
+                               $extensions = array_unique( $config->get( 
'FileExtensions' ) );
+                               $msg->params( $language->commaList( $extensions 
),
+                                       count( $extensions ) );
+
+                               // Add PLURAL support for the first parameter. 
This results
+                               // in a bit unlogical parameter sequence, but 
does not break
+                               // old translations
+                               if ( isset( $details['blacklistedExt'] ) ) {
+                                       $msg->params( count( 
$details['blacklistedExt'] ) );
+                               } else {
+                                       $msg->params( 1 );
+                               }
+
+                               return $msg->parse();
+                       case UploadBase::VERIFICATION_ERROR:
+                               unset( $details['status'] );
+                               $code = array_shift( $details['details'] );
+                               return wfMessage( $code, $details['details'] 
)->parse();
+                       case UploadBase::HOOK_ABORTED:
+                               if ( is_array( $details['error'] ) ) { # allow 
hooks to return error details in an array
+                                       $args = $details['error'];
+                                       $error = array_shift( $args );
+                               } else {
+                                       $error = $details['error'];
+                                       $args = null;
+                               }
+
+                               return wfMessage( $error, $args )->parse();
+                       default:
+                               throw new MWException( __METHOD__ . ": Unknown 
value `{$details['status']}`" );
+               }
+       }
+
+       /**
         * Formats a result of UploadBase::getExistsWarning as HTML
         * This check is static and can be done pre-upload via AJAX
         *

-- 
To view, visit https://gerrit.wikimedia.org/r/337854
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6a9a26d6ddd2ae4940a60cfd5a3424e735ca918c
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Matthias Mullie <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to