libxml / tests /tests_HTMLparser_htmlParseLookupGt.c
AryaWu's picture
Upload folder using huggingface_hub
6baed57 verified
#include "unity/unity.h"
#include <libxml/HTMLparser.h>
#include <string.h>
#include <stdlib.h>
/* Wrapper provided in the module for calling the static function */
int test_htmlParseLookupGt(xmlParserCtxtPtr ctxt);
/* Unity hooks */
void setUp(void) {
/* No per-test setup needed */
}
void tearDown(void) {
/* No per-test teardown needed */
}
/* Helper to create an HTML parser context from a C string */
static htmlParserCtxtPtr make_ctx(const char *s) {
int len = (int)strlen(s);
htmlParserCtxtPtr ctxt = htmlCreateMemoryParserCtxt(s, len);
TEST_ASSERT_NOT_NULL_MESSAGE(ctxt, "Failed to create HTML parser context");
TEST_ASSERT_NOT_NULL_MESSAGE(ctxt->input, "Parser input is NULL");
/* Ensure cur starts at the beginning of the buffer for our tests */
if (ctxt->input->base != NULL)
ctxt->input->cur = ctxt->input->base;
return ctxt;
}
/* Basic tag: should find '>' immediately */
void test_htmlParseLookupGt_basic_tag(void) {
htmlParserCtxtPtr ctxt = make_ctx("<a>");
ctxt->checkIndex = 0;
ctxt->endCheckState = 0;
int ret = test_htmlParseLookupGt(ctxt);
TEST_ASSERT_EQUAL_INT(0, ret);
TEST_ASSERT_EQUAL_UINT(0, ctxt->checkIndex);
TEST_ASSERT_EQUAL_INT(0, ctxt->endCheckState);
htmlFreeParserCtxt(ctxt);
}
/* Tag with attributes and spaces before closing '>' */
void test_htmlParseLookupGt_attrs_and_spaces(void) {
htmlParserCtxtPtr ctxt = make_ctx("<a href=\"test\" >");
ctxt->checkIndex = 0;
ctxt->endCheckState = 0;
int ret = test_htmlParseLookupGt(ctxt);
TEST_ASSERT_EQUAL_INT(0, ret);
TEST_ASSERT_EQUAL_UINT(0, ctxt->checkIndex);
TEST_ASSERT_EQUAL_INT(0, ctxt->endCheckState);
htmlFreeParserCtxt(ctxt);
}
/* '>' inside single-quoted attribute value must not terminate the tag */
void test_htmlParseLookupGt_gt_inside_single_quotes(void) {
htmlParserCtxtPtr ctxt = make_ctx("<a title='> not end' data='x'>");
ctxt->checkIndex = 0;
ctxt->endCheckState = 0;
int ret = test_htmlParseLookupGt(ctxt);
TEST_ASSERT_EQUAL_INT(0, ret);
TEST_ASSERT_EQUAL_UINT(0, ctxt->checkIndex);
TEST_ASSERT_EQUAL_INT(0, ctxt->endCheckState);
htmlFreeParserCtxt(ctxt);
}
/* '>' inside double-quoted attribute value must not terminate the tag */
void test_htmlParseLookupGt_gt_inside_double_quotes(void) {
htmlParserCtxtPtr ctxt = make_ctx("<a title=\"> not end\" data=\"x\">");
ctxt->checkIndex = 0;
ctxt->endCheckState = 0;
int ret = test_htmlParseLookupGt(ctxt);
TEST_ASSERT_EQUAL_INT(0, ret);
TEST_ASSERT_EQUAL_UINT(0, ctxt->checkIndex);
TEST_ASSERT_EQUAL_INT(0, ctxt->endCheckState);
htmlFreeParserCtxt(ctxt);
}
/* Incomplete tag: no closing '>' in buffer */
void test_htmlParseLookupGt_incomplete_no_gt(void) {
const char *buf = "<a href='incomplete'";
htmlParserCtxtPtr ctxt = make_ctx(buf);
ctxt->checkIndex = 0;
ctxt->endCheckState = 0;
size_t expectedIndex = (size_t)(ctxt->input->end - ctxt->input->cur);
int ret = test_htmlParseLookupGt(ctxt);
TEST_ASSERT_EQUAL_INT(-1, ret);
TEST_ASSERT_EQUAL_size_t(expectedIndex, ctxt->checkIndex);
/* endCheckState is implementation-defined but should be preserved and non-negative */
TEST_ASSERT_TRUE(ctxt->endCheckState >= 0);
htmlFreeParserCtxt(ctxt);
}
/* Repeated call on the same incomplete buffer should be idempotent */
void test_htmlParseLookupGt_incomplete_repeat_call_stable(void) {
const char *buf = "<a href='x' attr=y";
htmlParserCtxtPtr ctxt = make_ctx(buf);
ctxt->checkIndex = 0;
ctxt->endCheckState = 0;
size_t expectedIndex = (size_t)(ctxt->input->end - ctxt->input->cur);
int ret1 = test_htmlParseLookupGt(ctxt);
TEST_ASSERT_EQUAL_INT(-1, ret1);
int savedState = ctxt->endCheckState;
size_t savedIndex = ctxt->checkIndex;
int ret2 = test_htmlParseLookupGt(ctxt);
TEST_ASSERT_EQUAL_INT(-1, ret2);
TEST_ASSERT_EQUAL_size_t(expectedIndex, ctxt->checkIndex);
TEST_ASSERT_EQUAL_size_t(savedIndex, ctxt->checkIndex);
TEST_ASSERT_EQUAL_INT(savedState, ctxt->endCheckState);
htmlFreeParserCtxt(ctxt);
}
/* Resume scanning across buffers: first incomplete, then complete */
void test_htmlParseLookupGt_resume_scanning_across_buffers(void) {
const char *part1 = "<a href='value'";
const char *part2 = "<a href='value' data=x>";
/* First, incomplete buffer */
htmlParserCtxtPtr ctxt1 = make_ctx(part1);
ctxt1->checkIndex = 0;
ctxt1->endCheckState = 0;
int ret1 = test_htmlParseLookupGt(ctxt1);
TEST_ASSERT_EQUAL_INT(-1, ret1);
size_t savedIndex = ctxt1->checkIndex;
int savedState = ctxt1->endCheckState;
htmlFreeParserCtxt(ctxt1);
/* Now, new buffer that continues and closes the tag */
htmlParserCtxtPtr ctxt2 = make_ctx(part2);
ctxt2->checkIndex = savedIndex; /* resume offset */
ctxt2->endCheckState = savedState; /* resume state */
int ret2 = test_htmlParseLookupGt(ctxt2);
TEST_ASSERT_EQUAL_INT(0, ret2);
TEST_ASSERT_EQUAL_UINT(0, ctxt2->checkIndex);
TEST_ASSERT_EQUAL_INT(0, ctxt2->endCheckState);
htmlFreeParserCtxt(ctxt2);
}
/* Closing tag should be handled correctly */
void test_htmlParseLookupGt_closing_tag(void) {
htmlParserCtxtPtr ctxt = make_ctx("</div>");
ctxt->checkIndex = 0;
ctxt->endCheckState = 0;
int ret = test_htmlParseLookupGt(ctxt);
TEST_ASSERT_EQUAL_INT(0, ret);
TEST_ASSERT_EQUAL_UINT(0, ctxt->checkIndex);
TEST_ASSERT_EQUAL_INT(0, ctxt->endCheckState);
htmlFreeParserCtxt(ctxt);
}
/* Self-closing tag with '/' before '>' */
void test_htmlParseLookupGt_self_closing(void) {
htmlParserCtxtPtr ctxt = make_ctx("<img alt='x'/>");
ctxt->checkIndex = 0;
ctxt->endCheckState = 0;
int ret = test_htmlParseLookupGt(ctxt);
TEST_ASSERT_EQUAL_INT(0, ret);
TEST_ASSERT_EQUAL_UINT(0, ctxt->checkIndex);
TEST_ASSERT_EQUAL_INT(0, ctxt->endCheckState);
htmlFreeParserCtxt(ctxt);
}
int main(void) {
UNITY_BEGIN();
xmlInitParser();
RUN_TEST(test_htmlParseLookupGt_basic_tag);
RUN_TEST(test_htmlParseLookupGt_attrs_and_spaces);
RUN_TEST(test_htmlParseLookupGt_gt_inside_single_quotes);
RUN_TEST(test_htmlParseLookupGt_gt_inside_double_quotes);
RUN_TEST(test_htmlParseLookupGt_incomplete_no_gt);
RUN_TEST(test_htmlParseLookupGt_incomplete_repeat_call_stable);
RUN_TEST(test_htmlParseLookupGt_resume_scanning_across_buffers);
RUN_TEST(test_htmlParseLookupGt_closing_tag);
RUN_TEST(test_htmlParseLookupGt_self_closing);
xmlCleanupParser();
return UNITY_END();
}