Difference between revisions of "Wiki Upload Fix"

From WolfTech
Jump to navigation Jump to search
Line 1: Line 1:
 
== How It Works ==
 
== How It Works ==
  
The idea behind this is that the fopen(), fclose(), fread() calls that MediaWiki uses don't have access to the /tmp/ directory where uploaded files are temporarily stored. The move_uploaded_file() function however does have access to move PHP uploaded files out of the /tmp. What we're doing here is taking the uploaded file from the /tmp directory, uploading it a local location we can access, then substituting server's temporary $_FILES[file]['tmp_name'] variable with where we've put the new file. The wiki has access to this folder and therefore can do all the necessary checks.
+
The idea behind this is that the fopen(), fclose(), fread() calls that MediaWiki uses don't have access to the /tmp/ directory where uploaded files are temporarily stored. The move_uploaded_file() function however does have access to move PHP uploaded files out of the /tmp. What we're doing here is taking the uploaded file from the /tmp directory, uploading it to a local location we can access, then substituting server's temporary $_FILES[file]['tmp_name'] variable with where we've put the new file. The wiki has access to this folder and therefore can do all the necessary checks.
  
 
The only thing we need to make sure gets done is cleanup of the files sitting in our tmp directory, thus we edit the files below to take care of that.
 
The only thing we need to make sure gets done is cleanup of the files sitting in our tmp directory, thus we edit the files below to take care of that.

Revision as of 10:06, 14 March 2008

How It Works

The idea behind this is that the fopen(), fclose(), fread() calls that MediaWiki uses don't have access to the /tmp/ directory where uploaded files are temporarily stored. The move_uploaded_file() function however does have access to move PHP uploaded files out of the /tmp. What we're doing here is taking the uploaded file from the /tmp directory, uploading it to a local location we can access, then substituting server's temporary $_FILES[file]['tmp_name'] variable with where we've put the new file. The wiki has access to this folder and therefore can do all the necessary checks.

The only thing we need to make sure gets done is cleanup of the files sitting in our tmp directory, thus we edit the files below to take care of that.

Code Changes

Make sure there is a "tmp" folder in the main folder of your Wiki directory. Give it the AFS permissions necessary to be writeable by the Engineering web servers.

Open includes/SpecialUpload.php and find:

		$status = $this->mLocalFile->upload( $this->mTempPath, $this->mComment, $pageText, 
			File::DELETE_SOURCE, $this->mFileProps );
		if ( !$status->isGood() ) {
			$this->showError( $status->getWikiText() );
		} else {
			if ( $this->mWatchthis ) {
				global $wgUser;
				$wgUser->addWatch( $this->mLocalFile->getTitle() );
			}
			// Success, redirect to description page
			$wgOut->redirect( $this->mLocalFile->getTitle()->getFullURL() );
			$img = null; // @todo: added to avoid passing a ref to null - should this be defined somewhere?
			wfRunHooks( 'UploadComplete', array( &$img ) );
		}

Replace with:

		$status = $this->mLocalFile->upload( $this->mTempPath, $this->mComment, $pageText, 
			File::DELETE_SOURCE, $this->mFileProps );
			echo $this->mTempPath;
		if ( !$status->isGood() ) {
			$this->showError( $status->getWikiText() );
		} else {
			if ( $this->mWatchthis ) {
				global $wgUser;
				$wgUser->addWatch( $this->mLocalFile->getTitle() );
			}
			// Success, redirect to description page
			$this->cleanupTempFile();
			$wgOut->redirect( $this->mLocalFile->getTitle()->getFullURL() );
			$img = null; // @todo: added to avoid passing a ref to null - should this be defined somewhere?
			wfRunHooks( 'UploadComplete', array( &$img ) );
		}

Also in includes\SpecialUpload.php find:

	function uploadError( $error ) {
		global $wgOut;
		$wgOut->addHTML( "<h2>" . wfMsgHtml( 'uploadwarning' ) . "</h2>\n" );
		$wgOut->addHTML( "<span class='error'>{$error}</span>\n" );
	}

Replace with:

	function uploadError( $error ) {
		global $wgOut;
		$this->mRemoveTempFile = file_exists( $this->mTempPath );
		$this->cleanupTempFile();
		$wgOut->addHTML( "<h2>" . wfMsgHtml( 'uploadwarning' ) . "</h2>\n" );
		$wgOut->addHTML( "<span class='error'>{$error}</span>\n" );
	}

Open includes/WebRequest.php and find:

	function getFileTempname( $key ) {
		if( !isset( $_FILES[$key] ) ) {
			return NULL;
		}
		return $_FILES[$key]['tmp_name'];
	}

Replace with:

	function getFileTempname( $key ) {
		if( !isset( $_FILES[$key] ) ) {
			return NULL;
		}
		
		if (preg_match('#^/tmp/php#', $_FILES[$key]['tmp_name'])){
			if (move_uploaded_file($_FILES[$key]['tmp_name'], $GLOBALS['IP'] . $_FILES[$key]['tmp_name'])){
				$_FILES[$key]['tmp_name'] = $GLOBALS['IP'] . $_FILES[$key]['tmp_name'];
			}
		}
		
		return $_FILES[$key]['tmp_name'];
	}