|
|
#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(); |
|
|
} |