Prevent enormous changes from being pushed to repositoires by default
Summary: Fixes T13031. "Enormous" changes are basically changes which are too large to hold in memory, although the actual definition we use today is "more than 1GB of change text or `git diff` runs for more than 15 minutes". If an install configures a Herald content rule like "when content matches /XYZ/, do something" and then a user pushes a 30 GB source file, we can't put it into memory to `preg_match()` it. Currently, the way to handle this case is to write a separate Herald rule that rejects enormous changes. However, this isn't obvious and means the default behavior is unsafe. Make the default behavior safe by rejecting these changes with a message, similar to how we reject "dangerous" changes (which permanently delete or overwrite history) by default. Also, change a couple of UI strings from "Enormous" to "Very Large" to reduce ambiguity. See <https://discourse.phabricator-community.org/t/herald-enormous-check/822>. Test Plan: Changed the definition of "enormous" from 1GB to 1 byte. Pushed a change; got rejected. Allowed enormous changes, pushed, got rejected by a Herald rule. Disabled the Herald rule, pushed, got a clean push. Prevented enormous changes again. Grepped for "enormous" elsewhere in the UI. Reviewers: amckinley Reviewed By: amckinley Subscribers: joshuaspence Maniphest Tasks: T13031 Differential Revision: https://secure.phabricator.com/D18850
This commit is contained in:
@@ -277,9 +277,9 @@ final class DiffusionCommitController extends DiffusionController {
|
||||
'This commit is empty and does not affect any paths.'));
|
||||
} else if ($was_limited) {
|
||||
$info_panel = $this->renderStatusMessage(
|
||||
pht('Enormous Commit'),
|
||||
pht('Very Large Commit'),
|
||||
pht(
|
||||
'This commit is enormous, and affects more than %d files. '.
|
||||
'This commit is very large, and affects more than %d files. '.
|
||||
'Changes are not shown.',
|
||||
$hard_limit));
|
||||
} else if (!$this->getCommitExists()) {
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
final class DiffusionRepositoryEditEnormousController
|
||||
extends DiffusionRepositoryManageController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->loadDiffusionContextForEdit();
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$drequest = $this->getDiffusionRequest();
|
||||
$repository = $drequest->getRepository();
|
||||
|
||||
$panel_uri = id(new DiffusionRepositoryBasicsManagementPanel())
|
||||
->setRepository($repository)
|
||||
->getPanelURI();
|
||||
|
||||
if (!$repository->canAllowEnormousChanges()) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Unprotectable Repository'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'This repository can not be protected from enormous changes '.
|
||||
'because Phabricator does not control what users are allowed '.
|
||||
'to push to it.'))
|
||||
->addCancelButton($panel_uri);
|
||||
}
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$xaction = id(new PhabricatorRepositoryTransaction())
|
||||
->setTransactionType(PhabricatorRepositoryTransaction::TYPE_ENORMOUS)
|
||||
->setNewValue(!$repository->shouldAllowEnormousChanges());
|
||||
|
||||
$editor = id(new PhabricatorRepositoryEditor())
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setActor($viewer)
|
||||
->applyTransactions($repository, array($xaction));
|
||||
|
||||
return id(new AphrontReloadResponse())->setURI($panel_uri);
|
||||
}
|
||||
|
||||
if ($repository->shouldAllowEnormousChanges()) {
|
||||
$title = pht('Prevent Enormous Changes');
|
||||
|
||||
$body = pht(
|
||||
'It will no longer be possible to push enormous changes to this '.
|
||||
'repository.');
|
||||
|
||||
$submit = pht('Prevent Enormous Changes');
|
||||
} else {
|
||||
$title = pht('Allow Enormous Changes');
|
||||
|
||||
$body = array(
|
||||
pht(
|
||||
'If you allow enormous changes, users can push commits which are '.
|
||||
'too large for Herald to process content rules for. This can allow '.
|
||||
'users to evade content rules implemented in Herald.'),
|
||||
pht(
|
||||
'You can selectively configure Herald by adding rules to prevent a '.
|
||||
'subset of enormous changes (for example, based on who is trying '.
|
||||
'to push the change).'),
|
||||
);
|
||||
|
||||
$submit = pht('Allow Enormous Changes');
|
||||
}
|
||||
|
||||
$more_help = pht(
|
||||
'Enormous changes are commits which are too large to process with '.
|
||||
'content rules because: the diff text for the change is larger than '.
|
||||
'%s bytes; or the diff text takes more than %s seconds to extract.',
|
||||
new PhutilNumber(HeraldCommitAdapter::getEnormousByteLimit()),
|
||||
new PhutilNumber(HeraldCommitAdapter::getEnormousTimeLimit()));
|
||||
|
||||
$response = $this->newDialog();
|
||||
|
||||
foreach ((array)$body as $paragraph) {
|
||||
$response->appendParagraph($paragraph);
|
||||
}
|
||||
|
||||
return $response
|
||||
->setTitle($title)
|
||||
->appendParagraph($more_help)
|
||||
->addSubmitButton($submit)
|
||||
->addCancelButton($panel_uri);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user