wina11y: Fix handling for special text offset -1

As described in the IAccessible2 spec [1], -1 can be used as a
special text offset:

> Using IA2_TEXT_OFFSET_LENGTH (-1) as an offset in any of the
> IAccessibleText or IAccessibleEditableText methods is the same
> as specifying the length of the string.

Replace -1 by the text length *before* doing the
check whether end offset is smaller than the start offset.

Otherwise, trying to query the whole text of a Writer paragraph
containing the text "hello" in NVDA's Python console would
incorrectly trigger an error:

    >>> focus.IAccessibleTextObject.text(0,-1)
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "comtypes\__init__.pyc", line 856, in __call__
      File "monkeyPatches\comtypesMonkeyPatches.pyc", line 32, in __call__
    _ctypes.COMError: (-2147467259, 'Unspecified error', (None, None, None, 0, None))

With this commit in place, it works as expected:

    >>> focus.IAccessibleTextObject.text(0,-1)
    'hello'

[1] https://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/_general_info.html#_specialOffsets

Change-Id: I489a42270a56178cc8ee0564eec3dc82e15969c4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168853
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
(cherry picked from commit 0c7928dc10)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168885
This commit is contained in:
Michael Weghorn 2024-06-14 10:57:58 +02:00
parent 0612048edb
commit a1ad4744a1

View file

@ -438,25 +438,13 @@ COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_text(long startOffset, long
if(!pRXText.is()) if(!pRXText.is())
return E_FAIL; return E_FAIL;
if (endOffset < -1 || endOffset < startOffset ) if (endOffset == -1)
{ endOffset = pRXText->getCharacterCount();
if (endOffset < 0 || endOffset < startOffset)
return E_FAIL; return E_FAIL;
}
OUString ouStr;
if (endOffset == -1 )
{
long nLen=0;
if(SUCCEEDED(get_characterCount(&nLen)))
{
ouStr = pRXText->getTextRange(0, nLen);
}
}
else
{
ouStr = pRXText->getTextRange(startOffset, endOffset);
}
const OUString ouStr = pRXText->getTextRange(startOffset, endOffset);
SysFreeString(*text); SysFreeString(*text);
*text = SysAllocString(o3tl::toW(ouStr.getStr())); *text = SysAllocString(o3tl::toW(ouStr.getStr()));
return S_OK; return S_OK;