Bugfix: Remove all memory leaks detected by a valgrind run

This commit is contained in:
Johannes Schriewer 2018-10-04 02:42:33 +02:00
parent 1c2939c7ee
commit a644c1c4d4
7 changed files with 67 additions and 9 deletions

View file

@ -13,6 +13,7 @@
void mqtt_free(MQTTHandle *handle) {
platform_release(handle);
remove_all_subscriptions(handle);
free(handle);
}
@ -109,7 +110,7 @@ static inline void parse_packet(MQTTHandle *handle, MQTTPacket *packet) {
if (send_puback_packet(handle, payload->packet_id)) {
dispatch_subscription(handle, payload);
}
break;
break;
case MQTT_QOS_2:
send_pubrec_packet(handle, payload->packet_id, dispatch_subscription_direct, payload);
break;
@ -155,6 +156,7 @@ PlatformTaskFunc(_reader) {
PlatformStatusCode ret = platform_read(handle, buffer);
if (ret == PlatformStatusError) {
handle->reader_alive = false;
buffer_release(buffer);
return 0;
}

View file

@ -47,6 +47,37 @@ MQTTPacket *allocate_MQTTPacket(MQTTControlPacketType type) {
}
void free_MQTTPacket(MQTTPacket *packet) {
switch (packet->packet_type) {
case PacketTypePublish: {
PublishPayload *content = (PublishPayload *)packet->payload;
if (content->topic) free(content->topic);
if (content->message) free(content->message);
break;
}
#if MQTT_SERVER
case PacketTypeConnect: {
ConnectPayload *content = (ConnectPayload *)packet->payload;
if (content->client_id) free(content->client_id);
if (content->will_topic) free(content->will_topic);
if (content->will_message) free(content->will_message);
if (content->username) free(content->username);
if (content->password) free(content->password);
break;
}
case PacketTypeSubscribe: {
SubscribePayload *content = (SubscribePayload *)packet->payload;
if (content->topic) free(content->topic);
break;
}
case PacketTypeUnsubscribe: {
UnsubscribePayload *content = (UnsubscribePayload *)packet->payload;
if (content->topic) free(content->topic);
break;
}
#endif
default:
break;
}
free(packet->payload);
packet->payload = NULL;
free(packet);
@ -211,7 +242,7 @@ bool decode_publish(Buffer *buffer, PublishPayload *payload, size_t sz) {
+ buffer->data[buffer->position + 1];
buffer->position += 2;
}
size_t len = sz - (buffer->position - start_pos) + 1;
if (len > 1) {
payload->message = (char *)calloc(1, len);

View file

@ -70,6 +70,7 @@ void handle_pubrel(MQTTHandle *handle, void *context) {
free(ctx->payload->topic);
free(ctx->payload->message);
free(ctx->payload);
free(ctx);
}
/*
@ -213,11 +214,11 @@ bool send_disconnect_packet(MQTTHandle *handle) {
#if MQTT_CLIENT
bool send_puback_packet(MQTTHandle *handle, uint16_t packet_id) {
PacketIDPayload *payload = (PacketIDPayload *)calloc(1, sizeof(PacketIDPayload));
payload->packet_id = packet_id;
PacketIDPayload payload = { 0 };
payload.packet_id = packet_id;
DEBUG_LOG("Sending PUBACK");
Buffer *encoded = mqtt_packet_encode(&(MQTTPacket){ PacketTypePubAck, payload });
Buffer *encoded = mqtt_packet_encode(&(MQTTPacket){ PacketTypePubAck, &payload });
encoded->position = 0;
return send_buffer(handle, encoded);
}
@ -225,8 +226,8 @@ bool send_puback_packet(MQTTHandle *handle, uint16_t packet_id) {
#if MQTT_CLIENT
bool send_pubrec_packet(MQTTHandle *handle, uint16_t packet_id, MQTTPublishEventHandler callback, PublishPayload *publish) {
PacketIDPayload *payload = (PacketIDPayload *)calloc(1, sizeof(PacketIDPayload));
payload->packet_id = packet_id;
PacketIDPayload payload = { 0 };
payload.packet_id = packet_id;
PublishCallback *ctx = (PublishCallback *)malloc(sizeof(PublishCallback));
ctx->payload = malloc(sizeof(PublishPayload));
@ -238,7 +239,7 @@ bool send_pubrec_packet(MQTTHandle *handle, uint16_t packet_id, MQTTPublishEvent
expect_packet(handle, PacketTypePubRel, packet_id, handle_pubrel, ctx);
Buffer *encoded = mqtt_packet_encode(&(MQTTPacket){ PacketTypePubRec, payload });
Buffer *encoded = mqtt_packet_encode(&(MQTTPacket){ PacketTypePubRec, &payload });
encoded->position = 0;
return send_buffer(handle, encoded);
}

View file

@ -38,6 +38,18 @@ void remove_subscription(MQTTHandle *handle, char *topic) {
}
}
void remove_all_subscriptions(MQTTHandle *handle) {
SubscriptionItem *item = handle->subscriptions.items;
SubscriptionItem *prev = NULL;
while (item != NULL) {
prev = item;
item = item->next;
free(prev);
}
handle->subscriptions.items = NULL;
}
void subscription_set_pending(MQTTHandle *handle, char *topic, bool pending) {
SubscriptionItem *item = handle->subscriptions.items;

View file

@ -18,6 +18,7 @@ typedef struct {
void add_subscription(MQTTHandle *handle, char *topic, MQTTQosLevel qos, MQTTPublishEventHandler callback);
void remove_subscription(MQTTHandle *handle, char *topic);
void remove_all_subscriptions(MQTTHandle *handle);
void subscription_set_pending(MQTTHandle *handle, char *topic, bool pending);
void dispatch_subscription(MQTTHandle *handle, PublishPayload *payload);

View file

@ -11,6 +11,7 @@ TestResult test_vl_int_data_0(void) {
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
uint16_t result = variable_length_int_decode(buffer);
TESTASSERT(result == 0, "Should decode to 0");
buffer_release(buffer);
TEST_OK();
}
@ -19,6 +20,7 @@ TestResult test_vl_int_data_127(void) {
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
uint16_t result = variable_length_int_decode(buffer);
TESTASSERT(result == 127, "Should decode to 127");
buffer_release(buffer);
TEST_OK();
}
@ -27,6 +29,7 @@ TestResult test_vl_int_data_128(void) {
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
uint16_t result = variable_length_int_decode(buffer);
TESTASSERT(result == 128, "Should decode to 128");
buffer_release(buffer);
TEST_OK();
}
@ -35,6 +38,7 @@ TestResult test_vl_int_data_16383(void) {
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
uint16_t result = variable_length_int_decode(buffer);
TESTASSERT(result == 16383, "Should decode to 16383");
buffer_release(buffer);
TEST_OK();
}
@ -43,6 +47,7 @@ TestResult test_vl_int_data_16384(void) {
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
uint16_t result = variable_length_int_decode(buffer);
TESTASSERT(result == 16384, "Should decode to 16384");
buffer_release(buffer);
TEST_OK();
}
@ -51,6 +56,7 @@ TestResult test_vl_int_data_32767(void) {
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
uint16_t result = variable_length_int_decode(buffer);
TESTASSERT(result == 32767, "Should decode to 32767");
buffer_release(buffer);
TEST_OK();
}
@ -62,6 +68,8 @@ TestResult test_utf8_string_empty(void) {
char *string = utf8_string_decode(buffer);
TESTASSERT(strlen(string) == 0, "Should decode empty string");
free(string);
buffer_release(buffer);
TEST_OK();
}
@ -72,6 +80,8 @@ TestResult test_utf8_string_hello(void) {
char *string = utf8_string_decode(buffer);
TESTASSERT(strncmp("hello", string, 5) == 0, "Should decode to 'hello' string");
free(string);
buffer_release(buffer);
TEST_OK();
}
@ -114,7 +124,6 @@ TestResult test_decode_connect_invalid(void) {
TESTASSERT(packet == NULL, "Packet should not be valid");
buffer_release(buffer);
TEST_OK();
}

View file

@ -51,6 +51,8 @@ static inline TestResult TESTMEMCMP(Buffer *valid, Buffer *check) {
TESTRESULT_BUFFER(TestStatusFailureHexdump, "Buffer size differs from valid", check, valid);
}
if (memcmp(valid->data, check->data, valid->len) == 0) {
buffer_release(check);
buffer_release(valid);
TESTRESULT(TestStatusOk, "Buffer matches valid");
} else {
TESTRESULT_BUFFER(TestStatusFailureHexdump, "Buffer and valid differ", check, valid);