diff --git a/src/bacnet/bacstr.c b/src/bacnet/bacstr.c index 7a45675a..5f1b69c0 100644 --- a/src/bacnet/bacstr.c +++ b/src/bacnet/bacstr.c @@ -993,7 +993,7 @@ bool octetstring_init( /** @brief Converts an null terminated ASCII Hex string to an octet string. * * @param octet_string Pointer to the octet string. - * @param ascii_hex Pointer to the HEx-ASCII string. + * @param ascii_hex Pointer to the HEX-ASCII string. * * @return true if successfully converted and fits; false if too long */ bool octetstring_init_ascii_hex( @@ -1017,6 +1017,8 @@ bool octetstring_init_ascii_hex( continue; } if (ascii_hex[index + 1] == 0) { + /* not a hex pair */ + status = false; break; } hex_pair_string[0] = ascii_hex[index]; @@ -1028,8 +1030,9 @@ bool octetstring_init_ascii_hex( /* at least one pair was decoded */ status = true; } else { - break; + /* too long */ status = false; + break; } /* set up for next pair */ index += 2; diff --git a/test/bacnet/bacstr/src/main.c b/test/bacnet/bacstr/src/main.c index a17bdb4e..8533becb 100644 --- a/test/bacnet/bacstr/src/main.c +++ b/test/bacnet/bacstr/src/main.c @@ -26,6 +26,8 @@ static void testBitString(void) BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string2; BACNET_BIT_STRING bit_string3; + bool status = false; + unsigned bits = 0; bitstring_init(&bit_string); /* verify initialization */ @@ -69,6 +71,14 @@ static void testBitString(void) zassert_false(bitstring_same(&bit_string, &bit_string2), NULL); zassert_false(bitstring_same(&bit_string, &bit_string3), NULL); } + status = bitstring_init_ascii(&bit_string, "1111000010100101"); + zassert_true(status, NULL); + status = bitstring_init_ascii(&bit_string2, "1111000010100111"); + zassert_true(status, NULL); + status = bitstring_same(&bit_string, &bit_string2); + zassert_false(status, NULL); + zassert_equal(bitstring_bits_capacity(&bit_string), + (MAX_BITSTRING_BYTES * 8), NULL); } /** @@ -126,6 +136,41 @@ static void testCharacterString(void) for (i = 0; i < test_length; i++) { zassert_equal(value[i], test_append_string[i], NULL); } + /* init from valid ASCII string */ + status = characterstring_init_ansi(&bacnet_string, value); + zassert_true(status, NULL); + /* check for valid string */ + status = characterstring_valid(&bacnet_string); + zassert_true(status, NULL); + /* check for same string */ + status = characterstring_ansi_same(&bacnet_string, value); + zassert_true(status, NULL); + /* set the encoding */ + status = characterstring_set_encoding(&bacnet_string, CHARACTER_ANSI_X34); + zassert_true(status, NULL); + /* validate that string is printable */ + status = characterstring_printable(&bacnet_string); + zassert_true(status, NULL); + /* pass NULL arguments */ + status = characterstring_init_ansi(NULL, value); + zassert_false(status, NULL); + status = characterstring_valid(NULL); + zassert_false(status, NULL); + status = characterstring_ansi_same(NULL, value); + zassert_false(status, NULL); + status = characterstring_printable(NULL); + zassert_false(status, NULL); + /* null arguments that succeed */ + status = characterstring_init_ansi(&bacnet_string, NULL); + zassert_true(status, NULL); + status = characterstring_ansi_same(&bacnet_string, NULL); + zassert_true(status, NULL); + /* alternate API for init and copy */ + status = characterstring_init_ansi_safe(&bacnet_string, value, + strlen(value)); + status = characterstring_ansi_copy(test_append_string, + sizeof(test_append_string), &bacnet_string); + zassert_equal(strncmp(value, test_append_string, strlen(value)), 0, NULL); } /** @@ -134,10 +179,16 @@ static void testCharacterString(void) static void testOctetString(void) { BACNET_OCTET_STRING bacnet_string; + BACNET_OCTET_STRING bacnet_string_twin; uint8_t *value = NULL; uint8_t test_value[MAX_APDU] = "Patricia"; + uint8_t test_value_twin[MAX_APDU] = "PATRICIA"; uint8_t test_append_value[MAX_APDU] = " and the Kids"; uint8_t test_append_string[MAX_APDU] = ""; + const char * hex_value_valid = "1234567890ABCDEF"; + const char * hex_value_skips = "12:34:56:78:90:AB:CD:EF"; + const char * hex_value_odd = "1234567890ABCDE"; + char hex_value_long[MAX_APDU+MAX_APDU] = ""; bool status = false; size_t length = 0; size_t test_length = 0; @@ -188,6 +239,56 @@ static void testOctetString(void) for (i = 0; i < test_length; i++) { zassert_equal(value[i], test_append_string[i], NULL); } + /* twins, almost */ + test_length = strlen((char *)test_value); + status = octetstring_init(&bacnet_string, &test_value[0], test_length); + zassert_true(status, NULL); + test_length = strlen((char *)test_value_twin); + status = octetstring_init(&bacnet_string_twin, &test_value_twin[0], + test_length); + zassert_true(status, NULL); + status = octetstring_value_same(&bacnet_string, &bacnet_string_twin); + zassert_false(status, NULL); + /* null argument */ + status = octetstring_value_same(NULL, &bacnet_string_twin); + zassert_false(status, NULL); + status = octetstring_value_same(&bacnet_string, NULL); + zassert_false(status, NULL); + status = octetstring_value_same(NULL, NULL); + zassert_false(status, NULL); + /* self-healing length too long */ + bacnet_string.length = MAX_OCTET_STRING_BYTES+1; + length = octetstring_length(&bacnet_string); + zassert_equal(length, MAX_OCTET_STRING_BYTES, NULL); + /* valid case - empty string */ + status = octetstring_init_ascii_hex(&bacnet_string, ""); + zassert_true(status, NULL); + /* valid case - valid hex string */ + status = octetstring_init_ascii_hex(&bacnet_string, hex_value_valid); + zassert_true(status, NULL); + test_length = strlen(hex_value_valid)/2; + length = octetstring_length(&bacnet_string); + zassert_equal(length, test_length, NULL); + /* valid case - with non-hex characters interspersed */ + status = octetstring_init_ascii_hex(&bacnet_string, hex_value_skips); + zassert_true(status, NULL); + length = octetstring_length(&bacnet_string); + zassert_equal(length, test_length, NULL); + /* invalid case - not enough pairs */ + status = octetstring_init_ascii_hex(&bacnet_string, hex_value_odd); + zassert_false(status, NULL); + /* invalid case - too long */ + memset(hex_value_long, 'F', sizeof(hex_value_long)); + hex_value_long[sizeof(hex_value_long)-1] = 0; + status = octetstring_init_ascii_hex(&bacnet_string, hex_value_long); + zassert_false(status, NULL); + /* invalid case - null arguments */ + status = octetstring_init_ascii_hex(&bacnet_string, NULL); + zassert_false(status, NULL); + status = octetstring_init_ascii_hex(NULL, hex_value_long); + zassert_false(status, NULL); + status = octetstring_init_ascii_hex(NULL, NULL); + zassert_false(status, NULL); } /** * @}