|
|
#include "unity/unity.h" |
|
|
#include <libxml/HTMLparser.h> |
|
|
|
|
|
#include <stdlib.h> |
|
|
#include <string.h> |
|
|
|
|
|
|
|
|
void test_htmlParseComment(htmlParserCtxtPtr ctxt, int bogus); |
|
|
|
|
|
|
|
|
typedef struct { |
|
|
int count; |
|
|
char *last; |
|
|
} CommentCapture; |
|
|
|
|
|
static void free_capture(CommentCapture *cap) { |
|
|
if (cap->last) { |
|
|
free(cap->last); |
|
|
cap->last = NULL; |
|
|
} |
|
|
cap->count = 0; |
|
|
} |
|
|
|
|
|
static void comment_cb(void *ctx, const xmlChar *value) { |
|
|
CommentCapture *cap = (CommentCapture *)ctx; |
|
|
cap->count++; |
|
|
|
|
|
const char *val = (const char *)value; |
|
|
size_t n = strlen(val); |
|
|
free_capture(cap); |
|
|
cap->last = (char *)malloc(n + 1); |
|
|
if (cap->last) { |
|
|
memcpy(cap->last, val, n + 1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static htmlParserCtxtPtr make_ctxt(const char *data) { |
|
|
if (data == NULL) data = ""; |
|
|
int len = (int)strlen(data); |
|
|
htmlParserCtxtPtr ctxt = htmlCreateMemoryParserCtxt(data, len); |
|
|
return ctxt; |
|
|
} |
|
|
|
|
|
void setUp(void) { |
|
|
|
|
|
} |
|
|
|
|
|
void tearDown(void) { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlParseComment_bogus_basic(void) { |
|
|
CommentCapture cap = {0, NULL}; |
|
|
htmlParserCtxtPtr ctxt = make_ctxt("hello>"); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
xmlSAXHandler sax; |
|
|
memset(&sax, 0, sizeof(sax)); |
|
|
sax.comment = comment_cb; |
|
|
|
|
|
ctxt->sax = &sax; |
|
|
ctxt->userData = ∩ |
|
|
ctxt->disableSAX = 0; |
|
|
|
|
|
test_htmlParseComment(ctxt, 1); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(1, cap.count); |
|
|
TEST_ASSERT_NOT_NULL(cap.last); |
|
|
TEST_ASSERT_EQUAL_STRING("hello", cap.last); |
|
|
|
|
|
free_capture(&cap); |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlParseComment_bogus_no_terminator(void) { |
|
|
CommentCapture cap = {0, NULL}; |
|
|
htmlParserCtxtPtr ctxt = make_ctxt("noend"); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
xmlSAXHandler sax; |
|
|
memset(&sax, 0, sizeof(sax)); |
|
|
sax.comment = comment_cb; |
|
|
|
|
|
ctxt->sax = &sax; |
|
|
ctxt->userData = ∩ |
|
|
ctxt->disableSAX = 0; |
|
|
|
|
|
test_htmlParseComment(ctxt, 1); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(1, cap.count); |
|
|
TEST_ASSERT_NOT_NULL(cap.last); |
|
|
TEST_ASSERT_EQUAL_STRING("noend", cap.last); |
|
|
|
|
|
free_capture(&cap); |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlParseComment_nonbogus_immediate_gt(void) { |
|
|
CommentCapture cap = {0, NULL}; |
|
|
htmlParserCtxtPtr ctxt = make_ctxt(">"); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
xmlSAXHandler sax; |
|
|
memset(&sax, 0, sizeof(sax)); |
|
|
sax.comment = comment_cb; |
|
|
|
|
|
ctxt->sax = &sax; |
|
|
ctxt->userData = ∩ |
|
|
ctxt->disableSAX = 0; |
|
|
|
|
|
test_htmlParseComment(ctxt, 0); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(1, cap.count); |
|
|
TEST_ASSERT_NOT_NULL(cap.last); |
|
|
TEST_ASSERT_EQUAL_STRING("", cap.last); |
|
|
|
|
|
free_capture(&cap); |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlParseComment_nonbogus_immediate_arrow(void) { |
|
|
CommentCapture cap = {0, NULL}; |
|
|
htmlParserCtxtPtr ctxt = make_ctxt("->"); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
xmlSAXHandler sax; |
|
|
memset(&sax, 0, sizeof(sax)); |
|
|
sax.comment = comment_cb; |
|
|
|
|
|
ctxt->sax = &sax; |
|
|
ctxt->userData = ∩ |
|
|
ctxt->disableSAX = 0; |
|
|
|
|
|
test_htmlParseComment(ctxt, 0); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(1, cap.count); |
|
|
TEST_ASSERT_NOT_NULL(cap.last); |
|
|
TEST_ASSERT_EQUAL_STRING("", cap.last); |
|
|
|
|
|
free_capture(&cap); |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlParseComment_nonbogus_until_dash(void) { |
|
|
CommentCapture cap = {0, NULL}; |
|
|
htmlParserCtxtPtr ctxt = make_ctxt("abc-def->"); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
xmlSAXHandler sax; |
|
|
memset(&sax, 0, sizeof(sax)); |
|
|
sax.comment = comment_cb; |
|
|
|
|
|
ctxt->sax = &sax; |
|
|
ctxt->userData = ∩ |
|
|
ctxt->disableSAX = 0; |
|
|
|
|
|
test_htmlParseComment(ctxt, 0); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(1, cap.count); |
|
|
TEST_ASSERT_NOT_NULL(cap.last); |
|
|
TEST_ASSERT_EQUAL_STRING("abc", cap.last); |
|
|
|
|
|
free_capture(&cap); |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlParseComment_SAX_disabled(void) { |
|
|
CommentCapture cap = {0, NULL}; |
|
|
htmlParserCtxtPtr ctxt = make_ctxt("ignored>"); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
xmlSAXHandler sax; |
|
|
memset(&sax, 0, sizeof(sax)); |
|
|
sax.comment = comment_cb; |
|
|
|
|
|
ctxt->sax = &sax; |
|
|
ctxt->userData = ∩ |
|
|
ctxt->disableSAX = 1; |
|
|
|
|
|
test_htmlParseComment(ctxt, 1); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, cap.count); |
|
|
TEST_ASSERT_NULL(cap.last); |
|
|
|
|
|
free_capture(&cap); |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
|
|
|
void test_htmlParseComment_null_sax(void) { |
|
|
CommentCapture cap = {0, NULL}; |
|
|
htmlParserCtxtPtr ctxt = make_ctxt("hello>"); |
|
|
TEST_ASSERT_NOT_NULL(ctxt); |
|
|
|
|
|
ctxt->sax = NULL; |
|
|
ctxt->userData = ∩ |
|
|
ctxt->disableSAX = 0; |
|
|
|
|
|
test_htmlParseComment(ctxt, 1); |
|
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, cap.count); |
|
|
TEST_ASSERT_NULL(cap.last); |
|
|
|
|
|
free_capture(&cap); |
|
|
htmlFreeParserCtxt(ctxt); |
|
|
} |
|
|
|
|
|
int main(void) { |
|
|
|
|
|
xmlInitParser(); |
|
|
|
|
|
UNITY_BEGIN(); |
|
|
|
|
|
RUN_TEST(test_htmlParseComment_bogus_basic); |
|
|
RUN_TEST(test_htmlParseComment_bogus_no_terminator); |
|
|
RUN_TEST(test_htmlParseComment_nonbogus_immediate_gt); |
|
|
RUN_TEST(test_htmlParseComment_nonbogus_immediate_arrow); |
|
|
RUN_TEST(test_htmlParseComment_nonbogus_until_dash); |
|
|
RUN_TEST(test_htmlParseComment_SAX_disabled); |
|
|
RUN_TEST(test_htmlParseComment_null_sax); |
|
|
|
|
|
int rc = UNITY_END(); |
|
|
|
|
|
|
|
|
xmlCleanupParser(); |
|
|
|
|
|
return rc; |
|
|
} |