| | #include "unity/unity.h" |
| | #include <libxml/HTMLparser.h> |
| | #include <libxml/parser.h> |
| | #include <stdlib.h> |
| | #include <string.h> |
| |
|
| | |
| | extern void test_htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate); |
| |
|
| | |
| | static htmlParserCtxtPtr make_ctx_from_mem(const char *buf, int len) { |
| | htmlParserCtxtPtr ctxt = htmlCreateMemoryParserCtxt(buf, len); |
| | TEST_ASSERT_NOT_NULL_MESSAGE(ctxt, "Failed to create HTML parser context"); |
| | |
| | (void)htmlCtxtUseOptions(ctxt, HTML_PARSE_RECOVER | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING); |
| | return ctxt; |
| | } |
| |
|
| | static size_t cur_offset(htmlParserCtxtPtr ctxt) { |
| | return (size_t)(ctxt->input->cur - ctxt->input->base); |
| | } |
| |
|
| | static size_t end_offset(htmlParserCtxtPtr ctxt) { |
| | return (size_t)(ctxt->input->end - ctxt->input->base); |
| | } |
| |
|
| | |
| | void setUp(void) { |
| | |
| | xmlInitParser(); |
| | } |
| |
|
| | void tearDown(void) { |
| | |
| | } |
| |
|
| | |
| |
|
| | void test_htmlParseTryOrFinish_start_nonterminate_small_avail_returns_early(void) { |
| | const char *data = "abc"; |
| | htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| | TEST_ASSERT_EQUAL_INT(XML_PARSER_START, ctxt->instate); |
| |
|
| | size_t before_cur = cur_offset(ctxt); |
| | test_htmlParseTryOrFinish(ctxt, 0); |
| |
|
| | |
| | TEST_ASSERT_EQUAL_INT(XML_PARSER_START, ctxt->instate); |
| | TEST_ASSERT_EQUAL_size_t(before_cur, cur_offset(ctxt)); |
| |
|
| | htmlFreeParserCtxt(ctxt); |
| | } |
| |
|
| | void test_htmlParseTryOrFinish_start_terminate_progresses_and_consumes_text(void) { |
| | const char *data = "abc"; |
| | htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| | size_t end = end_offset(ctxt); |
| |
|
| | test_htmlParseTryOrFinish(ctxt, 1); |
| |
|
| | |
| | TEST_ASSERT_EQUAL_INT(XML_PARSER_CONTENT, ctxt->instate); |
| | TEST_ASSERT_EQUAL_size_t(end, cur_offset(ctxt)); |
| | |
| | TEST_ASSERT_EQUAL_INT(0, ctxt->endCheckState); |
| |
|
| | htmlFreeParserCtxt(ctxt); |
| | } |
| |
|
| | void test_htmlParseTryOrFinish_misc_to_start_tag_partial_nonterminate(void) { |
| | |
| | const char *data = " <p"; |
| | htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| |
|
| | test_htmlParseTryOrFinish(ctxt, 0); |
| |
|
| | |
| | TEST_ASSERT_EQUAL_INT(XML_PARSER_START_TAG, ctxt->instate); |
| | |
| | TEST_ASSERT_TRUE(ctxt->checkIndex != 0); |
| |
|
| | |
| | |
| | |
| | TEST_ASSERT_TRUE(cur_offset(ctxt) < end_offset(ctxt)); |
| |
|
| | htmlFreeParserCtxt(ctxt); |
| | } |
| |
|
| | void test_htmlParseTryOrFinish_parses_comment_and_advances(void) { |
| | const char *data = "<!--x-->"; |
| | htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| | size_t end = end_offset(ctxt); |
| |
|
| | test_htmlParseTryOrFinish(ctxt, 1); |
| |
|
| | |
| | TEST_ASSERT_EQUAL_size_t(end, cur_offset(ctxt)); |
| | |
| | TEST_ASSERT_NOT_EQUAL_INT(XML_PARSER_EOF, ctxt->instate); |
| |
|
| | htmlFreeParserCtxt(ctxt); |
| | } |
| |
|
| | void test_htmlParseTryOrFinish_parses_simple_element_and_end_tag_full_terminate(void) { |
| | const char *data = "<p>Hi</p>"; |
| | htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| | size_t end = end_offset(ctxt); |
| |
|
| | test_htmlParseTryOrFinish(ctxt, 1); |
| |
|
| | |
| | TEST_ASSERT_EQUAL_size_t(end, cur_offset(ctxt)); |
| | |
| | TEST_ASSERT_EQUAL_INT(XML_PARSER_CONTENT, ctxt->instate); |
| | TEST_ASSERT_EQUAL_INT(0, ctxt->endCheckState); |
| |
|
| | htmlFreeParserCtxt(ctxt); |
| | } |
| |
|
| | void test_htmlParseTryOrFinish_end_tag_only_transitions_and_consumes(void) { |
| | const char *data = "</p>"; |
| | htmlParserCtxtPtr ctxt = make_ctx_from_mem(data, (int)strlen(data)); |
| | size_t end = end_offset(ctxt); |
| |
|
| | test_htmlParseTryOrFinish(ctxt, 1); |
| |
|
| | |
| | TEST_ASSERT_EQUAL_size_t(end, cur_offset(ctxt)); |
| | |
| | TEST_ASSERT_EQUAL_INT(XML_PARSER_CONTENT, ctxt->instate); |
| |
|
| | htmlFreeParserCtxt(ctxt); |
| | } |
| |
|
| | |
| | int main(void) { |
| | UNITY_BEGIN(); |
| | RUN_TEST(test_htmlParseTryOrFinish_start_nonterminate_small_avail_returns_early); |
| | RUN_TEST(test_htmlParseTryOrFinish_start_terminate_progresses_and_consumes_text); |
| | RUN_TEST(test_htmlParseTryOrFinish_misc_to_start_tag_partial_nonterminate); |
| | RUN_TEST(test_htmlParseTryOrFinish_parses_comment_and_advances); |
| | RUN_TEST(test_htmlParseTryOrFinish_parses_simple_element_and_end_tag_full_terminate); |
| | RUN_TEST(test_htmlParseTryOrFinish_end_tag_only_transitions_and_consumes); |
| | return UNITY_END(); |
| | } |