Sanitize XML strings.

Replace characters with their XML string equivalents to allow for them
in the tests and groups names.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Jakub Czapiga 2024-01-30 11:12:03 +01:00 committed by Andreas Schneider
parent 54b3af4631
commit 90315882d6
3 changed files with 26 additions and 5 deletions

View File

@ -2963,6 +2963,16 @@ enum cm_printf_type {
static int xml_printed;
static int file_append;
static void cmprepare_xml_attribute_string(char *buf, size_t buf_len, const char *src)
{
snprintf(buf, buf_len, "%s", src);
c_strreplace(buf, buf_len, "&", "&amp;", NULL);
c_strreplace(buf, buf_len, "\"", "&quot;", NULL);
c_strreplace(buf, buf_len, "\'", "&apos;", NULL);
c_strreplace(buf, buf_len, "<", "&lt;", NULL);
c_strreplace(buf, buf_len, ">", "&gt;", NULL);
}
static void cmprintf_group_finish_xml(const char *group_name,
size_t total_executed,
size_t total_failed,
@ -3021,10 +3031,15 @@ static void cmprintf_group_finish_xml(const char *group_name,
}
}
char group_name_escaped[1024];
cmprepare_xml_attribute_string(group_name_escaped,
sizeof(group_name_escaped),
group_name);
fprintf(fp, "<testsuites>\n");
fprintf(fp, " <testsuite name=\"%s\" time=\"%.3f\" "
"tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" >\n",
group_name,
group_name_escaped,
total_runtime, /* seconds */
(unsigned)total_executed,
(unsigned)total_failed,
@ -3034,8 +3049,14 @@ static void cmprintf_group_finish_xml(const char *group_name,
for (i = 0; i < total_executed; i++) {
struct CMUnitTestState *cmtest = &cm_tests[i];
/* Escape double quotes and remove spaces in test name */
char test_name_escaped[1024];
cmprepare_xml_attribute_string(test_name_escaped,
sizeof(test_name_escaped),
cmtest->test->name);
fprintf(fp, " <testcase name=\"%s\" time=\"%.3f\" >\n",
cmtest->test->name, cmtest->runtime);
test_name_escaped, cmtest->runtime);
switch (cmtest->status) {
case CM_TEST_ERROR:

View File

@ -282,7 +282,7 @@ set(test_groups_tap_out
"# ok - test_group1"
"1\\.\\.1"
"ok 1 - int_test_success"
"# ok - test_group2")
"# ok - test_group2 num=<'\"2&2'\">")
set(test_skip_tap_out
"ok 1 # SKIP")
set(test_setup_fail_tap_out
@ -315,7 +315,7 @@ set(test_groups_xml_out
"<testcase name=\"null_test_success\" time=\"[0-9.]+\" >"
"</testcase>"
"</testsuite>"
".*<testsuite name=\"test_group2\" time=\"[0-9.]+\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\" >"
".*<testsuite name=\"test_group2 num=&lt[;]&apos[;]&quot[;]2&amp[;]2&apos[;]&quot[;]&gt[;]\" time=\"[0-9.]+\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\" >"
"<testcase name=\"int_test_success\" time=\"[0-9.]+\" >"
"</testcase>"
"</testsuite>"

View File

@ -64,7 +64,7 @@ int main(void) {
int result = 0;
result += cmocka_run_group_tests(test_group1, NULL, NULL);
result += cmocka_run_group_tests(test_group2, NULL, NULL);
result += cmocka_run_group_tests_name("test_group2 num=<'\"2&2'\">", test_group2, NULL, NULL);
return result;
}