Scripts and data used for generating ZhConversion.php
[lhc/web/wiklou.git] / includes / SpecialUpload.php
index 6bf243c..f02cb23 100644 (file)
@@ -109,7 +109,7 @@ class UploadForm {
         * @access private
         */
        function processUpload() {
-               global $wgUser, $wgOut, $wgLang;
+               global $wgUser, $wgOut, $wgLang, $wgContLang;
                global $wgUploadDirectory;
                global $wgSavedFile, $wgUploadOldVersion;
                global $wgUseCopyrightUpload, $wgCheckCopyrightUpload;
@@ -172,6 +172,10 @@ class UploadForm {
                                return $this->uploadError( wfMsg( 'badfiletype', htmlspecialchars( $ext ) ) );
                        }
                        
+                       if( !$this->verify( $this->mUploadTempName, $ext ) ) {
+                               return $this->uploadError( wfMsg( 'uploadcorrupt' ) );
+                       }
+                       
                        $this->saveUploadedFile( $this->mUploadSaveName, $this->mUploadTempName );
                        if ( !$nt->userCanEdit() ) {
                                return $this->uploadError( wfMsg( 'protectedpage' ) );
@@ -196,7 +200,7 @@ class UploadForm {
                                }
                                if( $nt->getArticleID() ) {
                                        $sk = $wgUser->getSkin();
-                                       $dname = $wgLang->getNsText( Namespace::getImage() ) .':'.$this->mUploadSaveName;
+                                       $dname = $wgContLang->getNsText( Namespace::getImage() ) .':'.$this->mUploadSaveName;
                                        $dlink = $sk->makeKnownLink( $dname, $dname );
                                        $warning .= '<li>'.wfMsg( 'fileexists', $dlink ).'</li>';
                                }
@@ -215,7 +219,7 @@ class UploadForm {
 
                $sk = $wgUser->getSkin();
                $ilink = $sk->makeMediaLink( $this->mUploadSaveName, Image::wfImageUrl( $this->mUploadSaveName ) );
-               $dname = $wgLang->getNsText( Namespace::getImage() ) . ':'.$this->mUploadSaveName;
+               $dname = $wgContLang->getNsText( Namespace::getImage() ) . ':'.$this->mUploadSaveName;
                $dlink = $sk->makeKnownLink( $dname, $dname );
 
                $wgOut->addHTML( '<h2>' . wfMsg( 'successfulupload' ) . "</h2>\n" );
@@ -352,7 +356,7 @@ class UploadForm {
                $fd = wfMsg( 'filedesc' );
                $ulb = wfMsg( 'uploadbtn' );
 
-               $clink = $sk->makeKnownLink( wfMsg( 'copyrightpage' ),
+               $clink = $sk->makeKnownLink( wfMsgForContent( 'copyrightpage' ),
                  wfMsg( 'copyrightpagename' ) );
                $ca = wfMsg( 'affirmation', $clink );
                $iw = wfMsg( 'ignorewarning' );
@@ -396,5 +400,114 @@ class UploadForm {
        <input tabindex='5' type='submit' name=\"wpUpload\" value=\"{$ulb}\" />
        </td></tr></table></form>\n" );
        }
+       
+       /**
+        * Returns false if the file is of a known type but can't be recognized,
+        * indicating a corrupt file.
+        * Returns true otherwise; unknown file types are not checked if given
+        * with an unrecognized extension.
+        *
+        * @param string $tmpfile Pathname to the temporary upload file
+        * @param string $extension The filename extension that the file is to be served with
+        * @return bool
+        */
+       function verify( $tmpfile, $extension ) {
+               if( $this->triggersIEbug( $tmpfile ) ) {
+                       return false;
+               }
+               
+               $fname = 'SpecialUpload::verify';
+               $mergeExtensions = array(
+                       'jpg' => 'jpeg',
+                       'tif' => 'tiff' );
+               $extensionTypes = array(
+                       # See http://www.php.net/getimagesize
+                       1 => 'gif',
+                       2 => 'jpeg',
+                       3 => 'png',
+                       4 => 'swf',
+                       5 => 'psd',
+                       6 => 'bmp',
+                       7 => 'tiff',
+                       8 => 'tiff',
+                       9 => 'jpc',
+                       10 => 'jp2',
+                       11 => 'jpx',
+                       12 => 'jb2',
+                       13 => 'swc',
+                       14 => 'iff',
+                       15 => 'wbmp',
+                       16 => 'xbm' );
+               
+               $extension = strtolower( $extension );
+               if( isset( $mergeExtensions[$extension] ) ) {
+                       $extension = $mergeExtensions[$extension];
+               }
+               wfDebug( "$fname: Testing file '$tmpfile' with given extension '$extension'\n" );
+               
+               if( !in_array( $extension, $extensionTypes ) ) {
+                       # Not a recognized image type. We don't know how to verify these.
+                       # They're allowed by policy or they wouldn't get this far, so we'll
+                       # let them slide for now.
+                       wfDebug( "$fname: Unknown extension; passing.\n" );
+                       return true;
+               }
+               
+               $data = @getimagesize( $tmpfile );
+               if( false === $data ) {
+                       # Didn't recognize the image type.
+                       # Either the image is corrupt or someone's slipping us some
+                       # bogus data such as HTML+JavaScript trying to take advantage
+                       # of an Internet Explorer security flaw.
+                       wfDebug( "$fname: getimagesize() doesn't recognize the file; rejecting.\n" );
+                       return false;
+               }
+               
+               $imageType = $data[2];
+               if( !isset( $extensionTypes[$imageType] ) ) {
+                       # Now we're kind of confused. Perhaps new image types added
+                       # to PHP's support that we don't know about.
+                       # We'll let these slide for now.
+                       wfDebug( "$fname: getimagesize() knows the file, but we don't recognize the type; passing.\n" );
+                       return true;
+               }
+               
+               $ext = strtolower( $extension );
+               if( $extension != $extensionTypes[$imageType] ) {
+                       # The given filename extension doesn't match the
+                       # file type. Probably just a mistake, but it's a stupid
+                       # one and we shouldn't let it pass. KILL THEM!
+                       wfDebug( "$fname: file extension does not match recognized type; rejecting.\n" );
+                       return false;
+               }
+               
+               wfDebug( "$fname: all clear; passing.\n" );
+               return true;
+       }
+       
+       /**
+        * Internet Explorer for Windows performs some really stupid file type
+        * autodetection which can cause it to interpret valid image files as HTML
+        * and potentially execute JavaScript, creating a cross-site scripting
+        * attack vectors.
+        *
+        * Returns true if IE is likely to mistake the given file for HTML.
+        *
+        * @param string $filename
+        * @return bool
+        */
+       function triggersIEbug( $filename ) {
+               $file = fopen( $filename, 'rb' );
+               $chunk = strtolower( fread( $file, 200 ) );
+               fclose( $file );
+               
+               $tags = array( '<html', '<head', '<body', '<script' );
+               foreach( $tags as $tag ) {
+                       if( false !== strpos( $chunk, $tag ) ) {
+                               return true;
+                       }
+               }
+               return false;
+       }
 }
 ?>