@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Iterate over ranges correctly for encryped files

Summary:
Fixes T12079. Currently, when a file is encrypted and a request has "Content-Range", we apply the range first, //then// decrypt the result. This doesn't work since you can't start decrypting something from somewhere in the middle (at least, not with our cipher selection).

Instead: decrypt the result, //then// apply the range.

Test Plan: Added failing unit tests, made them pass

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T12079

Differential Revision: https://secure.phabricator.com/D17623

+49 -8
+10 -1
src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php
··· 174 174 return (4 * 1024 * 1024); 175 175 } 176 176 177 - public function getRawFileDataIterator(PhabricatorFile $file, $begin, $end) { 177 + public function getRawFileDataIterator( 178 + PhabricatorFile $file, 179 + $begin, 180 + $end, 181 + PhabricatorFileStorageFormat $format) { 182 + 183 + // NOTE: It is currently impossible for files stored with the chunk 184 + // engine to have their own formatting (instead, the individual chunks 185 + // are formatted), so we ignore the format object. 186 + 178 187 $chunks = id(new PhabricatorFileChunkQuery()) 179 188 ->setViewer(PhabricatorUser::getOmnipotentUser()) 180 189 ->withChunkHandles(array($file->getStorageHandle()))
+14 -4
src/applications/files/engine/PhabricatorFileStorageEngine.php
··· 325 325 return $engine->getChunkSize(); 326 326 } 327 327 328 - public function getRawFileDataIterator(PhabricatorFile $file, $begin, $end) { 329 - // The default implementation is trivial and just loads the entire file 330 - // upfront. 331 - $data = $this->readFile($file->getStorageHandle()); 328 + public function getRawFileDataIterator( 329 + PhabricatorFile $file, 330 + $begin, 331 + $end, 332 + PhabricatorFileStorageFormat $format) { 333 + 334 + $formatted_data = $this->readFile($file->getStorageHandle()); 335 + $formatted_data = array($formatted_data); 336 + 337 + $data = ''; 338 + $format_iterator = $format->newReadIterator($formatted_data); 339 + foreach ($format_iterator as $raw_chunk) { 340 + $data .= $raw_chunk; 341 + } 332 342 333 343 if ($begin !== null && $end !== null) { 334 344 $data = substr($data, $begin, ($end - $begin));
+18
src/applications/files/format/__tests__/PhabricatorFileStorageFormatTestCase.php
··· 33 33 // The actual raw data in the storage engine should be encoded. 34 34 $raw_data = $engine->readFile($file->getStorageHandle()); 35 35 $this->assertEqual($expect, $raw_data); 36 + 37 + // If we generate an iterator over a slice of the file, it should return 38 + // the decrypted file. 39 + $iterator = $file->getFileDataIterator(4, 14); 40 + $raw_data = ''; 41 + foreach ($iterator as $data_chunk) { 42 + $raw_data .= $data_chunk; 43 + } 44 + $this->assertEqual('cow jumped', $raw_data); 36 45 } 37 46 38 47 public function testAES256Storage() { ··· 73 82 // input data. 74 83 $raw_data = $engine->readFile($file->getStorageHandle()); 75 84 $this->assertTrue($data !== $raw_data); 85 + 86 + // If we generate an iterator over a slice of the file, it should return 87 + // the decrypted file. 88 + $iterator = $file->getFileDataIterator(4, 14); 89 + $raw_data = ''; 90 + foreach ($iterator as $data_chunk) { 91 + $raw_data .= $data_chunk; 92 + } 93 + $this->assertEqual('cow jumped', $raw_data); 76 94 } 77 95 }
+7 -3
src/applications/files/storage/PhabricatorFile.php
··· 746 746 */ 747 747 public function getFileDataIterator($begin = null, $end = null) { 748 748 $engine = $this->instantiateStorageEngine(); 749 - $raw_iterator = $engine->getRawFileDataIterator($this, $begin, $end); 750 749 751 750 $key = $this->getStorageFormat(); 752 - 753 751 $format = id(clone PhabricatorFileStorageFormat::requireFormat($key)) 754 752 ->setFile($this); 755 753 756 - return $format->newReadIterator($raw_iterator); 754 + $iterator = $engine->getRawFileDataIterator( 755 + $this, 756 + $begin, 757 + $end, 758 + $format); 759 + 760 + return $iterator; 757 761 } 758 762 759 763 public function getURI() {