[qt5cpp] delete callback data allocated before signal emission (#7840)

* 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
This commit is contained in:
etherealjoy 2018-03-21 13:51:17 +01:00 committed by William Cheng
parent d1850091a7
commit 3b031ed2b8
10 changed files with 109 additions and 17 deletions

View File

@ -117,6 +117,7 @@ public class Qt5CPPGenerator extends AbstractCppCodegen implements CodegenConfig
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"));
}
@ -176,6 +177,7 @@ public class Qt5CPPGenerator extends AbstractCppCodegen implements CodegenConfig
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");

View File

@ -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

View File

@ -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

View File

@ -2,6 +2,7 @@
#include "{{classname}}.h"
#include "{{prefix}}Helpers.h"
#include "{{prefix}}ModelFactory.h"
#include "{{prefix}}QObjectWrapper.h"
#include <QJsonArray>
#include <QJsonDocument>
@ -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}}
@ -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}}

View File

@ -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;
@ -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();
};

View File

@ -13,6 +13,7 @@
#include "SWGPetApi.h"
#include "SWGHelpers.h"
#include "SWGModelFactory.h"
#include "SWGQObjectWrapper.h"
#include <QJsonArray>
#include <QJsonDocument>
@ -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) {
@ -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) {
@ -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) {
@ -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) {

View File

@ -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: apiteam@swagger.io
*
* 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

View File

@ -13,6 +13,7 @@
#include "SWGStoreApi.h"
#include "SWGHelpers.h"
#include "SWGModelFactory.h"
#include "SWGQObjectWrapper.h"
#include <QJsonArray>
#include <QJsonDocument>
@ -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());
@ -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) {
@ -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) {

View File

@ -13,6 +13,7 @@
#include "SWGUserApi.h"
#include "SWGHelpers.h"
#include "SWGModelFactory.h"
#include "SWGQObjectWrapper.h"
#include <QJsonArray>
#include <QJsonDocument>
@ -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) {
@ -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) {

View File

@ -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