#include "unity/unity.h" #include #include #include #include #include /* 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; }