Index: src/applications/diffusion/engine/DiffusionCommitHookEngine.php =================================================================== --- src/applications/diffusion/engine/DiffusionCommitHookEngine.php +++ src/applications/diffusion/engine/DiffusionCommitHookEngine.php @@ -1004,6 +1004,9 @@ } public function loadChangesetsForCommit($identifier) { + $byte_limit = HeraldCommitAdapter::getEnormousByteLimit(); + $time_limit = HeraldCommitAdapter::getEnormousTimeLimit(); + $vcs = $this->getRepository()->getVersionControlSystem(); switch ($vcs) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: @@ -1015,8 +1018,10 @@ 'user' => $this->getViewer(), 'commit' => $identifier, )); + $raw_diff = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest) - ->setTimeout(5 * 60) + ->setTimeout($time_limit) + ->setByteLimit($byte_limit) ->setLinesOfContext(0) ->loadRawDiff(); break; @@ -1027,15 +1032,29 @@ // the "--diff-cmd" flag. // For subversion, we need to use `svnlook`. - list($raw_diff) = execx( + $future = new ExecFuture( 'svnlook diff -t %s %s', $this->subversionTransaction, $this->subversionRepository); + + $future->setTimeout($time_limit); + $future->setStdoutSizeLimit($byte_limit); + $future->setStderrSizeLimit($byte_limit); + + list($raw_diff) = $future->resolvex(); break; default: throw new Exception(pht("Unknown VCS '%s!'", $vcs)); } + if (strlen($raw_diff) >= $byte_limit) { + throw new Exception( + pht( + 'The raw text of this change is enormous (larger than %d '. + 'bytes). Herald can not process it.', + $byte_limit)); + } + $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($changes); Index: src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php =================================================================== --- src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php +++ src/applications/diffusion/herald/HeraldPreCommitContentAdapter.php @@ -34,6 +34,7 @@ self::FIELD_DIFF_CONTENT, self::FIELD_DIFF_ADDED_CONTENT, self::FIELD_DIFF_REMOVED_CONTENT, + self::FIELD_DIFF_ENORMOUS, self::FIELD_REPOSITORY, self::FIELD_REPOSITORY_PROJECTS, self::FIELD_PUSHER, @@ -75,6 +76,9 @@ return $this->getDiffContent('+'); case self::FIELD_DIFF_REMOVED_CONTENT: return $this->getDiffContent('-'); + case self::FIELD_DIFF_ENORMOUS: + $this->getDiffContent('*'); + return ($this->changesets instanceof Exception); case self::FIELD_REPOSITORY: return $this->getHookEngine()->getRepository()->getPHID(); case self::FIELD_REPOSITORY_PROJECTS: Index: src/applications/herald/adapter/HeraldCommitAdapter.php =================================================================== --- src/applications/herald/adapter/HeraldCommitAdapter.php +++ src/applications/herald/adapter/HeraldCommitAdapter.php @@ -270,6 +270,14 @@ return $this->affectedRevision; } + public static function getEnormousByteLimit() { + return 1024 * 1024 * 1024; // 1GB + } + + public static function getEnormousTimeLimit() { + return 60 * 15; // 15 Minutes + } + private function loadCommitDiff() { $drequest = DiffusionRequest::newFromDictionary( array( @@ -278,7 +286,7 @@ 'commit' => $this->commit->getCommitIdentifier(), )); - $byte_limit = (1024 * 1024 * 1024); // 1GB + $byte_limit = self::getEnormousByteLimit(); $raw = DiffusionQuery::callConduitWithDiffusionRequest( PhabricatorUser::getOmnipotentUser(), @@ -286,7 +294,7 @@ 'diffusion.rawdiffquery', array( 'commit' => $this->commit->getCommitIdentifier(), - 'timeout' => (60 * 15), // 15 minutes + 'timeout' => self::getEnormousTimeLimit(), 'byteLimit' => $byte_limit, 'linesOfContext' => 0, )); Index: src/applications/herald/storage/HeraldRule.php =================================================================== --- src/applications/herald/storage/HeraldRule.php +++ src/applications/herald/storage/HeraldRule.php @@ -17,7 +17,7 @@ protected $isDisabled = 0; protected $triggerObjectPHID; - protected $configVersion = 25; + protected $configVersion = 26; // phids for which this rule has been applied private $ruleApplied = self::ATTACHABLE;