File size: 4,884 Bytes
6baed57 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
#include "unity/unity.h"
#include <libxml/HTMLparser.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
/* 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();
} |