Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

coap: Fix zero-length options #648

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions coap/er-coap-13/er-coap-13.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,39 +794,35 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
goto exit_parse_error;
}

if (++current_option == data_end) {
goto exit_parse_error;
}

/* avoids code duplication without function overhead */
x = &option_delta;
do
{
if (*x==13)
{
*x += current_option[0];
if (++current_option == data_end) {
goto exit_parse_error;
}
*x += current_option[0];
}
else if (*x==14)
{
*x += 255;
*x += current_option[0]<<8;
if (++current_option == data_end) {
goto exit_parse_error;
}
*x += current_option[0];
*x += current_option[0]<<8;
if (++current_option == data_end) {
goto exit_parse_error;
}
*x += current_option[0];
}
}
while (x != &option_length && (x = &option_length));

option_number += option_delta;

if (current_option + option_length > data_end)
if (++current_option + option_length > data_end)
{
PRINTF("OPTION %u (delta %u, len %u) has invalid length.\n", option_number, option_delta, option_length);
goto exit_parse_error;
Expand All @@ -841,6 +837,9 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
switch (option_number)
{
case COAP_OPTION_CONTENT_TYPE:
if (option_length > 2) {
goto exit_parse_error;
}
coap_pkt->content_type = (coap_content_type_t) coap_parse_int_option(current_option, option_length);
PRINTF("Content-Format [%u]\n", coap_pkt->content_type);
break;
Expand Down
46 changes: 46 additions & 0 deletions tests/er_coap_coap_parse_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,49 @@ static void test_option_format_unsupported_critical(void) {
CU_ASSERT_EQUAL(coap_parse_message(&coap_pkt, data, sizeof(data)), BAD_OPTION_4_02);
}

static void test_option_format_content_format_null(void) {
uint8_t data[] = {
0x60, // version 1, no options, no tokens
0x83, // Non-empty message
0xC3, // Message ID
0xF8, // Message ID
0xC0, // Content format "text/plain; charset=utf-8"
};

CU_ASSERT_EQUAL(coap_parse_message(&coap_pkt, data, sizeof(data)), NO_ERROR);
CU_ASSERT_PTR_EQUAL(coap_pkt.content_type, 0);
}

static void test_option_format_content_format_non_null(void) {
uint8_t data[] = {
0x60, // version 1, no options, no tokens
0x83, // Non-empty message
0xC3, // Message ID
0xF8, // Message ID
0xC2, // Content format; option length is 2 byte
0xFD, // 1st byte of 0xFDE8 (experimental usage)
0xE8, // 2nd byte
};

CU_ASSERT_EQUAL(coap_parse_message(&coap_pkt, data, sizeof(data)), NO_ERROR);
CU_ASSERT_PTR_EQUAL(coap_pkt.content_type, 0xFDE8);
}

static void test_option_format_content_format_invalid(void) {
uint8_t data[] = {
0x60, // version 1, no options, no tokens
0x83, // Non-empty message
0xC3, // Message ID
0xF8, // Message ID
0xC3, // Content format; option length is 3 byte (invalid!)
0xFD, // 1st byte of 0x999999 (invalid!)
0xE8, // 2nd byte
0xE8, // 3nd byte
};

CU_ASSERT_NOT_EQUAL(coap_parse_message(&coap_pkt, data, sizeof(data)), NO_ERROR);
}

static void test_option_format_unsupported_elective(void) {
uint8_t data[] = {
0x40, // version 1, no options, no token
Expand Down Expand Up @@ -324,6 +367,9 @@ static struct TestTable table[] = {
{"Option format: If none match", test_option_format_if_none_match},
{"Option format: Unsupported, elective", test_option_format_unsupported_elective},
{"Option format: Unsupported, critical", test_option_format_unsupported_critical},
{"Option format: Content format zero", test_option_format_content_format_null},
{"Option format: Content format 2 byte size", test_option_format_content_format_non_null},
{"Option format: Content format with invalid option length", test_option_format_content_format_invalid},
{"Payload: Minimal", test_payload_min},
{"Payload: Maximal", test_payload_max},
{NULL, NULL},
Expand Down