From ff2b19d58760980227e80676613949cdda91b786 Mon Sep 17 00:00:00 2001 From: Thomas Keller Date: Sat, 19 Nov 2011 01:13:22 +0100 Subject: [PATCH] The "exists file from archive in project" check was flawed because $name was overwritten. So, this was fixed by adding a special functionality when archive files are uploaded that replace existing files with equal names; these are now deleted. This is docuemented more clearly in the FAQ and it is also documented now that files in the archive that are not listed in the manifest are not extracted. --- src/IDF/Form/UploadArchive.php | 52 +++++++++++-------- src/IDF/templates/idf/faq-archive-format.html | 24 +++++++-- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/IDF/Form/UploadArchive.php b/src/IDF/Form/UploadArchive.php index 3699d51..4d014ed 100644 --- a/src/IDF/Form/UploadArchive.php +++ b/src/IDF/Form/UploadArchive.php @@ -58,13 +58,13 @@ class IDF_Form_UploadArchive extends Pluf_Form $this->archiveHelper->validate(); // extension validation - $names = $this->archiveHelper->getEntryNames(); - foreach ($names as $name) { + $fileNames = $this->archiveHelper->getEntryNames(); + foreach ($fileNames as $fileName) { $extra = strtolower(implode('|', explode(' ', Pluf::f('idf_extra_upload_ext')))); if (strlen($extra)) $extra .= '|'; - if (!preg_match('/\.('.$extra.'png|jpg|jpeg|gif|bmp|psd|tif|aiff|asf|avi|bz2|css|doc|eps|gz|jar|mdtext|mid|mov|mp3|mpg|ogg|pdf|ppt|ps|qt|ra|ram|rm|rtf|sdd|sdw|sit|sxi|sxw|swf|tgz|txt|wav|xls|xml|war|wmv|zip)$/i', $name)) { - @unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['file']); - throw new Pluf_Form_Invalid(sprintf(__('For security reasons, you cannot upload a file (%s) with this extension.'), $name)); + if (!preg_match('/\.('.$extra.'png|jpg|jpeg|gif|bmp|psd|tif|aiff|asf|avi|bz2|css|doc|eps|gz|jar|mdtext|mid|mov|mp3|mpg|ogg|pdf|ppt|ps|qt|ra|ram|rm|rtf|sdd|sdw|sit|sxi|sxw|swf|tgz|txt|wav|xls|xml|war|wmv|zip)$/i', $fileName)) { + @unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['archive']); + throw new Pluf_Form_Invalid(sprintf(__('For security reasons, you cannot upload a file (%s) with this extension.'), $fileName)); } } @@ -78,8 +78,8 @@ class IDF_Form_UploadArchive extends Pluf_Form } } - foreach ($names as $name) { - $meta = $this->archiveHelper->getMetaData($name); + foreach ($fileNames as $fileName) { + $meta = $this->archiveHelper->getMetaData($fileName); $count = array(); foreach ($meta['labels'] as $label) { $label = trim($label); @@ -100,12 +100,13 @@ class IDF_Form_UploadArchive extends Pluf_Form } } - $sql = new Pluf_SQL('file=%s AND project=%s', array($name, $this->project->id)); + $sql = new Pluf_SQL('file=%s AND project=%s', array($fileName, $this->project->id)); $upload = Pluf::factory('IDF_Upload')->getOne(array('filter' => $sql->gen())); - if ($upload) { + $meta = $this->archiveHelper->getMetaData($fileName); + if ($upload != null && $meta['replaces'] !== $fileName) { throw new Pluf_Form_Invalid( - sprintf(__('A file with the name "%s" has already been uploaded.'), $name)); + sprintf(__('A file with the name "%s" has already been uploaded and is not marked to be replaced.'), $fileName)); } } @@ -158,6 +159,24 @@ class IDF_Form_UploadArchive extends Pluf_Form } } + // process a possible replacement + if (!empty($meta['replaces'])) { + $sql = new Pluf_SQL('file=%s AND project=%s', array($meta['replaces'], $this->project->id)); + $oldUpload = Pluf::factory('IDF_Upload')->getOne(array('filter' => $sql->gen())); + + if ($oldUpload) { + if ($meta['replaces'] === $fileName) { + $oldUpload->delete(); + } else { + $tags = $this->project->getTagsFromConfig('labels_download_predefined', + IDF_Form_UploadConf::init_predefined); + // the deprecate tag is - by definition - always the last one + $deprecatedTag = array_pop($tags); + $oldUpload->setAssoc($deprecatedTag); + } + } + } + // extract the file $this->archiveHelper->extract($fileName, $uploadDir); @@ -175,19 +194,6 @@ class IDF_Form_UploadArchive extends Pluf_Form $upload->setAssoc($tag); } - // process a possible replacement - if (!empty($meta['replaces'])) { - $sql = new Pluf_SQL('file=%s AND project=%s', array($meta['replaces'], $this->project->id)); - $oldUpload = Pluf::factory('IDF_Upload')->getOne(array('filter' => $sql->gen())); - if ($oldUpload) { - $tags = $this->project->getTagsFromConfig('labels_download_predefined', - IDF_Form_UploadConf::init_predefined); - // the deprecate tag is - by definition - always the last one - $deprecatedTag = array_pop($tags); - $oldUpload->setAssoc($deprecatedTag); - } - } - // send the notification $upload->notify($this->project->getConf()); /** diff --git a/src/IDF/templates/idf/faq-archive-format.html b/src/IDF/templates/idf/faq-archive-format.html index fde66a1..5e25d10 100644 --- a/src/IDF/templates/idf/faq-archive-format.html +++ b/src/IDF/templates/idf/faq-archive-format.html @@ -25,8 +25,9 @@ contain an additional manifest file which describes the files that should be pub

Once such an archive has been uploaded and validated by InDefero, its files are extracted and individual downloads are created for each of them. If the archive contains files -that should deprecate existing downloads, then InDefero takes care of this as well - -automatically. +that should replace existing downloads, then InDefero takes care of this as well - +automatically. Files that exist in the archive but are not listed in the manifest are +not extracted.

@@ -85,9 +86,22 @@ This is the DTD for the format:

The format is more or less self-explaining, all fields map to properties of a single download. One special element has been introduced though, replaces. If this optional element -is given, InDefero looks for a file with that name in the project and deprecates it by attaching -the label Other:Deprecated to it. If no such file is found, the element is simply -ignored. +is given, InDefero looks for a file with that name in the project and acts in one of the following +two ways: +

+ + + +If no existing file is found for the replaces tag, then this is completely ignored.

{/block}