Bugfix: Remove all memory leaks detected by a valgrind run
This commit is contained in:
parent
1c2939c7ee
commit
a644c1c4d4
7 changed files with 67 additions and 9 deletions
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
void mqtt_free(MQTTHandle *handle) {
|
void mqtt_free(MQTTHandle *handle) {
|
||||||
platform_release(handle);
|
platform_release(handle);
|
||||||
|
remove_all_subscriptions(handle);
|
||||||
free(handle);
|
free(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ static inline void parse_packet(MQTTHandle *handle, MQTTPacket *packet) {
|
||||||
if (send_puback_packet(handle, payload->packet_id)) {
|
if (send_puback_packet(handle, payload->packet_id)) {
|
||||||
dispatch_subscription(handle, payload);
|
dispatch_subscription(handle, payload);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MQTT_QOS_2:
|
case MQTT_QOS_2:
|
||||||
send_pubrec_packet(handle, payload->packet_id, dispatch_subscription_direct, payload);
|
send_pubrec_packet(handle, payload->packet_id, dispatch_subscription_direct, payload);
|
||||||
break;
|
break;
|
||||||
|
@ -155,6 +156,7 @@ PlatformTaskFunc(_reader) {
|
||||||
PlatformStatusCode ret = platform_read(handle, buffer);
|
PlatformStatusCode ret = platform_read(handle, buffer);
|
||||||
if (ret == PlatformStatusError) {
|
if (ret == PlatformStatusError) {
|
||||||
handle->reader_alive = false;
|
handle->reader_alive = false;
|
||||||
|
buffer_release(buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
33
src/packet.c
33
src/packet.c
|
@ -47,6 +47,37 @@ MQTTPacket *allocate_MQTTPacket(MQTTControlPacketType type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_MQTTPacket(MQTTPacket *packet) {
|
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);
|
free(packet->payload);
|
||||||
packet->payload = NULL;
|
packet->payload = NULL;
|
||||||
free(packet);
|
free(packet);
|
||||||
|
@ -211,7 +242,7 @@ bool decode_publish(Buffer *buffer, PublishPayload *payload, size_t sz) {
|
||||||
+ buffer->data[buffer->position + 1];
|
+ buffer->data[buffer->position + 1];
|
||||||
buffer->position += 2;
|
buffer->position += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t len = sz - (buffer->position - start_pos) + 1;
|
size_t len = sz - (buffer->position - start_pos) + 1;
|
||||||
if (len > 1) {
|
if (len > 1) {
|
||||||
payload->message = (char *)calloc(1, len);
|
payload->message = (char *)calloc(1, len);
|
||||||
|
|
|
@ -70,6 +70,7 @@ void handle_pubrel(MQTTHandle *handle, void *context) {
|
||||||
free(ctx->payload->topic);
|
free(ctx->payload->topic);
|
||||||
free(ctx->payload->message);
|
free(ctx->payload->message);
|
||||||
free(ctx->payload);
|
free(ctx->payload);
|
||||||
|
free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -213,11 +214,11 @@ bool send_disconnect_packet(MQTTHandle *handle) {
|
||||||
|
|
||||||
#if MQTT_CLIENT
|
#if MQTT_CLIENT
|
||||||
bool send_puback_packet(MQTTHandle *handle, uint16_t packet_id) {
|
bool send_puback_packet(MQTTHandle *handle, uint16_t packet_id) {
|
||||||
PacketIDPayload *payload = (PacketIDPayload *)calloc(1, sizeof(PacketIDPayload));
|
PacketIDPayload payload = { 0 };
|
||||||
payload->packet_id = packet_id;
|
payload.packet_id = packet_id;
|
||||||
|
|
||||||
DEBUG_LOG("Sending PUBACK");
|
DEBUG_LOG("Sending PUBACK");
|
||||||
Buffer *encoded = mqtt_packet_encode(&(MQTTPacket){ PacketTypePubAck, payload });
|
Buffer *encoded = mqtt_packet_encode(&(MQTTPacket){ PacketTypePubAck, &payload });
|
||||||
encoded->position = 0;
|
encoded->position = 0;
|
||||||
return send_buffer(handle, encoded);
|
return send_buffer(handle, encoded);
|
||||||
}
|
}
|
||||||
|
@ -225,8 +226,8 @@ bool send_puback_packet(MQTTHandle *handle, uint16_t packet_id) {
|
||||||
|
|
||||||
#if MQTT_CLIENT
|
#if MQTT_CLIENT
|
||||||
bool send_pubrec_packet(MQTTHandle *handle, uint16_t packet_id, MQTTPublishEventHandler callback, PublishPayload *publish) {
|
bool send_pubrec_packet(MQTTHandle *handle, uint16_t packet_id, MQTTPublishEventHandler callback, PublishPayload *publish) {
|
||||||
PacketIDPayload *payload = (PacketIDPayload *)calloc(1, sizeof(PacketIDPayload));
|
PacketIDPayload payload = { 0 };
|
||||||
payload->packet_id = packet_id;
|
payload.packet_id = packet_id;
|
||||||
|
|
||||||
PublishCallback *ctx = (PublishCallback *)malloc(sizeof(PublishCallback));
|
PublishCallback *ctx = (PublishCallback *)malloc(sizeof(PublishCallback));
|
||||||
ctx->payload = malloc(sizeof(PublishPayload));
|
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);
|
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;
|
encoded->position = 0;
|
||||||
return send_buffer(handle, encoded);
|
return send_buffer(handle, encoded);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
void subscription_set_pending(MQTTHandle *handle, char *topic, bool pending) {
|
||||||
SubscriptionItem *item = handle->subscriptions.items;
|
SubscriptionItem *item = handle->subscriptions.items;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ typedef struct {
|
||||||
|
|
||||||
void add_subscription(MQTTHandle *handle, char *topic, MQTTQosLevel qos, MQTTPublishEventHandler callback);
|
void add_subscription(MQTTHandle *handle, char *topic, MQTTQosLevel qos, MQTTPublishEventHandler callback);
|
||||||
void remove_subscription(MQTTHandle *handle, char *topic);
|
void remove_subscription(MQTTHandle *handle, char *topic);
|
||||||
|
void remove_all_subscriptions(MQTTHandle *handle);
|
||||||
void subscription_set_pending(MQTTHandle *handle, char *topic, bool pending);
|
void subscription_set_pending(MQTTHandle *handle, char *topic, bool pending);
|
||||||
|
|
||||||
void dispatch_subscription(MQTTHandle *handle, PublishPayload *payload);
|
void dispatch_subscription(MQTTHandle *handle, PublishPayload *payload);
|
||||||
|
|
|
@ -11,6 +11,7 @@ TestResult test_vl_int_data_0(void) {
|
||||||
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
||||||
uint16_t result = variable_length_int_decode(buffer);
|
uint16_t result = variable_length_int_decode(buffer);
|
||||||
TESTASSERT(result == 0, "Should decode to 0");
|
TESTASSERT(result == 0, "Should decode to 0");
|
||||||
|
buffer_release(buffer);
|
||||||
TEST_OK();
|
TEST_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ TestResult test_vl_int_data_127(void) {
|
||||||
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
||||||
uint16_t result = variable_length_int_decode(buffer);
|
uint16_t result = variable_length_int_decode(buffer);
|
||||||
TESTASSERT(result == 127, "Should decode to 127");
|
TESTASSERT(result == 127, "Should decode to 127");
|
||||||
|
buffer_release(buffer);
|
||||||
TEST_OK();
|
TEST_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +29,7 @@ TestResult test_vl_int_data_128(void) {
|
||||||
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
||||||
uint16_t result = variable_length_int_decode(buffer);
|
uint16_t result = variable_length_int_decode(buffer);
|
||||||
TESTASSERT(result == 128, "Should decode to 128");
|
TESTASSERT(result == 128, "Should decode to 128");
|
||||||
|
buffer_release(buffer);
|
||||||
TEST_OK();
|
TEST_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +38,7 @@ TestResult test_vl_int_data_16383(void) {
|
||||||
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
||||||
uint16_t result = variable_length_int_decode(buffer);
|
uint16_t result = variable_length_int_decode(buffer);
|
||||||
TESTASSERT(result == 16383, "Should decode to 16383");
|
TESTASSERT(result == 16383, "Should decode to 16383");
|
||||||
|
buffer_release(buffer);
|
||||||
TEST_OK();
|
TEST_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +47,7 @@ TestResult test_vl_int_data_16384(void) {
|
||||||
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
||||||
uint16_t result = variable_length_int_decode(buffer);
|
uint16_t result = variable_length_int_decode(buffer);
|
||||||
TESTASSERT(result == 16384, "Should decode to 16384");
|
TESTASSERT(result == 16384, "Should decode to 16384");
|
||||||
|
buffer_release(buffer);
|
||||||
TEST_OK();
|
TEST_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +56,7 @@ TestResult test_vl_int_data_32767(void) {
|
||||||
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
Buffer *buffer = buffer_from_data_copy(data, sizeof(data));
|
||||||
uint16_t result = variable_length_int_decode(buffer);
|
uint16_t result = variable_length_int_decode(buffer);
|
||||||
TESTASSERT(result == 32767, "Should decode to 32767");
|
TESTASSERT(result == 32767, "Should decode to 32767");
|
||||||
|
buffer_release(buffer);
|
||||||
TEST_OK();
|
TEST_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +68,8 @@ TestResult test_utf8_string_empty(void) {
|
||||||
char *string = utf8_string_decode(buffer);
|
char *string = utf8_string_decode(buffer);
|
||||||
|
|
||||||
TESTASSERT(strlen(string) == 0, "Should decode empty string");
|
TESTASSERT(strlen(string) == 0, "Should decode empty string");
|
||||||
|
free(string);
|
||||||
|
buffer_release(buffer);
|
||||||
TEST_OK();
|
TEST_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +80,8 @@ TestResult test_utf8_string_hello(void) {
|
||||||
char *string = utf8_string_decode(buffer);
|
char *string = utf8_string_decode(buffer);
|
||||||
|
|
||||||
TESTASSERT(strncmp("hello", string, 5) == 0, "Should decode to 'hello' string");
|
TESTASSERT(strncmp("hello", string, 5) == 0, "Should decode to 'hello' string");
|
||||||
|
free(string);
|
||||||
|
buffer_release(buffer);
|
||||||
TEST_OK();
|
TEST_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +124,6 @@ TestResult test_decode_connect_invalid(void) {
|
||||||
|
|
||||||
TESTASSERT(packet == NULL, "Packet should not be valid");
|
TESTASSERT(packet == NULL, "Packet should not be valid");
|
||||||
buffer_release(buffer);
|
buffer_release(buffer);
|
||||||
|
|
||||||
TEST_OK();
|
TEST_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@ static inline TestResult TESTMEMCMP(Buffer *valid, Buffer *check) {
|
||||||
TESTRESULT_BUFFER(TestStatusFailureHexdump, "Buffer size differs from valid", check, valid);
|
TESTRESULT_BUFFER(TestStatusFailureHexdump, "Buffer size differs from valid", check, valid);
|
||||||
}
|
}
|
||||||
if (memcmp(valid->data, check->data, valid->len) == 0) {
|
if (memcmp(valid->data, check->data, valid->len) == 0) {
|
||||||
|
buffer_release(check);
|
||||||
|
buffer_release(valid);
|
||||||
TESTRESULT(TestStatusOk, "Buffer matches valid");
|
TESTRESULT(TestStatusOk, "Buffer matches valid");
|
||||||
} else {
|
} else {
|
||||||
TESTRESULT_BUFFER(TestStatusFailureHexdump, "Buffer and valid differ", check, valid);
|
TESTRESULT_BUFFER(TestStatusFailureHexdump, "Buffer and valid differ", check, valid);
|
||||||
|
|
Loading…
Reference in a new issue