Skip to content

Commit a857eb7

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 3f2b326 commit a857eb7

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

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)