Avoid potential negative array index access to cached text.
[LibreOffice.git] / winaccessibility / source / UAccCOM / EnumVariant.cxx
blob698461ac7a43e6bb2a802461b80b49a95243821b
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 "stdafx.h"
21 #include <UAccCOM.h>
22 #include "EnumVariant.h"
23 #include "MAccessible.h"
25 #include <sal/log.hxx>
26 #include <vcl/svapp.hxx>
28 using namespace com::sun::star::uno;
29 using namespace com::sun::star::accessibility;
32 // CEnumVariant
35 /**
36 * enumerate method,get next element
37 * @param cElements The number of elements to be returned.
38 * @param pvar An array of at least size celt in which the elements are to be returned.
39 * @param pcElementFetched Pointer to the number of elements returned in rgVar, or Null
40 * @return Result.
42 HRESULT STDMETHODCALLTYPE CEnumVariant::Next(ULONG cElements,VARIANT __RPC_FAR *pvar,ULONG __RPC_FAR *pcElementFetched)
44 SolarMutexGuard g;
46 ULONG l2;
48 if (pvar == nullptr)
49 return E_INVALIDARG;
51 if (pcElementFetched != nullptr)
52 *pcElementFetched = 0;
54 sal_Int64 nChildCount = m_pXAccessibleSelection->getSelectedAccessibleChildCount();
55 if (nChildCount > std::numeric_limits<long>::max())
57 SAL_WARN("iacc2", "CEnumVariant::Next: Child count exceeds maximum long value, "
58 "using max long.");
59 nChildCount = std::numeric_limits<long>::max();
62 // Retrieve the next cElements.
63 sal_Int64 l1;
64 for (l1 = m_nCurrent, l2 = 0; l1 < nChildCount && l2 < cElements; l1++, l2++)
66 Reference< XAccessible > pRXAcc = m_pXAccessibleSelection->getSelectedAccessibleChild(l1);
67 IAccessible* pChild = CMAccessible::get_IAccessibleFromXAccessible(pRXAcc.get());
68 if(pChild)
70 pvar[l2].vt = VT_DISPATCH;
71 pvar[l2].pdispVal = pChild;
72 pChild->AddRef();
74 else if(pRXAcc.is())
76 if (CMAccessible::g_pAccObjectManager)
77 CMAccessible::g_pAccObjectManager->InsertAccObj(pRXAcc.get(),pUNOInterface);
78 pChild = CMAccessible::get_IAccessibleFromXAccessible(pRXAcc.get());
79 if(pChild)
81 pvar[l2].vt = VT_DISPATCH;
82 pvar[l2].pdispVal = pChild;
83 pChild->AddRef();
87 // Set count of elements retrieved.
88 if (pcElementFetched != nullptr)
89 *pcElementFetched = l2;
90 m_nCurrent = l1;
92 return (l2 < cElements) ? S_FALSE : NOERROR;
95 /**
96 * skip the elements in the given range when enumerate elements
97 * @param cElements The number of elements to skip.
98 * @return Result.
100 HRESULT STDMETHODCALLTYPE CEnumVariant::Skip(ULONG cElements)
102 SolarMutexGuard g;
104 m_nCurrent += cElements;
105 sal_Int64 nChildCount = m_pXAccessibleSelection->getSelectedAccessibleChildCount();
106 if (nChildCount > std::numeric_limits<long>::max())
108 SAL_WARN("iacc2", "CEnumVariant::Skip: Child count exceeds maximum long value, "
109 "using max long.");
110 nChildCount = std::numeric_limits<long>::max();
112 if (m_nCurrent > nChildCount)
114 m_nCurrent = nChildCount;
115 return E_FAIL;
117 else
118 return NOERROR;
123 * reset the enumeration position to initial value
124 * @param
125 * @return Result.
127 HRESULT STDMETHODCALLTYPE CEnumVariant::Reset()
129 SolarMutexGuard g;
131 m_nCurrent = 0;
132 return NOERROR;
137 *create a new IEnumVariant object,
138 *copy current enumeration container and its state to
139 *the new object
140 *AT will use the copy object to get elements
141 * @param ppenum On return, pointer to the location of the clone enumerator
142 * @return Result.
144 HRESULT STDMETHODCALLTYPE CEnumVariant::Clone(IEnumVARIANT __RPC_FAR *__RPC_FAR *ppenum)
146 SolarMutexGuard g;
148 CEnumVariant * penum = nullptr;
149 HRESULT hr;
150 if (ppenum == nullptr)
151 return E_INVALIDARG;
153 *ppenum = nullptr;
155 hr = Create(&penum);
156 if( hr == S_OK )
158 penum->PutSelection(reinterpret_cast<hyper>(pUNOInterface));
159 *ppenum = penum;
161 else
163 if (penum)
164 penum->Release();
166 return hr;
170 *Static public method to create a CLSID_EnumVariant com object.
171 * @param ppenum Pointer to accept com object.
172 * @return Result.
174 HRESULT STDMETHODCALLTYPE CEnumVariant::Create(CEnumVariant __RPC_FAR *__RPC_FAR *ppenum)
176 SolarMutexGuard g;
178 HRESULT hr = createInstance<CEnumVariant>(IID_IEnumVariant, ppenum);
179 if (S_OK != hr)
181 return E_FAIL;
184 return S_OK;
188 *Return count of elements in current container
189 * @param.
190 * @return count of elements in current container.
192 long CEnumVariant::GetCountOfElements()
194 if(m_pXAccessibleSelection.is())
196 sal_Int64 nCount = m_pXAccessibleSelection->getSelectedAccessibleChildCount();
197 if (nCount > std::numeric_limits<long>::max())
199 SAL_WARN("iacc2", "CEnumVariant::GetCountOfElements: Count exceeds maximum long value, "
200 "using max long.");
201 nCount = std::numeric_limits<long>::max();
203 return nCount;
205 return 0;
209 * Set member m_pXAccessibleSelection to NULL and m_nCurrent to 0.
210 * @param.
211 * @return Result
213 COM_DECLSPEC_NOTHROW STDMETHODIMP CEnumVariant::ClearEnumeration()
215 // internal IEnumVariant - no mutex meeded
217 pUNOInterface = nullptr;
218 m_pXAccessibleSelection = nullptr;
219 m_nCurrent = 0;
220 return S_OK;
224 *Static method to fetch XAccessibleSelection
225 * @param pXAcc XAccessible interface.
226 * @return XAccessibleSelection interface.
228 static Reference<XAccessibleSelection> GetXAccessibleSelection(XAccessible* pXAcc)
230 if( pXAcc == nullptr)
231 return nullptr;
233 Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
234 if( !pRContext.is() )
235 return nullptr;
237 Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
238 if( !pRSelection.is() )
239 return nullptr;
241 return pRSelection;
245 * Put valid UNO XAccessible interface.
246 * @param pXSelection XAccessible interface.
247 * @return Result...
249 STDMETHODIMP CEnumVariant::PutSelection(hyper pXSelection)
251 // internal IEnumVariant - no mutex meeded
253 pUNOInterface = reinterpret_cast<XAccessible*>(pXSelection);
254 m_pXAccessibleSelection = GetXAccessibleSelection(pUNOInterface);
255 return S_OK;
258 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */