Skip to content

Commit

Permalink
[qt5cpp] delete callback data allocated before signal emission (#7840)
Browse files Browse the repository at this point in the history
* Small fixes to prevent crash when empty json body is provided.

* Add deleteLater wrapper for pointers passed to user code to prevent memory leak.

* Updates to move Object Wrapper to separate file

* Add Prefix to class name
  • Loading branch information
etherealjoy authored and wing328 committed Mar 21, 2018
1 parent d185009 commit 3b031ed
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ public Qt5CPPGenerator() {
supportingFiles.add(new SupportingFile("HttpRequest.cpp.mustache", sourceFolder, PREFIX + "HttpRequest.cpp"));
supportingFiles.add(new SupportingFile("modelFactory.mustache", sourceFolder, PREFIX + "ModelFactory.h"));
supportingFiles.add(new SupportingFile("object.mustache", sourceFolder, PREFIX + "Object.h"));
supportingFiles.add(new SupportingFile("QObjectWrapper.h.mustache", sourceFolder, PREFIX + "QObjectWrapper.h"));
if (optionalProjectFileFlag) {
supportingFiles.add(new SupportingFile("Project.mustache", sourceFolder, "client.pri"));
}
Expand Down Expand Up @@ -176,6 +177,7 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("HttpRequest.cpp.mustache", sourceFolder, modelNamePrefix + "HttpRequest.cpp"));
supportingFiles.add(new SupportingFile("modelFactory.mustache", sourceFolder, modelNamePrefix + "ModelFactory.h"));
supportingFiles.add(new SupportingFile("object.mustache", sourceFolder, modelNamePrefix + "Object.h"));
supportingFiles.add(new SupportingFile("QObjectWrapper.h.mustache", sourceFolder, modelNamePrefix + "QObjectWrapper.h"));

typeMapping.put("object", modelNamePrefix + "Object");
typeMapping.put("file", modelNamePrefix + "HttpRequestInputFileElement");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ HEADERS += \
$${PWD}/{{prefix}}Helpers.h \
$${PWD}/{{prefix}}HttpRequest.h \
$${PWD}/{{prefix}}ModelFactory.h \
$${PWD}/{{prefix}}Object.h
$${PWD}/{{prefix}}Object.h \
$${PWD}/{{prefix}}QObjectWrapper.h

SOURCES += \
# Models
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{{>licenseInfo}}
#ifndef {{prefix}}_QOBJECT_WRAPPER_H
#define {{prefix}}_QOBJECT_WRAPPER_H

#include <QObject>

{{#cppNamespaceDeclarations}}
namespace {{this}} {
{{/cppNamespaceDeclarations}}

template <typename ObjectPtrT>
class {{prefix}}QObjectWrapper : public QObject {
public:
{{prefix}}QObjectWrapper(ObjectPtrT ptr){
data = ptr;
}
~{{prefix}}QObjectWrapper(){
delete data;
}
private :
ObjectPtrT data;
};

{{#cppNamespaceDeclarations}}
}
{{/cppNamespaceDeclarations}}

#endif // {{prefix}}_QOBJECT_WRAPPER_H
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "{{classname}}.h"
#include "{{prefix}}Helpers.h"
#include "{{prefix}}ModelFactory.h"
#include "{{prefix}}QObjectWrapper.h"

#include <QJsonArray>
#include <QJsonDocument>
Expand Down Expand Up @@ -150,20 +151,30 @@ void
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonArray jsonArray = doc.array();

auto wrapper = new {{prefix}}QObjectWrapper<{{{returnType}}}> (output);
wrapper->deleteLater();
foreach(QJsonValue obj, jsonArray) {
{{{returnBaseType}}}* o = new {{returnBaseType}}();
QJsonObject jv = obj.toObject();
QJsonObject * ptr = (QJsonObject*)&jv;
o->fromJsonObject(*ptr);
auto objwrapper = new {{prefix}}QObjectWrapper<{{{returnBaseType}}}*> (o);
objwrapper->deleteLater();
output->append(o);
}
{{/isListContainer}}

{{^isListContainer}}
{{^isMapContainer}}
{{#returnTypeIsPrimitive}}
{{{returnType}}} output; // TODO add primitive output support
{{#isByteArray}}auto wrapper = new {{prefix}}QObjectWrapper<{{{returnType}}}> (output);
wrapper->deleteLater();{{/isByteArray}}
{{#isDateTime}}auto wrapper = new {{prefix}}QObjectWrapper<{{{returnType}}}> (output);
wrapper->deleteLater();{{/isDateTime}}
{{#isDate}}auto wrapper = new {{prefix}}QObjectWrapper<{{{returnType}}}> (output);
wrapper->deleteLater();{{/isDate}}
{{#isString}}auto wrapper = new {{prefix}}QObjectWrapper<{{{returnType}}}> (output);
wrapper->deleteLater();{{/isString}}
{{/returnTypeIsPrimitive}}
{{/isMapContainer}}
{{#isMapContainer}}
Expand All @@ -183,6 +194,8 @@ void
{{^returnTypeIsPrimitive}}
QString json(worker->response);
{{{returnType}}} output = static_cast<{{{returnType}}}>(create(json, QString("{{{returnBaseType}}}")));
auto wrapper = new {{prefix}}QObjectWrapper<{{{returnType}}}> (output);
wrapper->deleteLater();
{{/returnTypeIsPrimitive}}
{{/isMapContainer}}
{{/isListContainer}}
Expand Down
4 changes: 2 additions & 2 deletions samples/client/petstore/qt5cpp/PetStore/PetApiTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ void PetApiTests::updatePetWithFormTest() {
static SWGPetApi* api = getApi();

SWGPet* pet = createRandomPet();
static SWGPet* petToCheck;
SWGPet* petToCheck;
qint64 id = pet->getId();
static QEventLoop loop;
QTimer timer;
Expand All @@ -209,7 +209,7 @@ void PetApiTests::updatePetWithFormTest() {
timer.setInterval(1000);
timer.setSingleShot(true);

auto fetchPet = [](SWGPet* pet) {
auto fetchPet = [&](SWGPet* pet) {
petToCheck = pet;
loop.quit();
};
Expand Down
19 changes: 13 additions & 6 deletions samples/client/petstore/qt5cpp/client/SWGPetApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "SWGPetApi.h"
#include "SWGHelpers.h"
#include "SWGModelFactory.h"
#include "SWGQObjectWrapper.h"

#include <QJsonArray>
#include <QJsonDocument>
Expand Down Expand Up @@ -220,15 +221,17 @@ SWGPetApi::findPetsByStatusCallback(SWGHttpRequestWorker * worker) {
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonArray jsonArray = doc.array();

auto wrapper = new SWGQObjectWrapper<QList<SWGPet*>*> (output);
wrapper->deleteLater();
foreach(QJsonValue obj, jsonArray) {
SWGPet* o = new SWGPet();
QJsonObject jv = obj.toObject();
QJsonObject * ptr = (QJsonObject*)&jv;
o->fromJsonObject(*ptr);
auto objwrapper = new SWGQObjectWrapper<SWGPet*> (o);
objwrapper->deleteLater();
output->append(o);
}

worker->deleteLater();

if (worker->error_type == QNetworkReply::NoError) {
Expand Down Expand Up @@ -325,15 +328,17 @@ SWGPetApi::findPetsByTagsCallback(SWGHttpRequestWorker * worker) {
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonArray jsonArray = doc.array();

auto wrapper = new SWGQObjectWrapper<QList<SWGPet*>*> (output);
wrapper->deleteLater();
foreach(QJsonValue obj, jsonArray) {
SWGPet* o = new SWGPet();
QJsonObject jv = obj.toObject();
QJsonObject * ptr = (QJsonObject*)&jv;
o->fromJsonObject(*ptr);
auto objwrapper = new SWGQObjectWrapper<SWGPet*> (o);
objwrapper->deleteLater();
output->append(o);
}

worker->deleteLater();

if (worker->error_type == QNetworkReply::NoError) {
Expand Down Expand Up @@ -385,9 +390,10 @@ SWGPetApi::getPetByIdCallback(SWGHttpRequestWorker * worker) {
msg = "Error: " + worker->error_str;
}


QString json(worker->response);
SWGPet* output = static_cast<SWGPet*>(create(json, QString("SWGPet")));
auto wrapper = new SWGQObjectWrapper<SWGPet*> (output);
wrapper->deleteLater();
worker->deleteLater();

if (worker->error_type == QNetworkReply::NoError) {
Expand Down Expand Up @@ -554,9 +560,10 @@ SWGPetApi::uploadFileCallback(SWGHttpRequestWorker * worker) {
msg = "Error: " + worker->error_str;
}


QString json(worker->response);
SWGApiResponse* output = static_cast<SWGApiResponse*>(create(json, QString("SWGApiResponse")));
auto wrapper = new SWGQObjectWrapper<SWGApiResponse*> (output);
wrapper->deleteLater();
worker->deleteLater();

if (worker->error_type == QNetworkReply::NoError) {
Expand Down
35 changes: 35 additions & 0 deletions samples/client/petstore/qt5cpp/client/SWGQObjectWrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: [email protected]
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/

#ifndef SWG_QOBJECT_WRAPPER_H
#define SWG_QOBJECT_WRAPPER_H

#include <QObject>

namespace Swagger {

template <typename ObjectPtrT>
class SWGQObjectWrapper : public QObject {
public:
SWGQObjectWrapper(ObjectPtrT ptr){
data = ptr;
}
~SWGQObjectWrapper(){
delete data;
}
private :
ObjectPtrT data;
};

}

#endif // SWG_QOBJECT_WRAPPER_H
8 changes: 5 additions & 3 deletions samples/client/petstore/qt5cpp/client/SWGStoreApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "SWGStoreApi.h"
#include "SWGHelpers.h"
#include "SWGModelFactory.h"
#include "SWGQObjectWrapper.h"

#include <QJsonArray>
#include <QJsonDocument>
Expand Down Expand Up @@ -118,7 +119,6 @@ SWGStoreApi::getInventoryCallback(SWGHttpRequestWorker * worker) {
msg = "Error: " + worker->error_str;
}


QMap<QString, qint32>* output = new QMap<QString, qint32>();
QString json(worker->response);
QByteArray array (json.toStdString().c_str());
Expand Down Expand Up @@ -181,9 +181,10 @@ SWGStoreApi::getOrderByIdCallback(SWGHttpRequestWorker * worker) {
msg = "Error: " + worker->error_str;
}


QString json(worker->response);
SWGOrder* output = static_cast<SWGOrder*>(create(json, QString("SWGOrder")));
auto wrapper = new SWGQObjectWrapper<SWGOrder*> (output);
wrapper->deleteLater();
worker->deleteLater();

if (worker->error_type == QNetworkReply::NoError) {
Expand Down Expand Up @@ -236,9 +237,10 @@ SWGStoreApi::placeOrderCallback(SWGHttpRequestWorker * worker) {
msg = "Error: " + worker->error_str;
}


QString json(worker->response);
SWGOrder* output = static_cast<SWGOrder*>(create(json, QString("SWGOrder")));
auto wrapper = new SWGQObjectWrapper<SWGOrder*> (output);
wrapper->deleteLater();
worker->deleteLater();

if (worker->error_type == QNetworkReply::NoError) {
Expand Down
7 changes: 5 additions & 2 deletions samples/client/petstore/qt5cpp/client/SWGUserApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "SWGUserApi.h"
#include "SWGHelpers.h"
#include "SWGModelFactory.h"
#include "SWGQObjectWrapper.h"

#include <QJsonArray>
#include <QJsonDocument>
Expand Down Expand Up @@ -284,9 +285,10 @@ SWGUserApi::getUserByNameCallback(SWGHttpRequestWorker * worker) {
msg = "Error: " + worker->error_str;
}


QString json(worker->response);
SWGUser* output = static_cast<SWGUser*>(create(json, QString("SWGUser")));
auto wrapper = new SWGQObjectWrapper<SWGUser*> (output);
wrapper->deleteLater();
worker->deleteLater();

if (worker->error_type == QNetworkReply::NoError) {
Expand Down Expand Up @@ -352,9 +354,10 @@ SWGUserApi::loginUserCallback(SWGHttpRequestWorker * worker) {
msg = "Error: " + worker->error_str;
}


QString json(worker->response);
QString* output = static_cast<QString*>(create(json, QString("QString")));
auto wrapper = new SWGQObjectWrapper<QString*> (output);
wrapper->deleteLater();
worker->deleteLater();

if (worker->error_type == QNetworkReply::NoError) {
Expand Down
3 changes: 2 additions & 1 deletion samples/client/petstore/qt5cpp/client/client.pri
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ HEADERS += \
$${PWD}/SWGHelpers.h \
$${PWD}/SWGHttpRequest.h \
$${PWD}/SWGModelFactory.h \
$${PWD}/SWGObject.h
$${PWD}/SWGObject.h \
$${PWD}/SWGQObjectWrapper.h

SOURCES += \
# Models
Expand Down

0 comments on commit 3b031ed

Please sign in to comment.