mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-02 02:40:58 +01:00
Prevent Files from requiring infinite policy checks
Summary: Fixes T6726. Currently, a file may be attached to itself (or to other files, ultimately forming a loop). In this case, we currently run around the loop forever trying to load all the files. Instead, decline to load objects if we're inside a query which is already loading them. This produces the right policy result //and// completes in finite time. Test Plan: - Looped two files by writing `{F123}` and `{F124}` on the other files, respectively. - Loaded `F123`. - Saw long hang; used `debug.time-limit` to see huge stack trace instead. - Wrote patch. - `F123` now loads correctly. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6726 Differential Revision: https://secure.phabricator.com/D12756
This commit is contained in:
parent
a238f6a759
commit
7556a70280
2 changed files with 46 additions and 0 deletions
|
@ -104,6 +104,16 @@ final class PhabricatorObjectQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadObjectsByPHID(array $types, array $phids) {
|
private function loadObjectsByPHID(array $types, array $phids) {
|
||||||
|
// Don't try to load PHIDs which are already "in flight"; this prevents us
|
||||||
|
// from recursing indefinitely if policy checks or edges form a loop. We
|
||||||
|
// will decline to load the corresponding objects.
|
||||||
|
$in_flight = $this->getPHIDsInFlight();
|
||||||
|
foreach ($phids as $key => $phid) {
|
||||||
|
if (isset($in_flight[$phid])) {
|
||||||
|
unset($phids[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$results = array();
|
$results = array();
|
||||||
|
|
||||||
$workspace = $this->getObjectsFromWorkspace($phids);
|
$workspace = $this->getObjectsFromWorkspace($phids);
|
||||||
|
@ -119,6 +129,8 @@ final class PhabricatorObjectQuery
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->putPHIDsInFlight($phids);
|
||||||
|
|
||||||
$groups = array();
|
$groups = array();
|
||||||
foreach ($phids as $phid) {
|
foreach ($phids as $phid) {
|
||||||
$type = phid_get_type($phid);
|
$type = phid_get_type($phid);
|
||||||
|
|
|
@ -33,6 +33,7 @@ abstract class PhabricatorPolicyAwareQuery extends PhabricatorOffsetPagedQuery {
|
||||||
private $rawResultLimit;
|
private $rawResultLimit;
|
||||||
private $capabilities;
|
private $capabilities;
|
||||||
private $workspace = array();
|
private $workspace = array();
|
||||||
|
private $inFlightPHIDs = array();
|
||||||
private $policyFilteredPHIDs = array();
|
private $policyFilteredPHIDs = array();
|
||||||
private $canUseApplication;
|
private $canUseApplication;
|
||||||
|
|
||||||
|
@ -468,6 +469,39 @@ abstract class PhabricatorPolicyAwareQuery extends PhabricatorOffsetPagedQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark PHIDs as in flight.
|
||||||
|
*
|
||||||
|
* PHIDs which are "in flight" are actively being queried for. Using this
|
||||||
|
* list can prevent infinite query loops by aborting queries which cycle.
|
||||||
|
*
|
||||||
|
* @param list<phid> List of PHIDs which are now in flight.
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public function putPHIDsInFlight(array $phids) {
|
||||||
|
foreach ($phids as $phid) {
|
||||||
|
$this->inFlightPHIDs[$phid] = $phid;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get PHIDs which are currently in flight.
|
||||||
|
*
|
||||||
|
* PHIDs which are "in flight" are actively being queried for.
|
||||||
|
*
|
||||||
|
* @return map<phid, phid> PHIDs currently in flight.
|
||||||
|
*/
|
||||||
|
public function getPHIDsInFlight() {
|
||||||
|
$results = $this->inFlightPHIDs;
|
||||||
|
if ($this->getParentQuery()) {
|
||||||
|
$results += $this->getParentQuery()->getPHIDsInFlight();
|
||||||
|
}
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( Policy Query Implementation )---------------------------------------- */
|
/* -( Policy Query Implementation )---------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue