| | #include "unity/unity.h" |
| | #include <libxml/HTMLparser.h> |
| |
|
| | #include <stdlib.h> |
| | #include <string.h> |
| | #include <stdbool.h> |
| | #include <stdio.h> |
| |
|
| | |
| | static void assert_output_equals(const unsigned char *out, int outlen, const char *expected) { |
| | size_t exp_len = strlen(expected); |
| | TEST_ASSERT_EQUAL_INT((int)exp_len, outlen); |
| | TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, out, exp_len); |
| | } |
| |
|
| | |
| | static void assert_output_equals_either(const unsigned char *out, int outlen, |
| | const char *exp1, const char *exp2) { |
| | size_t len1 = strlen(exp1); |
| | size_t len2 = strlen(exp2); |
| | bool match1 = (outlen == (int)len1) && (memcmp(out, exp1, len1) == 0); |
| | bool match2 = (outlen == (int)len2) && (memcmp(out, exp2, len2) == 0); |
| | if (!(match1 || match2)) { |
| | |
| | char buf[64]; |
| | int n = outlen < (int)sizeof(buf) - 1 ? outlen : (int)sizeof(buf) - 1; |
| | memcpy(buf, out, n); |
| | buf[n] = '\0'; |
| | TEST_FAIL_MESSAGE("Output did not match either expected entity representation"); |
| | } |
| | } |
| |
|
| | void setUp(void) { |
| | |
| | } |
| |
|
| | void tearDown(void) { |
| | |
| | } |
| |
|
| | |
| | void test_htmlUTF8ToHtml_initialization_with_null_in(void) { |
| | unsigned char outbuf[16] = {0}; |
| | int outLen = (int)sizeof(outbuf); |
| | int inLen = 123; |
| | int ret = htmlUTF8ToHtml(outbuf, &outLen, NULL, &inLen); |
| | TEST_ASSERT_EQUAL_INT(0, ret); |
| | TEST_ASSERT_EQUAL_INT(0, outLen); |
| | TEST_ASSERT_EQUAL_INT(0, inLen); |
| | } |
| |
|
| | |
| | void test_htmlUTF8ToHtml_null_out_pointer_returns_error(void) { |
| | const unsigned char inbuf[] = { 'A' }; |
| | int outLen = 16; |
| | int inLen = (int)sizeof(inbuf); |
| | int ret = htmlUTF8ToHtml(NULL, &outLen, inbuf, &inLen); |
| | TEST_ASSERT_LESS_THAN_INT(0, ret); |
| | } |
| |
|
| | |
| | void test_htmlUTF8ToHtml_ascii_passthrough(void) { |
| | const unsigned char inbuf[] = "Hello"; |
| | unsigned char outbuf[64]; |
| | int outLen = (int)sizeof(outbuf); |
| | int inLen = (int)strlen((const char *)inbuf); |
| |
|
| | int ret = htmlUTF8ToHtml(outbuf, &outLen, inbuf, &inLen); |
| |
|
| | TEST_ASSERT_EQUAL_INT(5, ret); |
| | TEST_ASSERT_EQUAL_INT(5, outLen); |
| | TEST_ASSERT_EQUAL_INT(5, inLen); |
| |
|
| | |
| | unsigned char tmp[64]; |
| | memcpy(tmp, outbuf, outLen); |
| | tmp[outLen] = '\0'; |
| | TEST_ASSERT_EQUAL_STRING("Hello", (const char *)tmp); |
| | } |
| |
|
| | |
| | void test_htmlUTF8ToHtml_two_byte_utf8_to_entity_copy(void) { |
| | const unsigned char inbuf[] = { 0xC2, 0xA9 }; |
| | unsigned char outbuf[32] = {0}; |
| | int outLen = (int)sizeof(outbuf); |
| | int inLen = (int)sizeof(inbuf); |
| |
|
| | int ret = htmlUTF8ToHtml(outbuf, &outLen, inbuf, &inLen); |
| |
|
| | TEST_ASSERT_EQUAL_INT(outLen, ret); |
| | TEST_ASSERT_EQUAL_INT(2, inLen); |
| | |
| | assert_output_equals_either(outbuf, outLen, "©", "©"); |
| | } |
| |
|
| | |
| | void test_htmlUTF8ToHtml_mixed_ascii_and_entity(void) { |
| | const unsigned char inbuf[] = { 'A', 0xC2, 0xA9, 'B' }; |
| | unsigned char outbuf[64] = {0}; |
| | int outLen = (int)sizeof(outbuf); |
| | int inLen = (int)sizeof(inbuf); |
| |
|
| | int ret = htmlUTF8ToHtml(outbuf, &outLen, inbuf, &inLen); |
| |
|
| | TEST_ASSERT_EQUAL_INT(outLen, ret); |
| | TEST_ASSERT_EQUAL_INT(4, inLen); |
| | |
| | const char *exp1 = "A©B"; |
| | const char *exp2 = "A©B"; |
| | assert_output_equals_either(outbuf, outLen, exp1, exp2); |
| | } |
| |
|
| | |
| | void test_htmlUTF8ToHtml_four_byte_utf8_to_numeric_entity(void) { |
| | const unsigned char inbuf[] = { 0xF0, 0x9F, 0x98, 0x80 }; |
| | unsigned char outbuf[32] = {0}; |
| | int outLen = (int)sizeof(outbuf); |
| | int inLen = (int)sizeof(inbuf); |
| |
|
| | int ret = htmlUTF8ToHtml(outbuf, &outLen, inbuf, &inLen); |
| |
|
| | TEST_ASSERT_EQUAL_INT(outLen, ret); |
| | TEST_ASSERT_EQUAL_INT(4, inLen); |
| | assert_output_equals(outbuf, outLen, "😀"); |
| | } |
| |
|
| | |
| | void test_htmlUTF8ToHtml_incomplete_multibyte_sequence(void) { |
| | const unsigned char inbuf[] = { 'A', 0xC2 }; |
| | unsigned char outbuf[16] = {0}; |
| | int outLen = (int)sizeof(outbuf); |
| | int inLen = (int)sizeof(inbuf); |
| |
|
| | int ret = htmlUTF8ToHtml(outbuf, &outLen, inbuf, &inLen); |
| |
|
| | |
| | TEST_ASSERT_EQUAL_INT(1, ret); |
| | TEST_ASSERT_EQUAL_INT(1, outLen); |
| | TEST_ASSERT_EQUAL_INT(1, inLen); |
| | TEST_ASSERT_EQUAL_HEX8('A', outbuf[0]); |
| | } |
| |
|
| | |
| | void test_htmlUTF8ToHtml_outbuf_too_small_for_entity(void) { |
| | const unsigned char inbuf[] = { 0xC2, 0xA9 }; |
| | unsigned char outbuf[5] = {0}; |
| | int outLen = (int)sizeof(outbuf); |
| | int inLen = (int)sizeof(inbuf); |
| |
|
| | int ret = htmlUTF8ToHtml(outbuf, &outLen, inbuf, &inLen); |
| |
|
| | TEST_ASSERT_LESS_THAN_INT(0, ret); |
| | TEST_ASSERT_EQUAL_INT(0, outLen); |
| | TEST_ASSERT_EQUAL_INT(0, inLen); |
| | } |
| |
|
| | |
| | void test_htmlUTF8ToHtml_outbuf_too_small_mid_ascii(void) { |
| | const unsigned char inbuf[] = { 'A', 'B', 'C' }; |
| | unsigned char outbuf[2] = {0}; |
| | int outLen = (int)sizeof(outbuf); |
| | int inLen = (int)sizeof(inbuf); |
| |
|
| | int ret = htmlUTF8ToHtml(outbuf, &outLen, inbuf, &inLen); |
| |
|
| | TEST_ASSERT_LESS_THAN_INT(0, ret); |
| | TEST_ASSERT_EQUAL_INT(2, outLen); |
| | TEST_ASSERT_EQUAL_INT(2, inLen); |
| | TEST_ASSERT_EQUAL_HEX8('A', outbuf[0]); |
| | TEST_ASSERT_EQUAL_HEX8('B', outbuf[1]); |
| | } |
| |
|
| | |
| | void test_htmlUTF8ToHtml_exact_boundary_for_entity(void) { |
| | const unsigned char inbuf[] = { 0xC2, 0xA9 }; |
| | unsigned char outbuf[6] = {0}; |
| | int outLen = (int)sizeof(outbuf); |
| | int inLen = (int)sizeof(inbuf); |
| |
|
| | int ret = htmlUTF8ToHtml(outbuf, &outLen, inbuf, &inLen); |
| |
|
| | TEST_ASSERT_EQUAL_INT(6, ret); |
| | TEST_ASSERT_EQUAL_INT(6, outLen); |
| | TEST_ASSERT_EQUAL_INT(2, inLen); |
| | assert_output_equals_either(outbuf, outLen, "©", "©"); |
| | } |
| |
|
| | int main(void) { |
| | UNITY_BEGIN(); |
| | RUN_TEST(test_htmlUTF8ToHtml_initialization_with_null_in); |
| | RUN_TEST(test_htmlUTF8ToHtml_null_out_pointer_returns_error); |
| | RUN_TEST(test_htmlUTF8ToHtml_ascii_passthrough); |
| | RUN_TEST(test_htmlUTF8ToHtml_two_byte_utf8_to_entity_copy); |
| | RUN_TEST(test_htmlUTF8ToHtml_mixed_ascii_and_entity); |
| | RUN_TEST(test_htmlUTF8ToHtml_four_byte_utf8_to_numeric_entity); |
| | RUN_TEST(test_htmlUTF8ToHtml_incomplete_multibyte_sequence); |
| | RUN_TEST(test_htmlUTF8ToHtml_outbuf_too_small_for_entity); |
| | RUN_TEST(test_htmlUTF8ToHtml_outbuf_too_small_mid_ascii); |
| | RUN_TEST(test_htmlUTF8ToHtml_exact_boundary_for_entity); |
| | return UNITY_END(); |
| | } |