Commit 1810df13 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

Stop InlineContents iteration when reaching document boundary

This patch stops a crash in InlineContents previous/next iteration by
terminating the iteration at document boundary, so that subsequent
operations don't proceed with invalid parameters.

Bug: 903723
Change-Id: Iaed2ac1d5d74d3ab59da3a2f0db2d4f8150fb21b
Reviewed-on: https://chromium-review.googlesource.com/c/1331571Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarYoichi Osato <yoichio@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607499}
parent 68ea9d19
......@@ -328,35 +328,53 @@ EphemeralRangeInFlatTree TextOffsetMapping::InlineContents::GetRange() const {
PositionInFlatTree
TextOffsetMapping::InlineContents::LastPositionBeforeBlockFlow() const {
DCHECK(block_flow_);
if (const Node* node = block_flow_->NonPseudoNode())
if (const Node* node = block_flow_->NonPseudoNode()) {
if (!FlatTreeTraversal::Parent(*node)) {
// Reached start of document.
return PositionInFlatTree();
}
return PositionInFlatTree::BeforeNode(*node);
}
DCHECK(first_);
DCHECK(first_->NonPseudoNode());
DCHECK(FlatTreeTraversal::Parent(*first_->NonPseudoNode()));
return PositionInFlatTree::BeforeNode(*first_->NonPseudoNode());
}
PositionInFlatTree
TextOffsetMapping::InlineContents::FirstPositionAfterBlockFlow() const {
DCHECK(block_flow_);
if (const Node* node = block_flow_->NonPseudoNode())
if (const Node* node = block_flow_->NonPseudoNode()) {
if (!FlatTreeTraversal::Parent(*node)) {
// Reached end of document.
return PositionInFlatTree();
}
return PositionInFlatTree::AfterNode(*node);
}
DCHECK(last_);
DCHECK(last_->NonPseudoNode());
DCHECK(FlatTreeTraversal::Parent(*last_->NonPseudoNode()));
return PositionInFlatTree::AfterNode(*last_->NonPseudoNode());
}
// static
TextOffsetMapping::InlineContents TextOffsetMapping::InlineContents::NextOf(
const InlineContents& inline_contents) {
return TextOffsetMapping::FindForwardInlineContents(
inline_contents.FirstPositionAfterBlockFlow());
const PositionInFlatTree position_after =
inline_contents.FirstPositionAfterBlockFlow();
if (position_after.IsNull())
return InlineContents();
return TextOffsetMapping::FindForwardInlineContents(position_after);
}
// static
TextOffsetMapping::InlineContents TextOffsetMapping::InlineContents::PreviousOf(
const InlineContents& inline_contents) {
return TextOffsetMapping::FindBackwardInlineContents(
inline_contents.LastPositionBeforeBlockFlow());
const PositionInFlatTree position_before =
inline_contents.LastPositionBeforeBlockFlow();
if (position_before.IsNull())
return InlineContents();
return TextOffsetMapping::FindBackwardInlineContents(position_before);
}
std::ostream& operator<<(
......
......@@ -369,4 +369,20 @@ TEST_P(ParameterizedTextOffsetMappingTest, GetPositionAfter) {
// We hit DCHECK for offset 8, because we walk on "012 456".
}
// https://crbug.com/903723
TEST_P(ParameterizedTextOffsetMappingTest, InlineContentsWithDocumentBoundary) {
InsertStyleElement("*{position:fixed}");
SetBodyContent("");
const PositionInFlatTree position =
PositionInFlatTree::FirstPositionInNode(*GetDocument().body());
const TextOffsetMapping::InlineContents inline_contents =
TextOffsetMapping::FindForwardInlineContents(position);
EXPECT_TRUE(inline_contents.IsNotNull());
// Should not crash when previous/next iteration reaches document boundary.
EXPECT_TRUE(
TextOffsetMapping::InlineContents::PreviousOf(inline_contents).IsNull());
EXPECT_TRUE(
TextOffsetMapping::InlineContents::NextOf(inline_contents).IsNull());
}
} // namespace blink
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