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:
epriestley
2015-05-07 15:58:35 -07:00
parent a238f6a759
commit 7556a70280
2 changed files with 46 additions and 0 deletions

View File

@@ -104,6 +104,16 @@ final class PhabricatorObjectQuery
}
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();
$workspace = $this->getObjectsFromWorkspace($phids);
@@ -119,6 +129,8 @@ final class PhabricatorObjectQuery
return $results;
}
$this->putPHIDsInFlight($phids);
$groups = array();
foreach ($phids as $phid) {
$type = phid_get_type($phid);