AccessibleHandler: IAccessible::get_accSelection fails with 0x800706f7: The stub received bad data.

RESOLVED FIXED in Firefox 66

Status

()

enhancement
P2
normal
RESOLVED FIXED
5 months ago
4 months ago

People

(Reporter: Jamie, Assigned: Jamie)

Tracking

unspecified
mozilla66
All
Windows
Points:
---

Firefox Tracking Flags

(firefox66 fixed)

Details

Attachments

(2 attachments)

Assignee

Description

5 months ago
Calling IAccessible::get_accSelection in-process with AccessibleHandler enabled returns 0x800706f7 (The stub received bad data). I have no idea why yet. With the handler disabled, it behaves as expected; i.e. it returns a VT_UNKNOWN which can be QIed to IEnumVARIANT. This is breaking new functionality for NVDA (not yet landed) which renders the selected item in browse mode for list boxes and trees.
Is this broken for listboxes *and* trees? I se in AccessibleWrap::get_accSelection that we have a special case for selects (which in this case means select @size>1), but not for trees.
Assignee

Comment 2

5 months ago
I tested and it's broken for both. However, that isn't actually a special case. IsSelect() will return true for trees as well because ARIAMap specifies the eSelect type for role tree (and IsSelect calls HasGenericType, which also checks ARIAMap).
Assignee

Comment 3

5 months ago
Test cases:

HTML select, selected item should be "b":
data:text/html,<select size="2"><option>a</option><option selected>b</option></select>

ARIA tree, selected item should be "b":
data:text/html,<div role="tree"><div role="treeitem">a</div><div role="treeitem" aria-selected="true" tabindex="0">b</div></div>
Assignee

Comment 4

5 months ago
Aaron, do you have any idea why VT_UNKNOWN in a VARIANT out param breaks when the handler is in play? A generic IUnknown really should work. Even so, I changed a11y::HandlerProvider::GetEffectiveOutParamIid to return IID_IEnumVARIANT for IAccessible::get_accSelection (and verified that it hits that code path), but I still get this error. If I change the calling code to return  a single accessible as a VT_DISPATCH instead (just a test; that isn't practical for multiple selection), everything behaves as it should. If I return a single accessible with VT_UNKNOWN, it breaks. The fact that this only breaks with the handler suggests this is not MainThreadHandoff, but something specific to the HandlerProvider stuff. I can't fathom it beyond that, though, as the HandlerProvider shouldn't try to do anything unless the iid is IDispatch or IAccessible*.
Flags: needinfo?(aklotz)
Assignee

Comment 5

4 months ago
We only use the handler for specific interfaces such as IAccessible* and IAccessibleHyperlink.
For interfaces which don't use the handler, we currently write an empty payload, but this still adds bytes to the stream.
This seems to break marshaling such an interface in a VT_UNKNOWN in a VARIANT.
To fix this, just don't write any payload at all when we aren't using the handler for the target interface.
Assignee

Comment 6

4 months ago
Our accSelection implementation always returns an IUnknown which clients QI to IEnumVARIANT.
Marshaling as IUnknown works fine in this case, but it's more efficient and correct to marshal the correct interface.
Also, without this, we'd hit an assertion.

Depends on D16662
Assignee

Comment 7

4 months ago

Figured it out.

Flags: needinfo?(aklotz)

Comment 8

4 months ago
Pushed by mzehe@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/bdc982dd7830
part 1: A11y HandlerProvider: Don't write any payload at all (even an empty one) if the handler isn't used for the target interface. r=aklotz
https://hg.mozilla.org/integration/autoland/rev/ce47b0935c9f
part 2: Marshal the result from IAccessible::get_accSelection as IEnumVARIANT. r=MarcoZ

Comment 9

4 months ago
bugherder
Status: NEW → RESOLVED
Last Resolved: 4 months ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla66
Assignee: nobody → jteh
You need to log in before you can comment on or make changes to this bug.