#include "unity/unity.h" #include #include #include #include /* Wrapper for the static function under test (provided in the module) */ void test_htmlSkipBogusDoctype(htmlParserCtxtPtr ctxt); static htmlParserCtxtPtr make_ctxt_from_str(const char *s) { /* Use memory-based context so we control input content precisely */ return htmlCreateMemoryParserCtxt(s, (int)strlen(s)); } void setUp(void) { /* No global setup required */ } void tearDown(void) { /* No global teardown required */ } /* Basic case: single-line input with immediate '>' */ void test_htmlSkipBogusDoctype_basic(void) { const char *buf = "bogus>"; htmlParserCtxtPtr ctxt = make_ctxt_from_str(buf); TEST_ASSERT_NOT_NULL(ctxt); TEST_ASSERT_NOT_NULL(ctxt->input); /* Start at known position */ ctxt->input->line = 1; ctxt->input->col = 1; test_htmlSkipBogusDoctype(ctxt); /* Expect cursor right after '>' */ int offset = (int)(ctxt->input->cur - ctxt->input->base); TEST_ASSERT_EQUAL_INT(6, offset); /* "bogus>" is 6 chars */ /* No newlines, so line unchanged; col counts characters processed including '>' */ TEST_ASSERT_EQUAL_INT(1, ctxt->input->line); TEST_ASSERT_EQUAL_INT(7, ctxt->input->col); /* initial 1 + 6 chars processed */ htmlFreeParserCtxt(ctxt); } /* Newline handling: ensure line increments and col resets to 1 after '\n' */ void test_htmlSkipBogusDoctype_with_newlines(void) { const char *buf = "ab\ncd>"; htmlParserCtxtPtr ctxt = make_ctxt_from_str(buf); TEST_ASSERT_NOT_NULL(ctxt); TEST_ASSERT_NOT_NULL(ctxt->input); ctxt->input->line = 1; ctxt->input->col = 1; test_htmlSkipBogusDoctype(ctxt); int offset = (int)(ctxt->input->cur - ctxt->input->base); TEST_ASSERT_EQUAL_INT(6, offset); /* processed entire string up to and including '>' */ /* One newline encountered: line increments by 1 */ TEST_ASSERT_EQUAL_INT(2, ctxt->input->line); /* Col progression: 'a' -> 2, 'b' -> 3, '\n' -> (inc to 4 then reset to 1), 'c' -> 2, 'd' -> 3, '>' -> 4 */ TEST_ASSERT_EQUAL_INT(4, ctxt->input->col); htmlFreeParserCtxt(ctxt); } /* No closing '>' => should advance to end-of-buffer with correct line/col */ void test_htmlSkipBogusDoctype_no_gt_reaches_eof(void) { const char *buf = "no gt present"; const int len = (int)strlen(buf); htmlParserCtxtPtr ctxt = make_ctxt_from_str(buf); TEST_ASSERT_NOT_NULL(ctxt); TEST_ASSERT_NOT_NULL(ctxt->input); ctxt->input->line = 5; ctxt->input->col = 10; test_htmlSkipBogusDoctype(ctxt); /* Cursor at end */ int offset = (int)(ctxt->input->cur - ctxt->input->base); TEST_ASSERT_EQUAL_INT(len, offset); /* No newlines in input; col increments by total characters processed */ TEST_ASSERT_EQUAL_INT(5, ctxt->input->line); TEST_ASSERT_EQUAL_INT(10 + len, ctxt->input->col); htmlFreeParserCtxt(ctxt); } /* Zero available input at entry (cur == end) => no changes */ void test_htmlSkipBogusDoctype_zero_avail_noop(void) { const char *buf = ">"; htmlParserCtxtPtr ctxt = make_ctxt_from_str(buf); TEST_ASSERT_NOT_NULL(ctxt); TEST_ASSERT_NOT_NULL(ctxt->input); /* Move to end so avail == 0 */ ctxt->input->cur = ctxt->input->end; ctxt->input->line = 3; ctxt->input->col = 7; test_htmlSkipBogusDoctype(ctxt); /* Expect unchanged */ TEST_ASSERT_TRUE(ctxt->input->cur == ctxt->input->end); TEST_ASSERT_EQUAL_INT(3, ctxt->input->line); TEST_ASSERT_EQUAL_INT(7, ctxt->input->col); htmlFreeParserCtxt(ctxt); } /* Long input to ensure scanning works when avail is large (>64) */ void test_htmlSkipBogusDoctype_long_input(void) { /* Create 200 'x' characters followed by '>' */ const int xcount = 200; const int total = xcount + 1; char *buf = (char *)malloc((size_t)total + 1); TEST_ASSERT_NOT_NULL(buf); memset(buf, 'x', (size_t)xcount); buf[xcount] = '>'; buf[total] = '\0'; htmlParserCtxtPtr ctxt = make_ctxt_from_str(buf); TEST_ASSERT_NOT_NULL(ctxt); TEST_ASSERT_NOT_NULL(ctxt->input); ctxt->input->line = 1; ctxt->input->col = 1; test_htmlSkipBogusDoctype(ctxt); int offset = (int)(ctxt->input->cur - ctxt->input->base); TEST_ASSERT_EQUAL_INT(total, offset); /* advanced past '>' */ TEST_ASSERT_EQUAL_INT(1, ctxt->input->line); TEST_ASSERT_EQUAL_INT(1 + total, ctxt->input->col); htmlFreeParserCtxt(ctxt); free(buf); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_htmlSkipBogusDoctype_basic); RUN_TEST(test_htmlSkipBogusDoctype_with_newlines); RUN_TEST(test_htmlSkipBogusDoctype_no_gt_reaches_eof); RUN_TEST(test_htmlSkipBogusDoctype_zero_avail_noop); RUN_TEST(test_htmlSkipBogusDoctype_long_input); return UNITY_END(); }