diff options
author | Michael Weghorn <m.weghorn@posteo.de> | 2023-07-06 13:37:30 +0200 |
---|---|---|
committer | Michael Weghorn <m.weghorn@posteo.de> | 2023-07-08 00:12:08 +0200 |
commit | 7f7ccf955fa1138b712233628de4a73b3f845c7e (patch) | |
tree | d21c89f43873656dd237b96f0d7a3db120476f7d /sw | |
parent | 472950414a0fb07d5260b7b6b2d3a5d2dc18a68d (diff) |
tdf#155705 sw a11y: Only handle paragraph's own spell check data
When a paragraph is split across multiple pages, there
are multiple accessible paragraphs on the
accessibility layer, but there's still just a single text
node in the underlying Writer core model.
The `sw::WrongListIteratorCounter` used in
`SwTextMarkupHelper` is for the whole text node, i.e.
iterates over the spell check data from other pages
(i.e. other accessible paragraphs) as well in that case.
This caused invalid indices to be used when calculating the
index within the current accessible paragraph again when
iterating over all elements, causing a crash.
Fix this by filtering out the elements that are outside
of the accessible paragraph when handling markup information.
Change-Id: If76cc60cc9ff5614d0bcbaff196ac34ec908936e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154109
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/access/textmarkuphelper.cxx | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/sw/source/core/access/textmarkuphelper.cxx b/sw/source/core/access/textmarkuphelper.cxx index 34be72fff584..ae221f499831 100644 --- a/sw/source/core/access/textmarkuphelper.cxx +++ b/sw/source/core/access/textmarkuphelper.cxx @@ -113,8 +113,15 @@ sal_Int32 SwTextMarkupHelper::getTextMarkupCount( const sal_Int32 nTextMarkupTyp sal_Int32 nTextMarkupCount( 0 ); std::unique_ptr<sw::WrongListIteratorCounter> pIter = getIterator(nTextMarkupType); - if (pIter) - nTextMarkupCount = pIter->GetElementCount(); + // iterator may handle all items in the underlying text node in the model, which may be more + // than what is in the portion data (e.g. if a paragraph is split across multiple pages), + // only take into account those that are in the portion data + for (sal_uInt16 i = 0; i < pIter->GetElementCount(); i++) + { + std::optional<std::pair<TextFrameIndex, TextFrameIndex>> oIndices = pIter->GetElementAt(i); + if (oIndices && mrPortionData.IsValidCorePosition(oIndices->first) && mrPortionData.IsValidCorePosition(oIndices->second)) + nTextMarkupCount++; + } return nTextMarkupCount; } @@ -136,7 +143,27 @@ css::accessibility::TextSegment std::unique_ptr<sw::WrongListIteratorCounter> pIter = getIterator(nTextMarkupType); if (pIter) { - auto const oElement(pIter->GetElementAt(nTextMarkupIndex)); + std::optional<std::pair<TextFrameIndex, TextFrameIndex>> oElement; + const sal_uInt16 nIterElementCount = pIter->GetElementCount(); + sal_Int32 nIndexInPortion = 0; + sal_uInt16 nIterIndex = 0; + while (!oElement && nIterIndex < nIterElementCount) + { + // iterator may handle all items in the underlying text node in the model, which may be more + // than what is in the portion data (e.g. if a paragraph is split across multiple pages), + // only take into account those that are in the portion data + std::optional<std::pair<TextFrameIndex, TextFrameIndex>> oIndices = pIter->GetElementAt(nIterIndex); + if (oIndices && mrPortionData.IsValidCorePosition(oIndices->first) && mrPortionData.IsValidCorePosition(oIndices->second)) + { + if (nIndexInPortion == nTextMarkupIndex) + oElement = oIndices; + + nIndexInPortion++; + } + + nIterIndex++; + } + if (oElement) { const OUString& rText = mrPortionData.GetAccessibleString(); |