Commit e5444794 authored by Kurt Catti-Schmidt (SCHMIDT)'s avatar Kurt Catti-Schmidt (SCHMIDT) Committed by Commit Bot

DCHECK in AccessibilityPerformAction with IA2 setSelection method

This is the corresponding IA2 fix for the selection-iframe crash here:
https://chromium-review.googlesource.com/c/chromium/src/+/2300266

The approach is different for IA2. Since IA2's setSelectionRanges
requires actual nodes to be passed in, it doesn't make sense to move
the selection range to different nodes than specified. Instead, this
change simply returns E_INVALIDARG when two nodes are provided that
exist in different trees. I generally don't like this approach, as it
is reporting implementation limitations as a user-error, but I think
it's the best approach for this particular scenario.

A browser test was added that would crash without this fix in place.

AX-Relnotes: n/a

Bug: 1110522
Change-Id: Ifa8e9e7b43c52d611d0c77b134f5cb0ab3b86357
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2340291
Commit-Queue: Kurt Catti-Schmidt <kschmi@microsoft.com>
Reviewed-by: default avatarNektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#796515}
parent b6845321
...@@ -2714,6 +2714,94 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestSetSelectionRanges) { ...@@ -2714,6 +2714,94 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestSetSelectionRanges) {
ranges = nullptr; ranges = nullptr;
} }
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
TestSetSelectionRangesIFrame) {
AccessibilityNotificationWaiter waiter(shell()->web_contents(),
ui::kAXModeComplete,
ax::mojom::Event::kLoadComplete);
GURL url(
"data:text/html,"
"<!doctype html><html><body>"
"Text before iframe"
"<iframe src='data:text/html,"
"<!doctype html><html><body>"
"<button>Text in iframe</button></body></html>"
"'></iframe>"
"<button>Text after iframe</button>"
"</body></html>");
ASSERT_TRUE(NavigateToURL(shell(), url));
waiter.WaitForNotification();
WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
"Text in iframe");
Microsoft::WRL::ComPtr<IAccessible> document(GetRendererAccessible());
std::vector<base::win::ScopedVariant> document_children =
GetAllAccessibleChildren(document.Get());
ASSERT_EQ(1u, document_children.size());
Microsoft::WRL::ComPtr<IAccessible2> body_iaccessible2;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(document.Get(), document_children[0].AsInput())
.Get(),
&body_iaccessible2));
std::vector<base::win::ScopedVariant> body_children =
GetAllAccessibleChildren(body_iaccessible2.Get());
ASSERT_EQ(3u, body_children.size());
Microsoft::WRL::ComPtr<IAccessible2> iframe;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(document.Get(), body_children[1].AsInput())
.Get(),
&iframe));
std::vector<base::win::ScopedVariant> iframe_children =
GetAllAccessibleChildren(iframe.Get());
ASSERT_EQ(1u, iframe_children.size());
Microsoft::WRL::ComPtr<IAccessible2> iframe_body;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(document.Get(), iframe_children[0].AsInput())
.Get(),
&iframe_body));
std::vector<base::win::ScopedVariant> iframe_body_children =
GetAllAccessibleChildren(iframe_body.Get());
ASSERT_EQ(1u, iframe_body_children.size());
Microsoft::WRL::ComPtr<IAccessible2> text_in_iframe;
ASSERT_HRESULT_SUCCEEDED(
QueryIAccessible2(GetAccessibleFromVariant(
document.Get(), iframe_body_children[0].AsInput())
.Get(),
&text_in_iframe));
Microsoft::WRL::ComPtr<IAccessible2> text_after_iframe;
ASSERT_HRESULT_SUCCEEDED(QueryIAccessible2(
GetAccessibleFromVariant(document.Get(), body_children[2].AsInput())
.Get(),
&text_after_iframe));
Microsoft::WRL::ComPtr<IAccessible2_4> text_after_iframe_iaccessible2_4;
ASSERT_HRESULT_SUCCEEDED(
text_after_iframe.As(&text_after_iframe_iaccessible2_4));
LONG n_ranges = 1;
IA2Range* ranges =
reinterpret_cast<IA2Range*>(CoTaskMemAlloc(sizeof(IA2Range)));
ranges[0].anchor = text_in_iframe.Get();
ranges[0].anchorOffset = 0;
ranges[0].active = text_after_iframe.Get();
ranges[0].activeOffset = 2;
// This is expected to fail because the anchor and focus nodes are in
// different trees, which Blink doesn't support.
EXPECT_HRESULT_FAILED(
text_after_iframe_iaccessible2_4->setSelectionRanges(n_ranges, ranges));
CoTaskMemFree(ranges);
ranges = nullptr;
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestMultiLineSetSelection) { IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestMultiLineSetSelection) {
Microsoft::WRL::ComPtr<IAccessibleText> textarea_text; Microsoft::WRL::ComPtr<IAccessibleText> textarea_text;
SetUpTextareaField(&textarea_text); SetUpTextareaField(&textarea_text);
......
...@@ -1682,6 +1682,12 @@ IFACEMETHODIMP AXPlatformNodeWin::setSelectionRanges(LONG nRanges, ...@@ -1682,6 +1682,12 @@ IFACEMETHODIMP AXPlatformNodeWin::setSelectionRanges(LONG nRanges,
if (!anchor_node || !focus_node) if (!anchor_node || !focus_node)
return E_INVALIDARG; return E_INVALIDARG;
// Blink only supports selections within a single tree.
if (anchor_node->GetDelegate()->GetTreeData().tree_id !=
focus_node->GetDelegate()->GetTreeData().tree_id) {
return E_INVALIDARG;
}
if (ranges->anchorOffset < 0 || ranges->activeOffset < 0) if (ranges->anchorOffset < 0 || ranges->activeOffset < 0)
return E_INVALIDARG; return E_INVALIDARG;
......
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