summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsbk <SergeyKorepanov@gmail.com>2013-11-27 01:02:55 -0800
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-10 06:51:32 +0100
commit0d29579baffd4f31a3ec39590117f4fee821694d (patch)
tree49367fe99649d09bba73fef6fcdb0f5faffa6ccd
parent3a4cd70e12a0607988e6f7d4f7c0c4fbcf00af86 (diff)
Fixed various crashes in connection point enumerators
Task-number: QTBUG-35136 Task-number: QTBUG-35262 Task-number: QTBUG-35263 Task-number: QTBUG-35264 Task-number: QTBUG-35265 Task-number: QTBUG-35266 Task-number: QTBUG-35267 Task-number: QTBUG-35283 Task-number: QTBUG-35284 Task-number: QTBUG-35285 Task-number: QTBUG-35286 Change-Id: Icc51137fa52dd9a10b4c3ce1ca7fe6c56d556b7a Reviewed-by: Andy Shaw <andy.shaw@digia.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
-rw-r--r--src/activeqt/control/qaxserverbase.cpp114
1 files changed, 73 insertions, 41 deletions
diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp
index 5bc61dc..ee49deb 100644
--- a/src/activeqt/control/qaxserverbase.cpp
+++ b/src/activeqt/control/qaxserverbase.cpp
@@ -485,25 +485,30 @@ class QAxSignalVec : public IEnumConnectionPoints
{
public:
QAxSignalVec(const QAxServerBase::ConnectionPoints &points)
- : cpoints(points), ref(0)
+ : cpoints(points.values())
+ , current(0)
+ , ref(0)
{
InitializeCriticalSection(&refCountSection);
- for (QAxServerBase::ConnectionPointsIterator i = cpoints.begin(); i != cpoints.end(); ++i)
- (*i)->AddRef();
+ const int count = cpoints.count();
+ for (int i = 0; i < count; ++i)
+ cpoints.at(i)->AddRef();
}
QAxSignalVec(const QAxSignalVec &old)
+ : cpoints(old.cpoints)
+ , current(old.current)
{
InitializeCriticalSection(&refCountSection);
ref = 0;
- cpoints = old.cpoints;
- for (QAxServerBase::ConnectionPointsIterator i = cpoints.begin(); i != cpoints.end(); ++i)
- (*i)->AddRef();
- it = old.it;
+ const int count = cpoints.count();
+ for (int i = 0; i < count; ++i)
+ cpoints.at(i)->AddRef();
}
~QAxSignalVec()
{
- for (QAxServerBase::ConnectionPointsIterator i = cpoints.begin(); i != cpoints.end(); ++i)
- (*i)->Release();
+ const int count = cpoints.count();
+ for (int i = 0; i < count; ++i)
+ cpoints.at(i)->Release();
DeleteCriticalSection(&refCountSection);
}
@@ -522,6 +527,8 @@ public:
}
STDMETHOD(QueryInterface)(REFIID iid, void **iface)
{
+ if (!iface)
+ return E_POINTER;
*iface = 0;
if (iid == IID_IUnknown)
*iface = this;
@@ -535,44 +542,54 @@ public:
}
STDMETHOD(Next)(ULONG cConnections, IConnectionPoint **cpoint, ULONG *pcFetched)
{
+ if (!cpoint)
+ return E_POINTER;
+
+ if (!pcFetched && cConnections > 1)
+ return E_POINTER;
+
+ const int count = cpoints.count();
unsigned long i;
for (i = 0; i < cConnections; i++) {
- if (it == cpoints.end())
+ if (current==count)
break;
- IConnectionPoint *cp = *it;
+ IConnectionPoint *cp = cpoints.at(current);
cp->AddRef();
cpoint[i] = cp;
- ++it;
+ ++current;
}
+ if (pcFetched)
*pcFetched = i;
return i == cConnections ? S_OK : S_FALSE;
}
STDMETHOD(Skip)(ULONG cConnections)
{
+ const int count = cpoints.count();
while (cConnections) {
- ++it;
+ if (current == count)
+ return S_FALSE;
+ ++current;
--cConnections;
- if (it == cpoints.end())
- return S_FALSE;
}
return S_OK;
}
STDMETHOD(Reset)()
{
- it = cpoints.begin();
-
+ current = 0;
return S_OK;
}
STDMETHOD(Clone)(IEnumConnectionPoints **ppEnum)
{
+ if (!ppEnum)
+ return E_POINTER;
*ppEnum = new QAxSignalVec(*this);
(*ppEnum)->AddRef();
return S_OK;
}
- QAxServerBase::ConnectionPoints cpoints;
- QAxServerBase::ConnectionPointsIterator it;
+ QList<IConnectionPoint*> cpoints;
+ int current;
private:
CRITICAL_SECTION refCountSection;
@@ -591,16 +608,16 @@ public:
typedef QList<CONNECTDATA>::Iterator Iterator;
QAxConnection(QAxServerBase *parent, const QUuid &uuid)
- : that(parent), iid(uuid), ref(1)
+ : that(parent), iid(uuid), current(0), ref(1)
{
InitializeCriticalSection(&refCountSection);
}
QAxConnection(const QAxConnection &old)
+ : current(old.current)
{
InitializeCriticalSection(&refCountSection);
ref = 0;
connections = old.connections;
- it = old.it;
that = old.that;
iid = old.iid;
QList<CONNECTDATA>::Iterator it = connections.begin();
@@ -629,6 +646,8 @@ public:
}
STDMETHOD(QueryInterface)(REFIID iid, void **iface)
{
+ if (!iface)
+ return E_POINTER;
*iface = 0;
if (iid == IID_IUnknown)
*iface = (IConnectionPoint*)this;
@@ -653,6 +672,9 @@ public:
}
STDMETHOD(Advise)(IUnknown*pUnk, DWORD *pdwCookie)
{
+ if (!pUnk || !pdwCookie)
+ return E_POINTER;
+
{
IDispatch *checkImpl = 0;
pUnk->QueryInterface(iid, (void**)&checkImpl);
@@ -666,26 +688,26 @@ public:
cd.pUnk = pUnk;
cd.pUnk->AddRef();
connections.append(cd);
-
*pdwCookie = cd.dwCookie;
return S_OK;
}
STDMETHOD(Unadvise)(DWORD dwCookie)
{
- QList<CONNECTDATA>::Iterator it = connections.begin();
- while (it != connections.end()) {
- CONNECTDATA cd = *it;
- if (cd.dwCookie == dwCookie) {
- cd.pUnk->Release();
- connections.erase(it);
- return S_OK;
- }
- ++it;
- }
+ const int count = connections.count();
+ for (int i = 0; i < count; ++i) {
+ if (connections.at(i).dwCookie == dwCookie) {
+ connections.removeAt(i);
+ if (current >= i && current != 0)
+ --current;
+ return S_OK;
+ }
+ }
return CONNECT_E_NOCONNECTION;
}
STDMETHOD(EnumConnections)(IEnumConnections **ppEnum)
{
+ if (!ppEnum)
+ return E_POINTER;
*ppEnum = this;
AddRef();
@@ -693,13 +715,21 @@ public:
}
STDMETHOD(Next)(ULONG cConnections, CONNECTDATA *cd, ULONG *pcFetched)
{
+ if (!cd)
+ return E_POINTER;
+
+ if (!pcFetched && cConnections > 1)
+ return E_POINTER;
+
+ const int count = connections.count();
+
unsigned long i;
for (i = 0; i < cConnections; i++) {
- if (it == connections.end())
+ if (current == count)
break;
- cd[i] = *it;
+ cd[i] = connections.at(current);
cd[i].pUnk->AddRef();
- ++it;
+ ++current;
}
if (pcFetched)
*pcFetched = i;
@@ -707,22 +737,24 @@ public:
}
STDMETHOD(Skip)(ULONG cConnections)
{
+ const int count = connections.count();
while (cConnections) {
- ++it;
+ if (current == count)
+ return S_FALSE;
+ ++current;
--cConnections;
- if (it == connections.end())
- return S_FALSE;
}
return S_OK;
}
STDMETHOD(Reset)()
{
- it = connections.begin();
-
+ current = 0;
return S_OK;
}
STDMETHOD(Clone)(IEnumConnections **ppEnum)
{
+ if (!ppEnum)
+ return E_POINTER;
*ppEnum = new QAxConnection(*this);
(*ppEnum)->AddRef();
@@ -733,7 +765,7 @@ private:
QAxServerBase *that;
QUuid iid;
Connections connections;
- Iterator it;
+ int current;
CRITICAL_SECTION refCountSection;
LONG ref;