From 0d29579baffd4f31a3ec39590117f4fee821694d Mon Sep 17 00:00:00 2001 From: sbk Date: Wed, 27 Nov 2013 01:02:55 -0800 Subject: 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 Reviewed-by: Friedemann Kleint --- src/activeqt/control/qaxserverbase.cpp | 114 +++++++++++++++++++++------------ 1 file 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 cpoints; + int current; private: CRITICAL_SECTION refCountSection; @@ -591,16 +608,16 @@ public: typedef QList::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::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::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; -- cgit v1.2.3