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