| #include "unity/unity.h" |
| #include <libxml/HTMLparser.h> |
| #include <libxml/dict.h> |
|
|
| #include <string.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
|
|
| |
| extern xmlHashedString test_htmlParseHTMLName(htmlParserCtxtPtr ctxt, int attr); |
|
|
| static void assert_name_parse(const unsigned char *data, size_t len, |
| int attr, |
| const char *expected_name, |
| size_t expected_advance, |
| unsigned char expected_stop) |
| { |
| htmlParserCtxtPtr ctxt = htmlCreateMemoryParserCtxt((const char *)data, (int)len); |
| TEST_ASSERT_NOT_NULL_MESSAGE(ctxt, "Failed to create HTML parser context"); |
| TEST_ASSERT_NOT_NULL_MESSAGE(ctxt->dict, "Parser context dictionary is NULL"); |
| TEST_ASSERT_NOT_NULL_MESSAGE(ctxt->input, "Parser input is NULL"); |
| TEST_ASSERT_NOT_NULL_MESSAGE(ctxt->input->base, "Parser input base is NULL"); |
|
|
| const unsigned char *start = ctxt->input->base; |
| const unsigned char *before = ctxt->input->cur; |
|
|
| xmlHashedString ret = test_htmlParseHTMLName(ctxt, attr); |
|
|
| |
| TEST_ASSERT_NOT_NULL_MESSAGE(ret.name, "Returned name is NULL (memory error?)"); |
| TEST_ASSERT_EQUAL_STRING_MESSAGE(expected_name, (const char *)ret.name, |
| "Parsed name doesn't match expected"); |
|
|
| |
| size_t advanced = (size_t)(ctxt->input->cur - start); |
| size_t expected_adv = expected_advance; |
| TEST_ASSERT_EQUAL_size_t_MESSAGE(expected_adv, advanced, "Input pointer advanced by unexpected amount"); |
|
|
| |
| if (advanced < len) { |
| TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected_stop, (unsigned char)ctxt->input->cur[0], |
| "Did not stop at expected stop character"); |
| } else { |
| |
| TEST_FAIL_MESSAGE("Input advanced to end unexpectedly; expected a stop character to remain"); |
| } |
|
|
| htmlFreeParserCtxt(ctxt); |
| } |
|
|
| |
| void setUp(void) { |
| |
| } |
| void tearDown(void) { |
| |
| } |
|
|
| |
|
|
| |
| void test_htmlParseHTMLName_ascii_tag_lowercase_stop_on_gt(void) { |
| static const unsigned char data[] = "DIV>"; |
| |
| assert_name_parse(data, sizeof(data) - 1, 0, "div", 3, '>'); |
| } |
|
|
| |
| void test_htmlParseHTMLName_attr_stop_on_equal(void) { |
| static const unsigned char data[] = "HREF=/path"; |
| |
| assert_name_parse(data, sizeof(data) - 1, 1, "href", 4, '='); |
| } |
|
|
| |
| void test_htmlParseHTMLName_stop_on_space(void) { |
| static const unsigned char data[] = "name value"; |
| |
| assert_name_parse(data, sizeof(data) - 1, 0, "name", 4, ' '); |
| } |
|
|
| |
| void test_htmlParseHTMLName_stop_on_slash(void) { |
| static const unsigned char data[] = "br/>"; |
| |
| assert_name_parse(data, sizeof(data) - 1, 0, "br", 2, '/'); |
| } |
|
|
| |
| void test_htmlParseHTMLName_valid_utf8_preserved(void) { |
| |
| static const unsigned char data[] = { 'S','t','r','a', 0xC3,0x9F, 'e', '>' }; |
| |
| static const char expected[] = { 's','t','r','a', (char)0xC3,(char)0x9F, 'e', '\0' }; |
| |
| assert_name_parse(data, sizeof(data), 0, expected, 7, '>'); |
| } |
|
|
| |
| void test_htmlParseHTMLName_invalid_utf8_replacement(void) { |
| |
| static const unsigned char data[] = { 0xC0, 0xAF, '>' }; |
| |
| static const char expected[] = { (char)0xEF,(char)0xBF,(char)0xBD, |
| (char)0xEF,(char)0xBF,(char)0xBD, '\0' }; |
| |
| assert_name_parse(data, sizeof(data), 0, expected, 2, '>'); |
| } |
|
|
| |
| void test_htmlParseHTMLName_embedded_nul_replacement(void) { |
| |
| static const unsigned char data[] = { 'a','b', 0x00, 'c','d',' ' }; |
| static const char expected[] = { 'a','b', (char)0xEF,(char)0xBF,(char)0xBD, 'c','d', '\0' }; |
| |
| assert_name_parse(data, sizeof(data), 0, expected, 5, ' '); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
|
|
| RUN_TEST(test_htmlParseHTMLName_ascii_tag_lowercase_stop_on_gt); |
| RUN_TEST(test_htmlParseHTMLName_attr_stop_on_equal); |
| RUN_TEST(test_htmlParseHTMLName_stop_on_space); |
| RUN_TEST(test_htmlParseHTMLName_stop_on_slash); |
| RUN_TEST(test_htmlParseHTMLName_valid_utf8_preserved); |
| RUN_TEST(test_htmlParseHTMLName_invalid_utf8_replacement); |
| RUN_TEST(test_htmlParseHTMLName_embedded_nul_replacement); |
|
|
| int rc = UNITY_END(); |
| |
| xmlCleanupParser(); |
| return rc; |
| } |