Skip to content

Commit 1b1a761

Browse files
authored
Merge pull request #90 from c-jimenez/fix/memory_leaks
[memory] Fix various memory leaks or memory access/init issues
2 parents 103b35f + 7e03023 commit 1b1a761

File tree

10 files changed

+78
-24
lines changed

10 files changed

+78
-24
lines changed

src/chargepoint/connector/Connectors.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ Connectors::Connectors(ocpp::config::IOcppConfig& ocpp_config, ocpp::database::D
3939
{
4040
}
4141

42+
/** @brief Destructor */
43+
Connectors::~Connectors()
44+
{
45+
// Clear connector array
46+
for (Connector* connector : m_connectors)
47+
{
48+
delete connector;
49+
}
50+
m_connectors.clear();
51+
}
52+
4253
/** @brief Indicate if a connector id is valid */
4354
bool Connectors::isValid(unsigned int id) const
4455
{

src/chargepoint/connector/Connectors.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ class Connectors
4343
/** @brief Constructor */
4444
Connectors(ocpp::config::IOcppConfig& ocpp_config, ocpp::database::Database& database, ocpp::helpers::ITimerPool& timer_pool);
4545

46+
/** @brief Destructor */
47+
virtual ~Connectors();
48+
4649
/**
4750
* @brief Indicate if a connector id is valid
4851
* @param id Id of the connector

src/rpc/RpcBase.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ bool RpcBase::call(const std::string& action,
8787
// Wait for response
8888
std::stringstream expected_id;
8989
expected_id << m_transaction_id;
90-
RpcMessage* rpc_message = nullptr;
90+
std::shared_ptr<RpcMessage> rpc_message;
9191
auto wait_time = std::chrono::steady_clock().now() + timeout;
9292
do
9393
{
@@ -104,12 +104,15 @@ bool RpcBase::call(const std::string& action,
104104
if (rpc_message->unique_id != expected_id.str())
105105
{
106106
// Wrong message
107-
delete rpc_message;
108-
rpc_message = nullptr;
107+
rpc_message.reset();
109108
}
110109
}
111110
}
112-
} while (ret && (rpc_message == nullptr));
111+
else
112+
{
113+
ret = false;
114+
}
115+
} while (ret && !rpc_message);
113116

114117
// Extract response
115118
if (rpc_message)
@@ -126,7 +129,7 @@ bool RpcBase::call(const std::string& action,
126129
{
127130
message = rpc_message->message.GetString();
128131
}
129-
delete rpc_message;
132+
rpc_message.reset();
130133
}
131134
else
132135
{
@@ -164,12 +167,8 @@ void RpcBase::start()
164167
// Initialize transaction id sequence
165168
m_transaction_id = std::rand();
166169

167-
// Flush queues
168-
m_requests_queue.clear();
169-
m_requests_queue.setEnable(true);
170-
m_results_queue.clear();
171-
172170
// Start reception thread
171+
m_requests_queue.setEnable(true);
173172
m_rx_thread = new std::thread(std::bind(&RpcBase::rxThread, this));
174173
}
175174
}
@@ -185,6 +184,10 @@ void RpcBase::stop()
185184
m_rx_thread->join();
186185
delete m_rx_thread;
187186
m_rx_thread = nullptr;
187+
188+
// Flush queues
189+
m_requests_queue.clear();
190+
m_results_queue.clear();
188191
}
189192
}
190193

@@ -309,7 +312,7 @@ bool RpcBase::decodeCall(const std::string& unique_id,
309312
if (action.IsString() && payload.IsObject())
310313
{
311314
// Add request to the queue
312-
RpcMessage* msg = new RpcMessage(unique_id, action.GetString(), rpc_frame, payload);
315+
auto msg = std::make_shared<RpcMessage>(unique_id, action.GetString(), rpc_frame, payload);
313316
m_requests_queue.push(msg);
314317

315318
ret = true;
@@ -327,7 +330,7 @@ bool RpcBase::decodeCallResult(const std::string& unique_id, rapidjson::Document
327330
if (payload.IsObject())
328331
{
329332
// Add result to the queue
330-
RpcMessage* msg = new RpcMessage(unique_id, rpc_frame, payload);
333+
auto msg = std::make_shared<RpcMessage>(unique_id, rpc_frame, payload);
331334
m_results_queue.push(msg);
332335

333336
ret = true;
@@ -349,7 +352,7 @@ bool RpcBase::decodeCallError(const std::string& unique_id,
349352
if (error.IsString() && message.IsString() && payload.IsObject())
350353
{
351354
// Add error to the queue
352-
RpcMessage* msg = new RpcMessage(unique_id, rpc_frame, payload, &error, &message);
355+
auto msg = std::make_shared<RpcMessage>(unique_id, rpc_frame, payload, &error, &message);
353356
m_results_queue.push(msg);
354357

355358
ret = true;
@@ -380,7 +383,7 @@ void RpcBase::sendCallError(const std::string& unique_id, const char* error, con
380383
void RpcBase::rxThread()
381384
{
382385
// Thread loop
383-
RpcMessage* rpc_message = nullptr;
386+
std::shared_ptr<RpcMessage> rpc_message;
384387
while (m_requests_queue.pop(rpc_message))
385388
{
386389
// Notify call
@@ -417,7 +420,7 @@ void RpcBase::rxThread()
417420
}
418421

419422
// Free resources
420-
delete rpc_message;
423+
rpc_message.reset();
421424
}
422425
}
423426

src/rpc/RpcBase.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ along with OpenOCPP. If not, see <http://www.gnu.org/licenses/>.
2323
#include "Queue.h"
2424

2525
#include <condition_variable>
26+
#include <memory>
2627
#include <mutex>
2728
#include <thread>
2829
#include <vector>
@@ -129,9 +130,9 @@ class RpcBase : public IRpc
129130
/** @brief Mutex for concurrent call access */
130131
std::mutex m_call_mutex;
131132
/** @brief Queue for incomming call requests */
132-
ocpp::helpers::Queue<RpcMessage*> m_requests_queue;
133+
ocpp::helpers::Queue<std::shared_ptr<RpcMessage>> m_requests_queue;
133134
/** @brief Queue for incomming call results */
134-
ocpp::helpers::Queue<RpcMessage*> m_results_queue;
135+
ocpp::helpers::Queue<std::shared_ptr<RpcMessage>> m_results_queue;
135136
/** @brief Reception thread */
136137
std::thread* m_rx_thread;
137138

src/tools/helpers/Queue.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,32 @@ class Queue
115115
return ret;
116116
}
117117

118+
/**
119+
* @brief Adds an item to the queue
120+
* @param item Item to add
121+
* @return true if the item has been added, fale if the maximum capacity has been reached
122+
*/
123+
bool push(ItemType&& item)
124+
{
125+
bool ret = false;
126+
127+
// Lock queue
128+
std::unique_lock<std::mutex> lock(m_mutex);
129+
130+
// Check size
131+
if (m_queue.size() < MAX_SIZE)
132+
{
133+
// Add item
134+
m_queue.push(item);
135+
136+
// Wakeup waiting thread
137+
m_cond_var.notify_one();
138+
ret = true;
139+
}
140+
141+
return ret;
142+
}
143+
118144
/**
119145
* @brief Get an item from the queue
120146
* @param item Item retrieved from the queue

src/tools/x509/Certificate.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ void Certificate::convertCertificateRequest(void* request, const void* issuer, v
232232
ASN1_INTEGER* serial = ASN1_INTEGER_new();
233233
ASN1_STRING_set(serial, serial_bytes, sizeof(serial_bytes));
234234
X509_set_serialNumber(cert, serial);
235+
ASN1_INTEGER_free(serial);
235236

236237
// Set subject and issuer name
237238
X509_NAME* issuer_name;
@@ -268,7 +269,7 @@ void Certificate::convertCertificateRequest(void* request, const void* issuer, v
268269
}
269270
}
270271
}
271-
sk_X509_EXTENSION_free(extensions);
272+
sk_X509_EXTENSION_pop_free(extensions, X509_EXTENSION_free);
272273
}
273274
if (issuer_cert)
274275
{
@@ -386,13 +387,15 @@ void Certificate::readInfos(Certificate& certificate)
386387
certificate.m_x509v3_extensions_names.emplace_back(OBJ_nid2ln(extension_obj_nid));
387388
if (extension_obj_nid == NID_issuer_alt_name)
388389
{
389-
certificate.m_x509v3_extensions.issuer_alternate_names =
390-
convertGeneralNames(X509_get_ext_d2i(cert, NID_issuer_alt_name, nullptr, nullptr));
390+
void* ext = X509_get_ext_d2i(cert, NID_issuer_alt_name, nullptr, nullptr);
391+
certificate.m_x509v3_extensions.issuer_alternate_names = convertGeneralNames(ext);
392+
OPENSSL_free(ext);
391393
}
392394
else if (extension_obj_nid == NID_subject_alt_name)
393395
{
394-
certificate.m_x509v3_extensions.subject_alternate_names =
395-
convertGeneralNames(X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr));
396+
void* ext = X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr);
397+
certificate.m_x509v3_extensions.subject_alternate_names = convertGeneralNames(ext);
398+
OPENSSL_free(ext);
396399
}
397400
else if (extension_obj_nid == NID_basic_constraints)
398401
{
@@ -408,6 +411,7 @@ void Certificate::readInfos(Certificate& certificate)
408411
certificate.m_x509v3_extensions.basic_constraints.path_length = ASN1_INTEGER_get(basic_constraint->pathlen);
409412
}
410413
}
414+
OPENSSL_free(basic_constraint);
411415
}
412416
}
413417
else

src/tools/x509/CertificateRequest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,14 +269,14 @@ void CertificateRequest::create(const Subject& subject, const Extensions& extens
269269
sk_GENERAL_NAME_push(names, name);
270270
}
271271
X509V3_add1_i2d(&exts, NID_subject_alt_name, names, 0, 0);
272-
sk_GENERAL_NAME_free(names);
272+
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
273273
}
274274

275275
// Add extensions to request
276276
if (exts)
277277
{
278278
X509_REQ_add_extensions(x509_req, exts);
279-
sk_X509_EXTENSION_free(exts);
279+
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
280280
}
281281

282282
// Sign request

src/websockets/libwebsockets/LibWebsocketClient.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ void LibWebsocketClient::process()
254254
}
255255

256256
// Destroy context
257+
std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Ensure disconnect caller is joining
257258
lws_context_destroy(m_context);
258259
}
259260

src/websockets/libwebsockets/LibWebsocketServer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ void LibWebsocketServer::process()
242242
}
243243

244244
// Destroy context
245+
std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Ensure stop caller is joining
245246
lws_context_destroy(m_context);
246247
}
247248

tests/chargepoint/smartcharging/test_profile_database.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,16 @@ TEST_SUITE("Profile database")
8181
ChargingProfile profile6;
8282
profile6.chargingProfileId = 6;
8383
profile6.stackLevel = 6;
84+
profile6.chargingProfileKind = ChargingProfileKindType::Absolute;
8485
profile6.chargingProfilePurpose = ChargingProfilePurposeType::TxProfile;
86+
profile6.chargingSchedule.chargingRateUnit = ChargingRateUnitType::A;
8587

8688
// Tx profiles
8789
for (size_t i = 0; i < profiles.size(); i++)
8890
{
91+
profiles[i]->chargingProfileKind = ChargingProfileKindType::Absolute;
8992
profiles[i]->chargingProfilePurpose = ChargingProfilePurposeType::TxProfile;
93+
profiles[i]->chargingSchedule.chargingRateUnit = ChargingRateUnitType::A;
9094
CHECK(profile_db.install(1u, *profiles[i]));
9195
}
9296
CHECK_FALSE(profile_db.install(1u, profile6));

0 commit comments

Comments
 (0)