From 72131c84ce0fa7f1d775c06effa18fbb9ea35ec7 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 3 Oct 2018 21:35:33 +0100 Subject: [PATCH] Binary data read functions and tests. --- lib/packet_datatypes.c | 27 +++++++++---- lib/packet_mosq.h | 1 + test/unit/Makefile | 2 +- test/unit/datatype_read.c | 82 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 8 deletions(-) diff --git a/lib/packet_datatypes.c b/lib/packet_datatypes.c index 9e31974f..1fce5950 100644 --- a/lib/packet_datatypes.c +++ b/lib/packet_datatypes.c @@ -88,7 +88,7 @@ void packet__write_bytes(struct mosquitto__packet *packet, const void *bytes, ui } -int packet__read_string(struct mosquitto__packet *packet, char **str, int *length) +int packet__read_binary(struct mosquitto__packet *packet, void **data, int *length) { uint16_t slen; int rc; @@ -99,22 +99,35 @@ int packet__read_string(struct mosquitto__packet *packet, char **str, int *lengt if(packet->pos+slen > packet->remaining_length) return MOSQ_ERR_PROTOCOL; - *str = mosquitto__malloc(slen+1); - if(*str){ - memcpy(*str, &(packet->payload[packet->pos]), slen); - (*str)[slen] = '\0'; + *data = mosquitto__malloc(slen+1); + if(*data){ + memcpy(*data, &(packet->payload[packet->pos]), slen); + ((uint8_t *)(*data))[slen] = '\0'; packet->pos += slen; }else{ return MOSQ_ERR_NOMEM; } - if(mosquitto_validate_utf8(*str, slen)){ + *length = slen; + return MOSQ_ERR_SUCCESS; +} + + +int packet__read_string(struct mosquitto__packet *packet, char **str, int *length) +{ + int rc; + int len; + + rc = packet__read_binary(packet, (void **)str, &len); + if(rc) return rc; + + if(mosquitto_validate_utf8(*str, len)){ mosquitto__free(*str); *str = NULL; return MOSQ_ERR_MALFORMED_UTF8; } - *length = slen; + *length = len; return MOSQ_ERR_SUCCESS; } diff --git a/lib/packet_mosq.h b/lib/packet_mosq.h index 5b5b5c69..567ffcec 100644 --- a/lib/packet_mosq.h +++ b/lib/packet_mosq.h @@ -29,6 +29,7 @@ int packet__queue(struct mosquitto *mosq, struct mosquitto__packet *packet); int packet__read_byte(struct mosquitto__packet *packet, uint8_t *byte); int packet__read_bytes(struct mosquitto__packet *packet, void *bytes, uint32_t count); +int packet__read_binary(struct mosquitto__packet *packet, void **data, int *length); int packet__read_string(struct mosquitto__packet *packet, char **str, int *length); int packet__read_uint16(struct mosquitto__packet *packet, uint16_t *word); int packet__read_uint32(struct mosquitto__packet *packet, uint32_t *word); diff --git a/test/unit/Makefile b/test/unit/Makefile index 3ae0c526..d67b36db 100644 --- a/test/unit/Makefile +++ b/test/unit/Makefile @@ -2,7 +2,7 @@ include ../../config.mk .PHONY: all test clean coverage -CFLAGS=-I../.. -I../../lib -coverage -Wall +CFLAGS=-I../.. -I../../lib -coverage -Wall -ggdb TEST_LDFLAGS=-lcunit -coverage all : test diff --git a/test/unit/datatype_read.c b/test/unit/datatype_read.c index 07a1128b..95654e3f 100644 --- a/test/unit/datatype_read.c +++ b/test/unit/datatype_read.c @@ -82,6 +82,34 @@ static void varint_read_helper( } +static void binary_read_helper( + uint8_t *payload, + int remaining_length, + int rc_expected, + const uint8_t *value_expected, + int length_expected) +{ + struct mosquitto__packet packet; + uint8_t *value = NULL; + int length = -1; + int rc; + + memset(&packet, 0, sizeof(struct mosquitto__packet)); + packet.payload = payload; + packet.remaining_length = remaining_length; + rc = packet__read_binary(&packet, (void **)&value, &length); + CU_ASSERT_EQUAL(rc, rc_expected); + if(value_expected){ + /* FIXME - this should be a memcmp */ + CU_ASSERT_NSTRING_EQUAL(value, value_expected, length_expected); + }else{ + CU_ASSERT_EQUAL(value, NULL); + } + CU_ASSERT_EQUAL(length, length_expected); + free(value); +} + + static void string_read_helper( uint8_t *payload, int remaining_length, @@ -628,6 +656,58 @@ static void TEST_string_read_mqtt_1_5_4_3(void) } +/* ======================================================================== + * BINARY DATA TESTS + * ======================================================================== */ + +/* This tests reading Binary Data from an incoming packet. + * + * It tests: + * * Empty packet + */ +static void TEST_binary_data_read_empty(void) +{ + binary_read_helper(NULL, 0, MOSQ_ERR_PROTOCOL, NULL, -1); +} + + +/* This tests reading Binary Data from an incoming packet. + * + * It tests: + * * Truncated packets + */ +static void TEST_binary_data_read_truncated(void) +{ + uint8_t payload[20]; + + /* 1 byte packet */ + memset(payload, 0, sizeof(payload)); + payload[0] = 0x02; + binary_read_helper(payload, 1, MOSQ_ERR_PROTOCOL, NULL, -1); + + /* 2 byte packet */ + memset(payload, 0, sizeof(payload)); + payload[0] = 0x02; + payload[1] = 0x02; + binary_read_helper(payload, 2, MOSQ_ERR_PROTOCOL, NULL, -1); + + /* 3 byte packet */ + memset(payload, 0, sizeof(payload)); + payload[0] = 0x00; + payload[1] = 0x02; + payload[2] = 'a'; + binary_read_helper(payload, 3, MOSQ_ERR_PROTOCOL, NULL, -1); + + /* 3 byte packet */ + memset(payload, 0, sizeof(payload)); + payload[0] = 0x00; + payload[1] = 0x03; + payload[2] = 'a'; + payload[3] = 'b'; + binary_read_helper(payload, 4, MOSQ_ERR_PROTOCOL, NULL, -1); +} + + /* ======================================================================== * TEST SUITE SETUP * ======================================================================== */ @@ -662,6 +742,8 @@ int init_datatype_read_tests(void) || !CU_add_test(test_suite, "UTF-8 string read (valid string)", TEST_string_read_valid_string) || !CU_add_test(test_suite, "UTF-8 string read (malformed string)", TEST_string_read_malformed_string) || !CU_add_test(test_suite, "UTF-8 string read (MQTT-1.5.4-3)", TEST_string_read_mqtt_1_5_4_3) + || !CU_add_test(test_suite, "Binary Data read (empty packet)", TEST_binary_data_read_empty) + || !CU_add_test(test_suite, "Binary Data read (truncated packet)", TEST_binary_data_read_truncated) ){ printf("Error adding datatypes CUnit tests.\n");