1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-19 16:58:48 +02:00

Stop trying to assess the image dimensions of large files and file chunks

Summary:
Depends on D18828. Ref T7789. See <https://discourse.phabricator-community.org/t/git-lfs-fails-with-large-images/584>.

Currently, when you upload a large (>4MB) image, we may try to assess the dimensions for the image and for each individual chunk.

At best, this is slow and not useful. At worst, it fatals or consumes a ton of memory and I/O we don't need to be using.

Instead:

  - Don't try to assess dimensions for chunked files.
  - Don't try to assess dimensions for the chunks themselves.
  - Squelch errors for bad data, etc., that `gd` can't actually read, since we recover sensibly.

Test Plan:
  - Created a 2048x2048 PNG in Photoshop using the "Random Noise" filter which weighs 8.5MB.
  - Uploaded it.
  - Before patch: got complaints in log about `imagecreatefromstring()` failing, although the actual upload went OK in my environment.
  - After patch: clean log, no attempt to detect the size of a big image.
  - Also uploaded a small image, got dimensions detected properly still.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T7789

Differential Revision: https://secure.phabricator.com/D18830
This commit is contained in:
epriestley 2017-12-13 06:28:11 -08:00
parent 5295840a4c
commit e1d6bad864
3 changed files with 31 additions and 2 deletions

View file

@ -64,6 +64,7 @@ final class FileUploadChunkConduitAPIMethod
$params = array(
'name' => $file->getMonogram().'.chunk-'.$chunk->getID(),
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
'chunk' => true,
);
if ($mime_type !== null) {

View file

@ -40,6 +40,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
const METADATA_PROFILE = 'profile';
const METADATA_STORAGE = 'storage';
const METADATA_INTEGRITY = 'integrity';
const METADATA_CHUNK = 'chunk';
const STATUS_ACTIVE = 'active';
const STATUS_DELETED = 'deleted';
@ -410,7 +411,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
try {
$file->updateDimensions(false);
} catch (Exception $ex) {
// Do nothing
// Do nothing.
}
$file->saveAndIndex();
@ -1057,9 +1058,20 @@ final class PhabricatorFile extends PhabricatorFileDAO
throw new Exception(pht('Cannot retrieve image information.'));
}
if ($this->getIsChunk()) {
throw new Exception(
pht('Refusing to assess image dimensions of file chunk.'));
}
$engine = $this->instantiateStorageEngine();
if ($engine->isChunkEngine()) {
throw new Exception(
pht('Refusing to assess image dimensions of chunked file.'));
}
$data = $this->loadFileData();
$img = imagecreatefromstring($data);
$img = @imagecreatefromstring($data);
if ($img === false) {
throw new Exception(pht('Error when decoding image.'));
}
@ -1255,6 +1267,15 @@ final class PhabricatorFile extends PhabricatorFileDAO
return $this;
}
public function getIsChunk() {
return idx($this->metadata, self::METADATA_CHUNK);
}
public function setIsChunk($value) {
$this->metadata[self::METADATA_CHUNK] = $value;
return $this;
}
public function setIntegrityHash($integrity_hash) {
$this->metadata[self::METADATA_INTEGRITY] = $integrity_hash;
return $this;
@ -1339,6 +1360,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
'mime-type' => 'optional string',
'builtin' => 'optional string',
'storageEngines' => 'optional list<PhabricatorFileStorageEngine>',
'chunk' => 'optional bool',
));
$file_name = idx($params, 'name');
@ -1416,6 +1438,11 @@ final class PhabricatorFile extends PhabricatorFileDAO
$this->setMimeType($mime_type);
}
$is_chunk = idx($params, 'chunk');
if ($is_chunk) {
$this->setIsChunk(true);
}
return $this;
}

View file

@ -189,6 +189,7 @@ abstract class PhabricatorFileUploadSource
$params = array(
'name' => $file->getMonogram().'.chunk-'.$offset,
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
'chunk' => true,
);
// If this isn't the initial chunk, provide a dummy MIME type so we do not