From: Ian Baker Date: Thu, 14 Jul 2011 21:33:09 +0000 (+0000) Subject: fixed a condition where re-uploading a file that's already stashed causes breakage... X-Git-Tag: 1.31.0-rc.0~28836 X-Git-Url: http://git.cyclocoop.org/ecrire?a=commitdiff_plain;h=f776cbe6300dd58e6e7f8415f387a4c1d7c23892;p=lhc%2Fweb%2Fwiklou.git fixed a condition where re-uploading a file that's already stashed causes breakage. This mirrors the previous session-based behavior as closely as possible. --- diff --git a/includes/upload/UploadStash.php b/includes/upload/UploadStash.php index 9c526b4faa..66bf33f105 100644 --- a/includes/upload/UploadStash.php +++ b/includes/upload/UploadStash.php @@ -238,6 +238,30 @@ class UploadStash { // insert the file metadata into the db. wfDebug( __METHOD__ . " inserting $stashPath under $key\n" ); $dbw = $this->repo->getMasterDb(); + + // select happens on the master so this can all be in a transaction, which + // avoids a race condition that's likely with multiple people uploading from the same + // set of files + $dbw->begin(); + // first, check to see if it's already there. + $row = $dbw->selectRow( + 'uploadstash', + 'us_user, us_timestamp', + array('us_key' => $key), + __METHOD__ + ); + + // The current user can't have this key if: + // - the key is owned by someone else and + // - the age of the key is less than REPO_AGE + if( is_object( $row ) ) { + if( $row->us_user != $this->userId && + $row->wfTimestamp( TS_UNIX, $row->us_timestamp ) > time() - UploadStash::REPO_AGE * 3600 + ) { + $dbw->rollback(); + throw new UploadStashWrongOwnerException( "Attempting to upload a duplicate of a file that someone else has stashed" ); + } + } $this->fileMetadata[$key] = array( 'us_user' => $this->userId, @@ -255,13 +279,15 @@ class UploadStash { 'us_timestamp' => $dbw->timestamp(), 'us_status' => 'finished' ); - - - $dbw->insert( + + // if a row exists but previous checks on it passed, let the current user take over this key. + $dbw->replace( 'uploadstash', + 'us_key', $this->fileMetadata[$key], __METHOD__ ); + $dbw->commit(); // store the insertid in the class variable so immediate retrieval (possibly laggy) isn't necesary. $this->fileMetadata[$key]['us_id'] = $dbw->insertId();