Commit c42c5983 authored by epriestley's avatar epriestley
Browse files

Fix an issue where loading a mangled project graph could fail too abruptly

Ref T13484. If you load a subproject S which has a mangled/invalid `parentPath`, the query currently tries to execute an empty edge query and fatals.

Instead, we want to deny-by-default in the policy layer but not fail the query. The subproject should become restricted but not fatal anything related to it.

See T13484 for a future refinement where we could identify "broken / data integrity issue" objects explicilty.

Test Plan:
  - Modified the `projectPath` of some subproject in the database to `QQQQ...`.
  - Loaded that project page.
  - Before patch: fatal after issuing bad edge query.
  - After patch: "functionally correct" policy layer failure, although an explicit "data integrity issue" failure would be better.

Maniphest Tasks: T13484

Differential Revision:
parent 42e46bbe
......@@ -271,6 +271,25 @@ final class PhabricatorProjectQuery
$all_graph = $this->getAllReachableAncestors($projects);
// See T13484. If the graph is damaged (and contains a cycle or an edge
// pointing at a project which has been destroyed), some of the nodes we
// started with may be filtered out by reachability tests. If any of the
// projects we are linking up don't have available ancestors, filter them
// out.
foreach ($projects as $key => $project) {
$project_phid = $project->getPHID();
if (!isset($all_graph[$project_phid])) {
if (!$projects) {
return array();
// NOTE: Although we may not need much information about ancestors, we
// always need to test if the viewer is a member, because we will return
// ancestor projects to the policy filter via ExtendedPolicy calls. If
......@@ -46,6 +46,13 @@ final class PhabricatorEdgeQuery extends PhabricatorQuery {
* @task config
public function withSourcePHIDs(array $source_phids) {
if (!$source_phids) {
throw new Exception(
'Edge list passed to "withSourcePHIDs(...)" is empty, but it must '.
'be nonempty.'));
$this->sourcePHIDs = $source_phids;
return $this;
......@@ -158,11 +165,10 @@ final class PhabricatorEdgeQuery extends PhabricatorQuery {
* @task exec
public function execute() {
if (!$this->sourcePHIDs) {
if ($this->sourcePHIDs === null) {
throw new Exception(
'You must use %s to query edges.',
'You must use "withSourcePHIDs()" to query edges.'));
$sources = phid_group_by_type($this->sourcePHIDs);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment