Skip to content

Commit 2041e63

Browse files
committed
Bug 1974382: Avoid short-circuit evaluation on frame ancestor lookup. r=layout-anchor-positioning-reviewers,dshin
Differential Revision: https://phabricator.services.mozilla.com/D255501
1 parent 38db7e8 commit 2041e63

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

layout/base/PresShell.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12091,7 +12091,18 @@ void PresShell::AddAnchorPosAnchor(const nsAtom* aName, nsIFrame* aFrame) {
1209112091
// If the same element is already in the array,
1209212092
// someone forgot to call RemoveAnchorPosAnchor.
1209312093
if (BinarySearchIf(entry, 0, entry.Length(), cmp, &matchOrInsertionIdx)) {
12094-
MOZ_ASSERT_UNREACHABLE("Anchor added already");
12094+
if (entry.ElementAt(matchOrInsertionIdx) == aFrame) {
12095+
// nsLayoutUtils::CompareTreePosition() returns 0 when the frames are
12096+
// in different documents or child lists. This indicates that
12097+
// the tree is being restructured and we can defer anchor insertion
12098+
// to a MergeAnchorPosAnchors call after the restructuring is complete.
12099+
MOZ_ASSERT_UNREACHABLE("Attempt to insert a frame twice was made");
12100+
return;
12101+
}
12102+
MOZ_ASSERT(!entry.Contains(aFrame));
12103+
12104+
MOZ_ASSERT_UNREACHABLE("Frames were in different documents or child lists");
12105+
1209512106
return;
1209612107
}
1209712108

layout/base/nsLayoutUtils.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,11 +1161,16 @@ int32_t nsLayoutUtils::DoCompareTreePosition(
11611161
}
11621162

11631163
AutoTArray<const nsIFrame*, 20> frame1Ancestors;
1164-
if (aCommonAncestor &&
1165-
!FillAncestors(aFrame1, aCommonAncestor, &frame1Ancestors)) {
1164+
const nsIFrame* frame1CommonAncestor =
1165+
FillAncestors(aFrame1, aCommonAncestor, &frame1Ancestors);
1166+
if (aCommonAncestor && !frame1CommonAncestor) {
11661167
// We reached the root of the frame tree ... if aCommonAncestor was set,
1167-
// it is wrong
1168-
return DoCompareTreePosition(aFrame1, aFrame2, nullptr);
1168+
// it is wrong. We need to recompute without aCommonAncestor,
1169+
// but computing frame1Ancestors array again can be avoided by
1170+
// swapping the order of the arguments.
1171+
const int32_t oppositeResult =
1172+
DoCompareTreePosition(aFrame2, aFrame1, frame1Ancestors, nullptr);
1173+
return -oppositeResult;
11691174
}
11701175

11711176
int32_t last1 = int32_t(frame1Ancestors.Length()) - 1;

0 commit comments

Comments
 (0)