Add filesize limits for document rendering engines and support partial/complete rendering
Summary: Depends on D19238. Ref T13105. Give document engines some reasonable automatic support for degrading gracefully when someone tries to hexdump a 100MB file or similar. Also, make "Video" sort above "Audio" for files which could be rendered either way. Test Plan: Viewed audio, video, image, and other files. Adjusted limits and saw full, partial, and fallback/error rendering. Maniphest Tasks: T13105 Differential Revision: https://secure.phabricator.com/D19239
This commit is contained in:
@@ -22,6 +22,18 @@ abstract class PhabricatorDocumentEngine
|
||||
PhabricatorDocumentRef $ref);
|
||||
|
||||
final public function newDocument(PhabricatorDocumentRef $ref) {
|
||||
$can_complete = $this->canRenderCompleteDocument($ref);
|
||||
$can_partial = $this->canRenderPartialDocument($ref);
|
||||
|
||||
if (!$can_complete && !$can_partial) {
|
||||
return $this->newMessage(
|
||||
pht(
|
||||
'This document is too large to be rendered inline. (The document '.
|
||||
'is %s bytes, the limit for this engine is %s bytes.)',
|
||||
new PhutilNumber($ref->getByteLength()),
|
||||
new PhutilNumber($this->getByteLengthLimit())));
|
||||
}
|
||||
|
||||
return $this->newDocumentContent($ref);
|
||||
}
|
||||
|
||||
@@ -51,20 +63,49 @@ abstract class PhabricatorDocumentEngine
|
||||
final public function newSortVector(PhabricatorDocumentRef $ref) {
|
||||
$content_score = $this->getContentScore($ref);
|
||||
|
||||
// Prefer engines which can render the entire file over engines which
|
||||
// can only render a header, and engines which can render a header over
|
||||
// engines which can't render anything.
|
||||
if ($this->canRenderCompleteDocument($ref)) {
|
||||
$limit_score = 0;
|
||||
} else if ($this->canRenderPartialDocument($ref)) {
|
||||
$limit_score = 1;
|
||||
} else {
|
||||
$limit_score = 2;
|
||||
}
|
||||
|
||||
return id(new PhutilSortVector())
|
||||
->addInt($limit_score)
|
||||
->addInt(-$content_score);
|
||||
}
|
||||
|
||||
protected function getContentScore() {
|
||||
protected function getContentScore(PhabricatorDocumentRef $ref) {
|
||||
return 2000;
|
||||
}
|
||||
|
||||
abstract public function getViewAsLabel(PhabricatorDocumentRef $ref);
|
||||
|
||||
public function getViewAsIconIcon(PhabricatorDocumentRef $ref) {
|
||||
$can_complete = $this->canRenderCompleteDocument($ref);
|
||||
$can_partial = $this->canRenderPartialDocument($ref);
|
||||
|
||||
if (!$can_complete && !$can_partial) {
|
||||
return 'fa-times';
|
||||
}
|
||||
|
||||
return $this->getDocumentIconIcon($ref);
|
||||
}
|
||||
|
||||
public function getViewAsIconColor(PhabricatorDocumentRef $ref) {
|
||||
$can_complete = $this->canRenderCompleteDocument($ref);
|
||||
|
||||
if (!$can_complete) {
|
||||
return 'grey';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRenderURI(PhabricatorDocumentRef $ref) {
|
||||
$file = $ref->getFile();
|
||||
if (!$file) {
|
||||
@@ -107,4 +148,33 @@ abstract class PhabricatorDocumentEngine
|
||||
return array_select_keys($engines, array_keys($vectors));
|
||||
}
|
||||
|
||||
protected function getByteLengthLimit() {
|
||||
return (1024 * 1024 * 8);
|
||||
}
|
||||
|
||||
protected function canRenderCompleteDocument(PhabricatorDocumentRef $ref) {
|
||||
$limit = $this->getByteLengthLimit();
|
||||
if ($limit) {
|
||||
$length = $ref->getByteLength();
|
||||
if ($length > $limit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function canRenderPartialDocument(PhabricatorDocumentRef $ref) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function newMessage($message) {
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'document-engine-error',
|
||||
),
|
||||
$message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user