1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 01:08:50 +02:00

Fix an issue where non-ID changeset state keys were used as changeset IDs

Summary:
Ref T13519. This is a little fuzzy, but I think the workflow here is:

  - View an intradiff, generating an ephemeral comparison changeset with no changeset ID. This produces a state key of "*".
  - Apply "hidden" state changes to the changeset.
  - View some other intradiff and/or diff view.
  - The code attempts to use "*" as a changset ID?

I'm not entirely sure this is accurate; this was observed in production and I couldn't get a clean reproduction case locally.

Optimistically, try making changeset IDs explicit rather than relying on state keys to be "usually changeset-ID-like".

Test Plan: Used "hidden" locally across multiple intradiffs, but I wasn't cleanly able to reproduce the initial issue.

Maniphest Tasks: T13519

Differential Revision: https://secure.phabricator.com/D21223
This commit is contained in:
epriestley 2020-05-04 15:57:22 -07:00
parent 6b69102990
commit a590db28b2
2 changed files with 14 additions and 5 deletions

View file

@ -49,6 +49,11 @@ final class DifferentialViewState
$properties['diffID'] = (int)$diff_id; $properties['diffID'] = (int)$diff_id;
} }
$changeset_id = $changeset->getID();
if ($changeset_id !== null) {
$properties['changesetID'] = (int)$changeset_id;
}
$path_hash = $this->getChangesetPathHash($changeset); $path_hash = $this->getChangesetPathHash($changeset);
$changeset_phid = $this->getChangesetKey($changeset); $changeset_phid = $this->getChangesetKey($changeset);

View file

@ -197,12 +197,12 @@ final class PhabricatorChangesetViewStateEngine
$entries = isort($entries, 'epoch'); $entries = isort($entries, 'epoch');
if ($entries) { if ($entries) {
$other_key = last_key($entries);
$other_spec = last($entries); $other_spec = last($entries);
$this_version = (int)$changeset->getDiffID(); $this_version = (int)$changeset->getDiffID();
$other_version = (int)idx($other_spec, 'diffID'); $other_version = (int)idx($other_spec, 'diffID');
$other_value = (bool)idx($other_spec, 'value', false); $other_value = (bool)idx($other_spec, 'value', false);
$other_id = (int)idx($other_spec, 'changesetID');
if ($other_value === false) { if ($other_value === false) {
$is_hidden = false; $is_hidden = false;
@ -211,10 +211,14 @@ final class PhabricatorChangesetViewStateEngine
} else { } else {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
if ($other_id) {
$other_changeset = id(new DifferentialChangesetQuery()) $other_changeset = id(new DifferentialChangesetQuery())
->setViewer($viewer) ->setViewer($viewer)
->withIDs(array($other_key)) ->withIDs(array($other_id))
->executeOne(); ->executeOne();
} else {
$other_changeset = null;
}
$is_modified = false; $is_modified = false;
if ($other_changeset) { if ($other_changeset) {