Merge "Revert "Added some constants to speed up Setup.php""
[lhc/web/wiklou.git] / includes / upload / UploadBase.php
index a6c3421..67bffc3 100644 (file)
@@ -31,8 +31,6 @@
  * UploadBase and subclasses are the backend of MediaWiki's file uploads.
  * The frontends are formed by ApiUpload and SpecialUpload.
  *
- * See also includes/docs/upload.txt
- *
  * @author Brion Vibber
  * @author Bryan Tong Minh
  * @author Michael Dale
@@ -476,9 +474,10 @@ abstract class UploadBase {
                                return array( 'uploadscripted' );
                        }
                        if ( $this->mFinalExtension == 'svg' || $mime == 'image/svg+xml' ) {
-                               if ( $this->detectScriptInSvg( $this->mTempPath ) ) {
+                               $svgStatus = $this->detectScriptInSvg( $this->mTempPath );
+                               if ( $svgStatus !== false ) {
                                        wfProfileOut( __METHOD__ );
-                                       return array( 'uploadscripted' );
+                                       return $svgStatus;
                                }
                        }
                }
@@ -657,7 +656,11 @@ abstract class UploadBase {
                // Check dupes against archives
                $archivedImage = new ArchivedFile( null, 0, "{$hash}.{$this->mFinalExtension}" );
                if ( $archivedImage->getID() > 0 ) {
-                       $warnings['duplicate-archive'] = $archivedImage->getName();
+                       if ( $archivedImage->userCan( File::DELETED_FILE ) ) {
+                               $warnings['duplicate-archive'] = $archivedImage->getName();
+                       } else {
+                               $warnings['duplicate-archive'] = '';
+                       }
                }
 
                wfProfileOut( __METHOD__ );
@@ -723,7 +726,8 @@ abstract class UploadBase {
                # exclamation mark, so restrict file name to 240 bytes.
                if ( strlen( $this->mFilteredName ) > 240 ) {
                        $this->mTitleError = self::FILENAME_TOO_LONG;
-                       return $this->mTitle = null;
+                       $this->mTitle = null;
+                       return $this->mTitle;
                }
 
                /**
@@ -736,7 +740,8 @@ abstract class UploadBase {
                $nt = Title::makeTitleSafe( NS_FILE, $this->mFilteredName );
                if ( is_null( $nt ) ) {
                        $this->mTitleError = self::ILLEGAL_FILENAME;
-                       return $this->mTitle = null;
+                       $this->mTitle = null;
+                       return $this->mTitle;
                }
                $this->mFilteredName = $nt->getDBkey();
 
@@ -777,19 +782,22 @@ abstract class UploadBase {
 
                if ( $this->mFinalExtension == '' ) {
                        $this->mTitleError = self::FILETYPE_MISSING;
-                       return $this->mTitle = null;
+                       $this->mTitle = null;
+                       return $this->mTitle;
                } elseif ( $blackListedExtensions ||
                                ( $wgCheckFileExtensions && $wgStrictFileExtensions &&
                                        !$this->checkFileExtensionList( $ext, $wgFileExtensions ) ) ) {
                        $this->mBlackListedExtensions = $blackListedExtensions;
                        $this->mTitleError = self::FILETYPE_BADTYPE;
-                       return $this->mTitle = null;
+                       $this->mTitle = null;
+                       return $this->mTitle;
                }
 
                // Windows may be broken with special characters, see bug XXX
                if ( wfIsWindows() && !preg_match( '/^[\x0-\x7f]*$/', $nt->getText() ) ) {
                        $this->mTitleError = self::WINDOWS_NONASCII_FILENAME;
-                       return $this->mTitle = null;
+                       $this->mTitle = null;
+                       return $this->mTitle;
                }
 
                # If there was more than one "extension", reassemble the base
@@ -802,10 +810,12 @@ abstract class UploadBase {
 
                if ( strlen( $partname ) < 1 ) {
                        $this->mTitleError = self::MIN_LENGTH_PARTNAME;
-                       return $this->mTitle = null;
+                       $this->mTitle = null;
+                       return $this->mTitle;
                }
 
-               return $this->mTitle = $nt;
+               $this->mTitle = $nt;
+               return $this->mTitle;
        }
 
        /**
@@ -1155,11 +1165,36 @@ abstract class UploadBase {
 
        /**
         * @param $filename string
-        * @return bool
+        * @return mixed false of the file is verified (does not contain scripts), array otherwise.
         */
        protected function detectScriptInSvg( $filename ) {
-               $check = new XmlTypeCheck( $filename, array( $this, 'checkSvgScriptCallback' ) );
-               return $check->filterMatch;
+               $check = new XmlTypeCheck(
+                       $filename,
+                       array( $this, 'checkSvgScriptCallback' ),
+                       true,
+                       array( 'processing_instruction_handler' => 'UploadBase::checkSvgPICallback' )
+               );
+               if ( $check->wellFormed !== true ) {
+                       // Invalid xml (bug 58553)
+                       return array( 'uploadinvalidxml' );
+               } elseif ( $check->filterMatch ) {
+                       return array( 'uploadscripted' );
+               }
+               return false;
+       }
+
+       /**
+        * Callback to filter SVG Processing Instructions.
+        * @param $target string processing instruction name
+        * @param $data string processing instruction attribute and value
+        * @return bool (true if the filter identified something bad)
+        */
+       public static function checkSvgPICallback( $target, $data ) {
+               // Don't allow external stylesheets (bug 57550)
+               if ( preg_match( '/xml-stylesheet/i', $target) ) {
+                       return true;
+               }
+               return false;
        }
 
        /**