1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL21$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 or version 3 as published by the Free
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22** following information to ensure the GNU Lesser General Public License
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25**
26** As a special exception, The Qt Company gives you certain additional
27** rights. These rights are described in The Qt Company LGPL Exception
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29**
30** $QT_END_LICENSE$
31**
32****************************************************************************/
33
34#include "maliciousplugin_p.h"
35
36#include <QThread>
37#include <QMutex>
38#include <QSet>
39#include <QDebug>
40
41#include <QtOrganizer/qorganizeritemrequests.h>
42#include <QtOrganizer/qorganizermanager.h>
43
44#ifndef MALICIOUSPLUGINTARGET
45#define MALICIOUSPLUGINTARGET organizer_maliciousplugin
46#endif
47
48#ifndef MALICIOUSPLUGINNAME
49#define MALICIOUSPLUGINNAME maliciousplugin
50#endif
51
52#define makestr(x) (#x)
53#define makename(x) makestr(x)
54
55QTORGANIZER_USE_NAMESPACE
56
57class MaliciousThreadObject : public QObject
58{
59 Q_OBJECT
60
61public:
62 MaliciousThreadObject() {}
63
64public slots:
65 void activateRequest(QOrganizerAbstractRequest *req)
66 {
67 mutex.lock();
68 if (activeRequests.contains(value: req))
69 QOrganizerManagerEngine::updateRequestState(request: req, state: QOrganizerAbstractRequest::ActiveState);
70 mutex.unlock();
71 }
72
73 void finishRequest(QOrganizerAbstractRequest *req)
74 {
75 QOrganizerManager::Error errorResult = QOrganizerManager::NoError;
76 QMap<int, QOrganizerManager::Error> errorMap;
77 QList<QOrganizerItemId> idResult;
78 QList<QOrganizerItem> itemResult;
79 QList<QOrganizerCollection> collectionResult;
80
81 mutex.lock();
82 if (activeRequests.contains(value: req)) {
83 switch (req->type()) {
84 case QOrganizerAbstractRequest::ItemSaveRequest:
85 QOrganizerManagerEngine::updateItemSaveRequest(request: static_cast<QOrganizerItemSaveRequest *>(req), result: itemResult, error: errorResult, errorMap, newState: QOrganizerAbstractRequest::FinishedState);
86 break;
87
88 case QOrganizerAbstractRequest::ItemFetchRequest:
89 QOrganizerManagerEngine::updateItemFetchRequest(request: static_cast<QOrganizerItemFetchRequest *>(req), result: itemResult, error: errorResult, newState: QOrganizerAbstractRequest::FinishedState);
90 break;
91
92 case QOrganizerAbstractRequest::ItemIdFetchRequest:
93 QOrganizerManagerEngine::updateItemIdFetchRequest(request: static_cast<QOrganizerItemIdFetchRequest *>(req), result: idResult, error: errorResult, newState: QOrganizerAbstractRequest::FinishedState);
94 break;
95
96 case QOrganizerAbstractRequest::ItemFetchByIdRequest:
97 QOrganizerManagerEngine::updateItemFetchByIdRequest(request: static_cast<QOrganizerItemFetchByIdRequest *>(req), result: itemResult, error: errorResult, errorMap, QOrganizerAbstractRequest::FinishedState);
98 break;
99
100 case QOrganizerAbstractRequest::ItemFetchForExportRequest:
101 QOrganizerManagerEngine::updateItemFetchForExportRequest(request: static_cast<QOrganizerItemFetchForExportRequest *>(req), result: itemResult, error: errorResult, newState: QOrganizerAbstractRequest::FinishedState);
102 break;
103
104 case QOrganizerAbstractRequest::ItemOccurrenceFetchRequest:
105 QOrganizerManagerEngine::updateItemOccurrenceFetchRequest(request: static_cast<QOrganizerItemOccurrenceFetchRequest *>(req), result: itemResult, error: errorResult, newState: QOrganizerAbstractRequest::FinishedState);
106 break;
107
108 case QOrganizerAbstractRequest::ItemRemoveRequest:
109 QOrganizerManagerEngine::updateItemRemoveRequest(request: static_cast <QOrganizerItemRemoveRequest *>(req), error: errorResult, errorMap, newState: QOrganizerAbstractRequest::FinishedState);
110 break;
111
112 case QOrganizerAbstractRequest::ItemRemoveByIdRequest:
113 QOrganizerManagerEngine::updateItemRemoveByIdRequest(request: static_cast <QOrganizerItemRemoveByIdRequest *>(req), error: errorResult, errorMap, newState: QOrganizerAbstractRequest::FinishedState);
114 break;
115
116 case QOrganizerAbstractRequest::CollectionSaveRequest:
117 QOrganizerManagerEngine::updateCollectionSaveRequest(request: static_cast <QOrganizerCollectionSaveRequest *>(req), result: collectionResult, error: errorResult, errorMap, newState: QOrganizerAbstractRequest::FinishedState);
118 break;
119
120 case QOrganizerAbstractRequest::CollectionFetchRequest:
121 QOrganizerManagerEngine::updateCollectionFetchRequest(request: static_cast<QOrganizerCollectionFetchRequest *>(req), result: collectionResult, error: errorResult, newState: QOrganizerAbstractRequest::FinishedState);
122 break;
123
124 case QOrganizerAbstractRequest::CollectionRemoveRequest:
125 QOrganizerManagerEngine::updateCollectionRemoveRequest(request: static_cast<QOrganizerCollectionRemoveRequest *>(req), error: errorResult, errorMap, newState: QOrganizerAbstractRequest::FinishedState);
126 break;
127
128 default:
129 break;
130 }
131 }
132 activeRequests.remove(value: req);
133 mutex.unlock();
134 }
135
136public:
137 QMutex mutex;
138 QSet<QOrganizerAbstractRequest *> activeRequests;
139};
140
141
142class MaliciousThread : public QThread
143{
144 Q_OBJECT
145
146public:
147 MaliciousThread();
148 ~MaliciousThread();
149
150 QObject *eventLoopQuitHack;
151};
152
153MaliciousThread::MaliciousThread()
154{
155 eventLoopQuitHack = new QObject;
156 eventLoopQuitHack->moveToThread(thread: this);
157 connect(asender: eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), atype: Qt::DirectConnection);
158}
159
160MaliciousThread::~MaliciousThread()
161{
162 eventLoopQuitHack->deleteLater();
163 wait();
164}
165
166
167MaliciousAsyncManagerEngine::MaliciousAsyncManagerEngine()
168 : QOrganizerManagerEngine()
169{
170 thread = new MaliciousThread();
171 threadObject = new MaliciousThreadObject();
172 threadObject->moveToThread(thread);
173
174 connect(sender: this, SIGNAL(doStartRequest(QOrganizerAbstractRequest*)), receiver: threadObject, SLOT(activateRequest(QOrganizerAbstractRequest*)), Qt::BlockingQueuedConnection);
175 connect(sender: this, SIGNAL(doFinishRequest(QOrganizerAbstractRequest*)), receiver: threadObject, SLOT(finishRequest(QOrganizerAbstractRequest*)), Qt::BlockingQueuedConnection);
176
177 thread->start();
178}
179
180MaliciousAsyncManagerEngine::~MaliciousAsyncManagerEngine()
181{
182 delete thread;
183 delete threadObject;
184}
185
186QString MaliciousAsyncManagerEngine::managerName() const
187{
188 return QString(makename(MALICIOUSPLUGINNAME));
189}
190
191bool MaliciousAsyncManagerEngine::startRequest(QOrganizerAbstractRequest *req)
192{
193 threadObject->mutex.lock();
194 threadObject->activeRequests.insert(value: req);
195 threadObject->mutex.unlock();
196
197 // Spawn a thread to do stuff on another thread
198 emit doStartRequest(req);
199 emit doFinishRequest(req);
200
201 return true;
202}
203
204bool MaliciousAsyncManagerEngine::cancelRequest(QOrganizerAbstractRequest *req)
205{
206 updateRequestState(request: req, state: QOrganizerAbstractRequest::CanceledState);
207 QOrganizerManagerEngine::cancelRequest(request: req);
208 return true;
209}
210
211void MaliciousAsyncManagerEngine::requestDestroyed(QOrganizerAbstractRequest *req)
212{
213 threadObject->mutex.lock();
214 threadObject->activeRequests.remove(value: req);
215 threadObject->mutex.unlock();
216 QOrganizerManagerEngine::requestDestroyed(request: req);
217}
218
219
220QString MaliciousEngineFactory::managerName() const
221{
222 return QString(makename(MALICIOUSPLUGINNAME));
223}
224
225QOrganizerManagerEngine *MaliciousEngineFactory::engine(const QMap<QString, QString> &parameters, QOrganizerManager::Error *error)
226{
227 Q_UNUSED(parameters);
228 *error = QOrganizerManager::NoError;
229 return new MaliciousAsyncManagerEngine();
230}
231
232#include "maliciousplugin.moc"
233

source code of qtpim/tests/auto/organizer/qorganizeritemasync/maliciousplugin/maliciousplugin.cpp