From 46ebee74a6d4e193e46ec0e4c817d6dd09211f26 Mon Sep 17 00:00:00 2001 From: rillke Date: Fri, 13 Feb 2015 19:10:36 +0100 Subject: [PATCH] Detect duplicate archived files by SHA1 search on upload - As of now, we detect duplicate files by a combination of sha1 and file extension. - Since multiple file extensions for the same MIME are permitted this method does not reliably work. Bug: T74070 Change-Id: If13059441097799227f23ece36a96c8375f17aab --- RELEASE-NOTES-1.25 | 2 ++ includes/filerepo/file/ArchivedFile.php | 12 ++++++++++-- includes/upload/UploadBase.php | 8 ++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/RELEASE-NOTES-1.25 b/RELEASE-NOTES-1.25 index 2c4288501e..8992ce0ce9 100644 --- a/RELEASE-NOTES-1.25 +++ b/RELEASE-NOTES-1.25 @@ -152,6 +152,8 @@ production. ** 'extend' method added to QuickTemplate to append additional values to any field of data array * (T86974) Several Title methods now load from the database when necessary (instead of returning incorrect results) even when the page ID is known. +* (T74070) Duplicate search for archived files on file upload now omits the extension. + This requires the fa_sha1 field being populated. === Action API changes in 1.25 === * (T67403) XML tag highlighting is now only performed for formats diff --git a/includes/filerepo/file/ArchivedFile.php b/includes/filerepo/file/ArchivedFile.php index 5b0d8e2baa..1d45428310 100644 --- a/includes/filerepo/file/ArchivedFile.php +++ b/includes/filerepo/file/ArchivedFile.php @@ -100,8 +100,9 @@ class ArchivedFile { * @param Title $title * @param int $id * @param string $key + * @param string $sha1 */ - function __construct( $title, $id = 0, $key = '' ) { + function __construct( $title, $id = 0, $key = '', $sha1 = '' ) { $this->id = -1; $this->title = false; $this->name = false; @@ -136,7 +137,11 @@ class ArchivedFile { $this->key = $key; } - if ( !$id && !$key && !( $title instanceof Title ) ) { + if ( $sha1 ) { + $this->sha1 = $sha1; + } + + if ( !$id && !$key && !( $title instanceof Title ) && !$sha1 ) { throw new MWException( "No specifications provided to ArchivedFile constructor." ); } } @@ -162,6 +167,9 @@ class ArchivedFile { if ( $this->title ) { $conds['fa_name'] = $this->title->getDBkey(); } + if ( $this->sha1 ) { + $conds['fa_sha1'] = $this->sha1; + } if ( !count( $conds ) ) { throw new MWException( "No specific information for retrieving archived file" ); diff --git a/includes/upload/UploadBase.php b/includes/upload/UploadBase.php index a8a38c70cb..fccb5e1a3a 100644 --- a/includes/upload/UploadBase.php +++ b/includes/upload/UploadBase.php @@ -677,10 +677,10 @@ abstract class UploadBase { } // Check dupes against archives - $archivedImage = new ArchivedFile( null, 0, "{$hash}.{$this->mFinalExtension}" ); - if ( $archivedImage->getID() > 0 ) { - if ( $archivedImage->userCan( File::DELETED_FILE ) ) { - $warnings['duplicate-archive'] = $archivedImage->getName(); + $archivedFile = new ArchivedFile( null, 0, '', $hash ); + if ( $archivedFile->getID() > 0 ) { + if ( $archivedFile->userCan( File::DELETED_FILE ) ) { + $warnings['duplicate-archive'] = $archivedFile->getName(); } else { $warnings['duplicate-archive'] = ''; } -- 2.20.1