Commit a66f367f authored by Joey Arhar's avatar Joey Arhar Committed by Chromium LUCI CQ

Fix crash when find-in-page scrolls to disconnected node

Clusterfuzz found an interesting case where if a match is disconnected
from the document, and there is another display locked element in the
document, and the match is in shadowdom, an enclosing block for the
match cannot be created because the tree has no layout objects.

Fixed: 1160283
Change-Id: I1a2c9003b99d2dbe20344bd39b629c7427f11da9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2613952Reviewed-by: default avatarvmpstr <vmpstr@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#841068}
parent e2ee33a2
...@@ -887,7 +887,7 @@ void TextFinder::Scroll(std::unique_ptr<AsyncScrollContext> context) { ...@@ -887,7 +887,7 @@ void TextFinder::Scroll(std::unique_ptr<AsyncScrollContext> context) {
// Likewise, if the target scroll element is display locked, then we shouldn't // Likewise, if the target scroll element is display locked, then we shouldn't
// scroll to it. // scroll to it.
Element* beforematch_element = GetBeforematchElement(*context->range); Element* beforematch_element = GetBeforematchElement(*context->range);
if (context->range->collapsed() || if (context->range->collapsed() || !context->range->IsConnected() ||
(beforematch_element && (beforematch_element &&
DisplayLockUtilities::NearestHiddenMatchableInclusiveAncestor( DisplayLockUtilities::NearestHiddenMatchableInclusiveAncestor(
*beforematch_element))) { *beforematch_element))) {
...@@ -899,7 +899,7 @@ void TextFinder::Scroll(std::unique_ptr<AsyncScrollContext> context) { ...@@ -899,7 +899,7 @@ void TextFinder::Scroll(std::unique_ptr<AsyncScrollContext> context) {
// We also need to re-assign to active_match_ here in order to make sure the // We also need to re-assign to active_match_ here in order to make sure the
// search starts from context->range. active_match_ may have been unassigned // search starts from context->range. active_match_ may have been unassigned
// during the async steps. // during the async steps.
active_match_ = context->range; active_match_ = context->range->IsConnected() ? context->range : nullptr;
FindInternal(context->identifier, context->search_text, context->options, FindInternal(context->identifier, context->search_text, context->options,
context->wrap_within_frame, /*active_now=*/nullptr, context->wrap_within_frame, /*active_now=*/nullptr,
context->first_match, context->wrapped_around); context->first_match, context->wrapped_around);
......
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
.hidden {
content-visibility: hidden-matchable;
}
</style>
<div class="hidden"></div>
<script>
async_test(t => {
const host = document.createElement('div');
document.body.appendChild(host);
const root = host.attachShadow({mode: 'closed'});
const match = document.createElement('div');
match.textContent = 'match';
root.appendChild(match);
match.classList.add('hidden');
match.addEventListener('beforematch', () => {
match.classList.remove('hidden');
host.remove();
});
testRunner.findString('match', ['Async']);
requestAnimationFrame(t.step_func(() => {
requestAnimationFrame(t.step_func_done());
}));
}, `Disconnecting a match in shadowdom shouldn't crash the renderer.`);
</script>
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