Avoid potential negative array index access to cached text.
[LibreOffice.git] / winaccessibility / source / UAccCOM / AccTableCell.cxx
blob95725c2a40429f2f5fe68c3dc74972718ad11586
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "AccTableCell.h"
21 #include "MAccessible.h"
23 #include <vcl/svapp.hxx>
24 #include <com/sun/star/accessibility/XAccessible.hpp>
26 using namespace com::sun::star::accessibility;
27 using namespace com::sun::star::uno;
29 CAccTableCell::CAccTableCell()
30 : m_nIndexInParent(0)
34 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::put_XInterface(hyper pXInterface)
36 // internal IUNOXWrapper - no mutex meeded
38 try
40 CUNOXWrapper::put_XInterface(pXInterface);
41 if (pUNOInterface == nullptr)
42 return E_INVALIDARG;
44 Reference<XAccessibleContext> xContext = pUNOInterface->getAccessibleContext();
45 if (!xContext.is())
46 return E_FAIL;
48 // retrieve reference to table (parent of the cell)
49 Reference<XAccessibleContext> xParentContext
50 = xContext->getAccessibleParent()->getAccessibleContext();
51 Reference<XAccessibleTable> xTable(xParentContext, UNO_QUERY);
53 if (!xTable.is())
55 m_xTable.clear();
56 return E_FAIL;
59 m_xTable = xTable;
60 m_nIndexInParent = xContext->getAccessibleIndexInParent();
61 return S_OK;
63 catch (...)
65 return E_FAIL;
69 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_columnExtent(long* pColumnsSpanned)
71 SolarMutexGuard g;
73 try
75 if (pColumnsSpanned == nullptr)
76 return E_INVALIDARG;
78 if (!m_xTable.is())
79 return E_FAIL;
81 long nRow = 0, nColumn = 0;
82 get_rowIndex(&nRow);
83 get_columnIndex(&nColumn);
85 *pColumnsSpanned = m_xTable->getAccessibleColumnExtentAt(nRow, nColumn);
86 return S_OK;
88 catch (...)
90 return E_FAIL;
94 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_columnHeaderCells(IUnknown*** cellAccessibles,
95 long* pColumnHeaderCellCount)
97 SolarMutexGuard g;
99 if (!cellAccessibles || !pColumnHeaderCellCount)
100 return E_INVALIDARG;
102 if (!m_xTable.is())
103 return E_FAIL;
105 Reference<XAccessibleTable> xHeaders = m_xTable->getAccessibleColumnHeaders();
106 if (!xHeaders.is())
107 return E_FAIL;
109 const sal_Int32 nCount = xHeaders->getAccessibleRowCount();
110 *pColumnHeaderCellCount = nCount;
111 *cellAccessibles = static_cast<IUnknown**>(CoTaskMemAlloc(nCount * sizeof(IUnknown*)));
112 sal_Int32 nCol = 0;
113 get_columnIndex(&nCol);
114 for (sal_Int32 nRow = 0; nRow < nCount; nRow++)
116 Reference<XAccessible> xCell = xHeaders->getAccessibleCellAt(nRow, nCol);
117 assert(xCell.is());
119 IAccessible* pIAccessible = CMAccessible::get_IAccessibleFromXAccessible(xCell.get());
120 if (!pIAccessible)
122 Reference<XAccessible> xTableAcc(m_xTable, UNO_QUERY);
123 CMAccessible::g_pAccObjectManager->InsertAccObj(xCell.get(), xTableAcc.get());
124 pIAccessible = CMAccessible::get_IAccessibleFromXAccessible(xCell.get());
126 assert(pIAccessible && "Couldn't retrieve IAccessible object for cell.");
128 pIAccessible->AddRef();
129 (*cellAccessibles)[nRow] = pIAccessible;
131 return S_OK;
134 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_columnIndex(long* pColumnIndex)
136 SolarMutexGuard g;
140 if (pColumnIndex == nullptr)
141 return E_INVALIDARG;
143 if (!m_xTable.is())
144 return E_FAIL;
146 *pColumnIndex = m_xTable->getAccessibleColumn(m_nIndexInParent);
147 return S_OK;
149 catch (...)
151 return E_FAIL;
155 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_rowExtent(long* pRowsSpanned)
157 SolarMutexGuard g;
161 if (pRowsSpanned == nullptr)
162 return E_INVALIDARG;
164 if (!m_xTable.is())
165 return E_FAIL;
167 long nRow = 0, nColumn = 0;
168 get_rowIndex(&nRow);
169 get_columnIndex(&nColumn);
171 *pRowsSpanned = m_xTable->getAccessibleRowExtentAt(nRow, nColumn);
173 return S_OK;
175 catch (...)
177 return E_FAIL;
181 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_rowHeaderCells(IUnknown*** cellAccessibles,
182 long* pRowHeaderCellCount)
184 SolarMutexGuard g;
186 if (!cellAccessibles || !pRowHeaderCellCount)
187 return E_INVALIDARG;
189 if (!m_xTable.is())
190 return E_FAIL;
192 Reference<XAccessibleTable> xHeaders = m_xTable->getAccessibleRowHeaders();
193 if (!xHeaders.is())
194 return E_FAIL;
196 const sal_Int32 nCount = xHeaders->getAccessibleColumnCount();
197 *pRowHeaderCellCount = nCount;
198 *cellAccessibles = static_cast<IUnknown**>(CoTaskMemAlloc(nCount * sizeof(IUnknown*)));
199 sal_Int32 nRow = 0;
200 get_rowIndex(&nRow);
201 for (sal_Int32 nCol = 0; nCol < nCount; nCol++)
203 Reference<XAccessible> xCell = xHeaders->getAccessibleCellAt(nRow, nCol);
204 assert(xCell.is());
206 IAccessible* pIAccessible = CMAccessible::get_IAccessibleFromXAccessible(xCell.get());
207 if (!pIAccessible)
209 Reference<XAccessible> xTableAcc(m_xTable, UNO_QUERY);
210 CMAccessible::g_pAccObjectManager->InsertAccObj(xCell.get(), xTableAcc.get());
211 pIAccessible = CMAccessible::get_IAccessibleFromXAccessible(xCell.get());
213 assert(pIAccessible && "Couldn't retrieve IAccessible object for cell.");
215 pIAccessible->AddRef();
216 (*cellAccessibles)[nCol] = pIAccessible;
218 return S_OK;
221 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_rowIndex(long* pRowIndex)
223 SolarMutexGuard g;
227 if (pRowIndex == nullptr)
228 return E_INVALIDARG;
230 if (!m_xTable.is())
231 return E_FAIL;
233 *pRowIndex = m_xTable->getAccessibleRow(m_nIndexInParent);
234 return S_OK;
236 catch (...)
238 return E_FAIL;
242 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_isSelected(boolean* pIsSelected)
244 SolarMutexGuard g;
248 if (pIsSelected == nullptr)
249 return E_INVALIDARG;
251 if (!m_xTable.is())
252 return E_FAIL;
254 long nRow = 0, nColumn = 0;
255 get_rowIndex(&nRow);
256 get_columnIndex(&nColumn);
258 *pIsSelected = m_xTable->isAccessibleSelected(nRow, nColumn);
259 return S_OK;
261 catch (...)
263 return E_FAIL;
267 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_rowColumnExtents(long* pRow, long* pColumn,
268 long* pRowExtents,
269 long* pColumnExtents,
270 boolean* pIsSelected)
272 SolarMutexGuard g;
274 if (!pRow || !pColumn || !pRowExtents || !pColumnExtents || !pIsSelected)
275 return E_INVALIDARG;
277 if (get_rowIndex(pRow) != S_OK)
278 return E_FAIL;
279 if (get_columnIndex(pColumn) != S_OK)
280 return E_FAIL;
281 if (get_rowExtent(pRowExtents) != S_OK)
282 return E_FAIL;
283 if (get_columnExtent(pColumnExtents) != S_OK)
284 return E_FAIL;
285 if (get_isSelected(pIsSelected) != S_OK)
286 return E_FAIL;
287 return S_OK;
290 COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_table(IUnknown** ppTable)
292 if (!ppTable)
293 return E_INVALIDARG;
295 if (!m_xTable.is())
296 return E_FAIL;
298 Reference<XAccessible> xAcc(m_xTable, UNO_QUERY);
299 if (!xAcc.is())
300 return E_FAIL;
302 IAccessible* pRet = CMAccessible::get_IAccessibleFromXAccessible(xAcc.get());
303 if (!pRet)
304 return E_FAIL;
306 *ppTable = pRet;
307 pRet->AddRef();
308 return S_OK;
311 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */