Commit e5fd7b20 authored by Frank Poole's avatar Frank Poole Committed by Commit Bot

Fix Access violation at BrowserAccessibility::GetInlineTextRect

Currently, BrowserAccessibility::GetInlineTextRect may receive negative
inner text offsets which later induce an access violation when
retrieving character offsets. These negative inner text offsets are the
result of unnecessary searching through sub-trees which do not contain
the queried text offsets.

This change resolves this bug by adding additional validation of inner
text bounds. Any inner text offsets passed to GetInlineTextRect are
pre-validated by GetInnerTextRangeBoundsRect.

Bug: 960452
Change-Id: I4de0f23fcde2319874805141d396f576b176d796
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1605150Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: Frank Poole <frpoole@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#658775}
parent dee9e140
......@@ -658,17 +658,30 @@ gfx::Rect BrowserAccessibility::GetInnerTextRangeBoundsRectInSubtree(
InternalGetChild(i);
const int child_inner_text_length =
browser_accessibility_child->GetInnerText().length();
// The text bounds queried are not in this subtree; skip it and continue.
const int child_start_offset =
std::max(start_offset - child_offset_in_parent, 0);
if (child_start_offset > child_inner_text_length)
continue;
// The text bounds queried have already been gathered; short circuit.
const int child_end_offset =
std::min(end_offset - child_offset_in_parent, child_inner_text_length);
if (child_end_offset < 0)
return bounds;
// Increase the text bounds by the subtree text bounds.
const gfx::Rect child_bounds =
browser_accessibility_child->GetInnerTextRangeBoundsRectInSubtree(
std::max(start_offset - child_offset_in_parent, 0),
std::min(end_offset - child_offset_in_parent,
child_inner_text_length),
coordinate_system, clipping_behavior, offscreen_result);
child_offset_in_parent += child_inner_text_length;
child_start_offset, child_end_offset, coordinate_system,
clipping_behavior, offscreen_result);
if (bounds.IsEmpty())
bounds = child_bounds;
else
bounds.Union(child_bounds);
child_offset_in_parent += child_inner_text_length;
}
return bounds;
......@@ -677,6 +690,7 @@ gfx::Rect BrowserAccessibility::GetInnerTextRangeBoundsRectInSubtree(
gfx::RectF BrowserAccessibility::GetInlineTextRect(const int start_offset,
const int end_offset,
const int max_length) const {
DCHECK(start_offset >= 0 && end_offset >= 0 && start_offset <= end_offset);
int local_start_offset = start_offset, local_end_offset = end_offset;
const std::vector<int32_t>& character_offsets =
GetIntListAttribute(ax::mojom::IntListAttribute::kCharacterOffsets);
......
......@@ -236,6 +236,24 @@ TEST_F(BrowserAccessibilityTest, GetInnerTextRangeBoundsRect) {
root_accessible->PlatformGetChild(0);
ASSERT_NE(nullptr, static_text_accessible);
#ifdef OS_ANDROID
// Android disallows getting inner text from root accessibility nodes.
EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
root_accessible
->GetInnerTextRangeBoundsRect(
0, 1, ui::AXCoordinateSystem::kRootFrame,
ui::AXClippingBehavior::kUnclipped)
.ToString());
#else
// Validate the bounding box of 'H' from root.
EXPECT_EQ(gfx::Rect(100, 100, 6, 9).ToString(),
root_accessible
->GetInnerTextRangeBoundsRect(
0, 1, ui::AXCoordinateSystem::kRootFrame,
ui::AXClippingBehavior::kUnclipped)
.ToString());
#endif
// Validate the bounding box of 'H' from static text.
EXPECT_EQ(gfx::Rect(100, 100, 6, 9).ToString(),
static_text_accessible
......
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