Skip to content

test_runner: junit reporter writes raw C0 control characters (e.g. ANSI color codes), producing invalid XML #67155

Open

Description

@yasyf

Version

v24.20.0 (also present on main)

Platform

Linux x64

Subsystem

test_runner

What steps will reproduce the bug?

// t.test.mjs
import { test } from "node:test"
import assert from "node:assert"
test("diff", () => assert.deepEqual({ a: 1 }, { a: 2 }))
FORCE_COLOR=1 node --test --test-reporter junit --test-reporter-destination r.xml t.test.mjs
xmllint --noout r.xml

What is the expected behavior?

r.xml is well-formed XML 1.0.

What do you see instead?

xmllint rejects the file: the <failure> message contains raw ANSI escape bytes (U+001B) from the colored assertion diff. XML 1.0 forbids C0 control characters other than tab, LF and CR, even as numeric character references (&#27; is also illegal), so JUnit consumers reject the whole report.

Additional information

lib/internal/test_runner/reporter/junit.js escapes only &, <, " and newlines. Any C0 control character in a test name, failure message or stack is written as-is. Colored assertion diffs are the common trigger (child processes get FORCE_COLOR=1 when the runner's destination is a color terminal), but a test name or error string containing \x1b or \x00 produces the same invalid file. The reporter would need to strip or replace these characters rather than escape them.

Related: #67149 (a different junit reporter output defect, <undefined> elements after truncated results).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions