summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2022-08-10 08:47:07 +0200
committerMichael Weghorn <m.weghorn@posteo.de>2022-08-11 08:46:03 +0200
commit69ecff82d0e5a0592f9bf6aa4fee364ff1c9754c (patch)
tree36297087f55beafe109afef4789edb8f115a2f07 /vcl
parentf810f05e2b50068f6d14be152eb4c2ffbc1c4e5e (diff)
qt a11y: Check range for offset passed to text methods
Otherwise LO crashes when invalid offsets are passed from AT when using the qt5/qt6/kf5 VCL plugins. One scenario that resulted in a crash: * start Accerciser * start Calc * press F2 in cell A1 to enter edit mode * navigate to the "Cell A1" object representing the editable cell, then to its paragraph child in Accerciser's treeview of the LO a11y hierarchy * in Accerciser's "Interface Viewer", type Enter, then any character This would crash due to a `com::sun::star::lang::IndexOutOfBoundsException` being thrown by one of the methods of the XAccessibleText/XAccessibleEditableText interfaces. Change-Id: I1b8c6057ca1e4e4485d516418bb82cd1a6697ce1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138078 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/qt5/QtAccessibleWidget.cxx96
1 files changed, 85 insertions, 11 deletions
diff --git a/vcl/qt5/QtAccessibleWidget.cxx b/vcl/qt5/QtAccessibleWidget.cxx
index a7d0457801e6..ac60b3746803 100644
--- a/vcl/qt5/QtAccessibleWidget.cxx
+++ b/vcl/qt5/QtAccessibleWidget.cxx
@@ -844,7 +844,10 @@ QString QtAccessibleWidget::attributes(int offset, int* startOffset, int* endOff
offset = nTextLength - 1;
if (offset < 0 || offset > nTextLength)
+ {
+ SAL_WARN("vcl.qt", "QtAccessibleWidget::attributes called with invalid offset: " << offset);
return QString();
+ }
const Sequence<PropertyValue> attribs
= xText->getCharacterAttributes(offset, Sequence<OUString>());
@@ -887,6 +890,7 @@ int QtAccessibleWidget::characterCount() const
return xText->getCharacterCount();
return 0;
}
+
QRect QtAccessibleWidget::characterRect(int nOffset) const
{
Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
@@ -931,11 +935,21 @@ void QtAccessibleWidget::removeSelection(int /* selectionIndex */)
{
SAL_INFO("vcl.qt", "Unsupported QAccessibleTextInterface::removeSelection");
}
+
void QtAccessibleWidget::scrollToSubstring(int startIndex, int endIndex)
{
Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
- if (xText.is())
- xText->scrollSubstringTo(startIndex, endIndex, AccessibleScrollType_SCROLL_ANYWHERE);
+ if (!xText.is())
+ return;
+
+ sal_Int32 nTextLength = xText->getCharacterCount();
+ if (startIndex < 0 || startIndex > nTextLength || endIndex < 0 || endIndex > nTextLength)
+ {
+ SAL_WARN("vcl.qt", "QtAccessibleWidget::scrollToSubstring called with invalid offset.");
+ return;
+ }
+
+ xText->scrollSubstringTo(startIndex, endIndex, AccessibleScrollType_SCROLL_ANYWHERE);
}
void QtAccessibleWidget::selection(int selectionIndex, int* startOffset, int* endOffset) const
@@ -960,25 +974,55 @@ int QtAccessibleWidget::selectionCount() const
return 1; // Only 1 selection supported atm
return 0;
}
+
void QtAccessibleWidget::setCursorPosition(int position)
{
Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
- if (xText.is())
- xText->setCaretPosition(position);
+ if (!xText.is())
+ return;
+
+ if (position < 0 || position > xText->getCharacterCount())
+ {
+ SAL_WARN("vcl.qt",
+ "QtAccessibleWidget::setCursorPosition called with invalid offset: " << position);
+ return;
+ }
+
+ xText->setCaretPosition(position);
}
+
void QtAccessibleWidget::setSelection(int /* selectionIndex */, int startOffset, int endOffset)
{
Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
- if (xText.is())
- xText->setSelection(startOffset, endOffset);
+ if (!xText.is())
+ return;
+
+ sal_Int32 nTextLength = xText->getCharacterCount();
+ if (startOffset < 0 || startOffset > nTextLength || endOffset < 0 || endOffset > nTextLength)
+ {
+ SAL_WARN("vcl.qt", "QtAccessibleWidget::setSelection called with invalid offset.");
+ return;
+ }
+
+ xText->setSelection(startOffset, endOffset);
}
+
QString QtAccessibleWidget::text(int startOffset, int endOffset) const
{
Reference<XAccessibleText> xText(getAccessibleContextImpl(), UNO_QUERY);
- if (xText.is())
- return toQString(xText->getTextRange(startOffset, endOffset));
- return QString();
+ if (!xText.is())
+ return QString();
+
+ sal_Int32 nTextLength = xText->getCharacterCount();
+ if (startOffset < 0 || startOffset > nTextLength || endOffset < 0 || endOffset > nTextLength)
+ {
+ SAL_WARN("vcl.qt", "QtAccessibleWidget::text called with invalid offset.");
+ return QString();
+ }
+
+ return toQString(xText->getTextRange(startOffset, endOffset));
}
+
QString QtAccessibleWidget::textAfterOffset(int /* offset */,
QAccessible::TextBoundaryType /* boundaryType */,
int* /* startOffset */, int* /* endOffset */) const
@@ -993,9 +1037,9 @@ QString QtAccessibleWidget::textAtOffset(int offset, QAccessible::TextBoundaryTy
if (startOffset == nullptr || endOffset == nullptr)
return QString();
+ const int nCharCount = characterCount();
if (boundaryType == QAccessible::NoBoundary)
{
- const int nCharCount = characterCount();
*startOffset = 0;
*endOffset = nCharCount;
return text(0, nCharCount);
@@ -1010,7 +1054,14 @@ QString QtAccessibleWidget::textAtOffset(int offset, QAccessible::TextBoundaryTy
// special value of -1 for offset means text length
if (offset == -1)
- offset = xText->getCharacterCount();
+ offset = nCharCount;
+
+ if (offset < 0 || offset > nCharCount)
+ {
+ SAL_WARN("vcl.qt",
+ "QtAccessibleWidget::textAtOffset called with invalid offset: " << offset);
+ return QString();
+ }
const TextSegment segment = xText->getTextAtIndex(offset, nUnoBoundaryType);
*startOffset = segment.SegmentStart;
@@ -1037,6 +1088,14 @@ void QtAccessibleWidget::deleteText(int startOffset, int endOffset)
Reference<XAccessibleEditableText> xEditableText(xAc, UNO_QUERY);
if (!xEditableText.is())
return;
+
+ sal_Int32 nTextLength = xEditableText->getCharacterCount();
+ if (startOffset < 0 || startOffset > nTextLength || endOffset < 0 || endOffset > nTextLength)
+ {
+ SAL_WARN("vcl.qt", "QtAccessibleWidget::deleteText called with invalid offset.");
+ return;
+ }
+
xEditableText->deleteText(startOffset, endOffset);
}
@@ -1049,6 +1108,13 @@ void QtAccessibleWidget::insertText(int offset, const QString& text)
Reference<XAccessibleEditableText> xEditableText(xAc, UNO_QUERY);
if (!xEditableText.is())
return;
+
+ if (offset < 0 || offset > xEditableText->getCharacterCount())
+ {
+ SAL_WARN("vcl.qt", "QtAccessibleWidget::insertText called with invalid offset: " << offset);
+ return;
+ }
+
xEditableText->insertText(toOUString(text), offset);
}
@@ -1061,6 +1127,14 @@ void QtAccessibleWidget::replaceText(int startOffset, int endOffset, const QStri
Reference<XAccessibleEditableText> xEditableText(xAc, UNO_QUERY);
if (!xEditableText.is())
return;
+
+ sal_Int32 nTextLength = xEditableText->getCharacterCount();
+ if (startOffset < 0 || startOffset > nTextLength || endOffset < 0 || endOffset > nTextLength)
+ {
+ SAL_WARN("vcl.qt", "QtAccessibleWidget::replaceText called with invalid offset.");
+ return;
+ }
+
xEditableText->replaceText(startOffset, endOffset, toOUString(text));
}