File size: 6,070 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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
#include "unity/unity.h"
#include <libxml/HTMLparser.h>
#include <libxml/xmlerror.h>
#include <libxml/parser.h>
#include <string.h>
#include <stdlib.h>
/* The wrapper provided in the module for the static function */
void test_htmlCheckMeta(htmlParserCtxtPtr ctxt, const xmlChar **atts);
static htmlParserCtxtPtr make_ctxt(void) {
htmlParserCtxtPtr ctxt = htmlNewParserCtxt();
TEST_ASSERT_NOT_NULL_MESSAGE(ctxt, "Failed to create HTML parser context");
xmlCtxtResetLastError(ctxt);
return ctxt;
}
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
static void assert_encoding_equals_case_insensitive(const xmlChar *enc, const char *expected) {
TEST_ASSERT_NOT_NULL_MESSAGE(enc, "Encoding was not set");
TEST_ASSERT_EQUAL_INT_MESSAGE(0, xmlStrcasecmp(enc, BAD_CAST expected),
"Declared encoding does not match expected (case-insensitive compare)");
}
void test_htmlCheckMeta_charset_utf8_sets_declared_encoding(void) {
htmlParserCtxtPtr ctxt = make_ctxt();
const xmlChar *atts[] = {
BAD_CAST "charset", BAD_CAST "utf-8",
NULL
};
TEST_ASSERT_NULL_MESSAGE(ctxt->encoding, "Precondition failed: encoding should start as NULL");
xmlCtxtResetLastError(ctxt);
test_htmlCheckMeta(ctxt, atts);
assert_encoding_equals_case_insensitive(ctxt->encoding, "utf-8");
xmlErrorPtr err = xmlCtxtGetLastError(ctxt);
TEST_ASSERT_TRUE_MESSAGE(err == NULL || err->code == 0,
"Unexpected error after setting UTF-8 encoding");
htmlFreeParserCtxt(ctxt);
}
void test_htmlCheckMeta_http_equiv_content_type_sets_declared_encoding(void) {
htmlParserCtxtPtr ctxt = make_ctxt();
const xmlChar *atts[] = {
BAD_CAST "http-equiv", BAD_CAST "Content-Type",
BAD_CAST "content", BAD_CAST "text/html; charset=ISO-8859-1",
NULL
};
TEST_ASSERT_NULL(ctxt->encoding);
xmlCtxtResetLastError(ctxt);
test_htmlCheckMeta(ctxt, atts);
assert_encoding_equals_case_insensitive(ctxt->encoding, "ISO-8859-1");
xmlErrorPtr err = xmlCtxtGetLastError(ctxt);
TEST_ASSERT_TRUE_MESSAGE(err == NULL || err->code == 0,
"Unexpected error after setting ISO-8859-1 encoding");
htmlFreeParserCtxt(ctxt);
}
void test_htmlCheckMeta_charset_precedence_over_http_equiv(void) {
htmlParserCtxtPtr ctxt = make_ctxt();
const xmlChar *atts[] = {
BAD_CAST "http-equiv", BAD_CAST "Content-Type",
BAD_CAST "content", BAD_CAST "text/html; charset=ISO-8859-1",
BAD_CAST "charset", BAD_CAST "utf-8",
NULL
};
TEST_ASSERT_NULL(ctxt->encoding);
xmlCtxtResetLastError(ctxt);
test_htmlCheckMeta(ctxt, atts);
/* charset attribute should take precedence */
assert_encoding_equals_case_insensitive(ctxt->encoding, "utf-8");
htmlFreeParserCtxt(ctxt);
}
void test_htmlCheckMeta_non_ascii_incompatible_emits_error_and_ignores(void) {
htmlParserCtxtPtr ctxt = make_ctxt();
const xmlChar *atts[] = {
BAD_CAST "charset", BAD_CAST "utf-16",
NULL
};
TEST_ASSERT_NULL(ctxt->encoding);
xmlCtxtResetLastError(ctxt);
test_htmlCheckMeta(ctxt, atts);
/* Should not set encoding due to non-ASCII-compatibility */
TEST_ASSERT_NULL_MESSAGE(ctxt->encoding, "Encoding should not be set for non-ASCII-compatible charset");
xmlErrorPtr err = xmlCtxtGetLastError(ctxt);
TEST_ASSERT_NOT_NULL_MESSAGE(err, "Expected an error for non-ASCII-compatible charset");
TEST_ASSERT_EQUAL_INT_MESSAGE(XML_ERR_UNSUPPORTED_ENCODING, err->code,
"Expected XML_ERR_UNSUPPORTED_ENCODING error code");
htmlFreeParserCtxt(ctxt);
}
void test_htmlCheckMeta_null_context_no_crash(void) {
const xmlChar *atts[] = {
BAD_CAST "charset", BAD_CAST "utf-8",
NULL
};
/* Just ensure no crash; nothing to assert on context */
test_htmlCheckMeta(NULL, atts);
TEST_ASSERT_TRUE(1);
}
void test_htmlCheckMeta_null_atts_no_action(void) {
htmlParserCtxtPtr ctxt = make_ctxt();
TEST_ASSERT_NULL(ctxt->encoding);
xmlCtxtResetLastError(ctxt);
test_htmlCheckMeta(ctxt, NULL);
TEST_ASSERT_NULL_MESSAGE(ctxt->encoding, "Encoding should remain NULL when atts is NULL");
htmlFreeParserCtxt(ctxt);
}
void test_htmlCheckMeta_content_without_http_equiv_no_action(void) {
htmlParserCtxtPtr ctxt = make_ctxt();
const xmlChar *atts[] = {
BAD_CAST "content", BAD_CAST "text/html; charset=UTF-8",
NULL
};
TEST_ASSERT_NULL(ctxt->encoding);
xmlCtxtResetLastError(ctxt);
test_htmlCheckMeta(ctxt, atts);
TEST_ASSERT_NULL_MESSAGE(ctxt->encoding, "Encoding should not be set without http-equiv=Content-Type");
htmlFreeParserCtxt(ctxt);
}
void test_htmlCheckMeta_case_insensitive_matching(void) {
htmlParserCtxtPtr ctxt = make_ctxt();
const xmlChar *atts[] = {
BAD_CAST "HTTP-EQUIV", BAD_CAST "content-type",
BAD_CAST "CoNtEnT", BAD_CAST "text/html; charset=iso-8859-1",
NULL
};
TEST_ASSERT_NULL(ctxt->encoding);
xmlCtxtResetLastError(ctxt);
test_htmlCheckMeta(ctxt, atts);
assert_encoding_equals_case_insensitive(ctxt->encoding, "iso-8859-1");
htmlFreeParserCtxt(ctxt);
}
int main(void) {
xmlInitParser();
UNITY_BEGIN();
RUN_TEST(test_htmlCheckMeta_charset_utf8_sets_declared_encoding);
RUN_TEST(test_htmlCheckMeta_http_equiv_content_type_sets_declared_encoding);
RUN_TEST(test_htmlCheckMeta_charset_precedence_over_http_equiv);
RUN_TEST(test_htmlCheckMeta_non_ascii_incompatible_emits_error_and_ignores);
RUN_TEST(test_htmlCheckMeta_null_context_no_crash);
RUN_TEST(test_htmlCheckMeta_null_atts_no_action);
RUN_TEST(test_htmlCheckMeta_content_without_http_equiv_no_action);
RUN_TEST(test_htmlCheckMeta_case_insensitive_matching);
int res = UNITY_END();
xmlCleanupParser();
return res;
} |