diff options
author | sbk <SergeyKorepanov@gmail.com> | 2013-11-27 09:02:55 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-12-19 10:55:35 (GMT) |
commit | 3bef845f4623e0edcd52ddcffee3612f4f7f6779 (patch) | |
tree | 772fde4737cba23e0e4ccfe2c2ae751c4fadde93 | |
parent | cd7aaa3820cb0b3ab777d1e8ae31379a1ef835e7 (diff) | |
download | Qt-3bef845f4623e0edcd52ddcffee3612f4f7f6779.zip Qt-3bef845f4623e0edcd52ddcffee3612f4f7f6779.tar.gz Qt-3bef845f4623e0edcd52ddcffee3612f4f7f6779.tar.bz2 |
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>
(cherry picked from qtactiveqt/0d29579baffd4f31a3ec39590117f4fee821694d)
-rw-r--r-- | src/activeqt/control/qaxserverbase.cpp | 114 |
1 files changed, 73 insertions, 41 deletions
diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp index e23dffb..2358d57 100644 --- a/src/activeqt/control/qaxserverbase.cpp +++ b/src/activeqt/control/qaxserverbase.cpp @@ -495,25 +495,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); } @@ -539,6 +544,8 @@ public: } STDMETHOD(QueryInterface)(REFIID iid, void **iface) { + if (!iface) + return E_POINTER; *iface = 0; if (iid == IID_IUnknown) *iface = this; @@ -552,44 +559,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; @@ -608,16 +625,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(); @@ -653,6 +670,8 @@ public: } STDMETHOD(QueryInterface)(REFIID iid, void **iface) { + if (!iface) + return E_POINTER; *iface = 0; if (iid == IID_IUnknown) *iface = (IConnectionPoint*)this; @@ -677,6 +696,9 @@ public: } STDMETHOD(Advise)(IUnknown*pUnk, DWORD *pdwCookie) { + if (!pUnk || !pdwCookie) + return E_POINTER; + { IDispatch *checkImpl = 0; pUnk->QueryInterface(iid, (void**)&checkImpl); @@ -690,26 +712,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(); @@ -717,13 +739,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; @@ -731,22 +761,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(); @@ -757,7 +789,7 @@ private: QAxServerBase *that; QUuid iid; Connections connections; - Iterator it; + int current; CRITICAL_SECTION refCountSection; unsigned long ref; |