diff --git a/benchmark/util/strip-vt-control-characters.js b/benchmark/util/strip-vt-control-characters.js new file mode 100644 index 00000000000000..a83b03bb2bb26d --- /dev/null +++ b/benchmark/util/strip-vt-control-characters.js @@ -0,0 +1,36 @@ +'use strict'; + +const common = require('../common.js'); + +const { stripVTControlCharacters } = require('node:util'); +const assert = require('node:assert'); + +const bench = common.createBenchmark(main, { + input: ['noAnsi-short', 'noAnsi-long', 'ansi-short', 'ansi-long'], + n: [1e6], +}); + +function main({ input, n }) { + let str; + switch (input) { + case 'noAnsi-short': + str = 'This is a plain text string without any ANSI codes'; + break; + case 'noAnsi-long': + str = 'Long plain text without ANSI. '.repeat(333); + break; + case 'ansi-short': + str = '\u001B[31mHello\u001B[39m'; + break; + case 'ansi-long': + str = ('\u001B[31m' + 'colored text '.repeat(10) + '\u001B[39m').repeat(10); + break; + } + + bench.start(); + for (let i = 0; i < n; i++) { + const result = stripVTControlCharacters(str); + assert.ok(typeof result === 'string'); + } + bench.end(n); +} diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 3d0787e8d1a9b7..c39183e6a6c20a 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -3036,6 +3036,10 @@ if (internalBinding('config').hasIntl) { function stripVTControlCharacters(str) { validateString(str, 'str'); + if (!StringPrototypeIncludes(str, '\u001B') && + !StringPrototypeIncludes(str, '\u009B')) + return str; + return RegExpPrototypeSymbolReplace(ansi, str, ''); } diff --git a/test/parallel/test-util.js b/test/parallel/test-util.js index 1ecddc829a0fdb..ad6c8142b27d0b 100644 --- a/test/parallel/test-util.js +++ b/test/parallel/test-util.js @@ -87,3 +87,13 @@ assert.throws(() => { message: 'The "str" argument must be of type string.' + common.invalidArgTypeHelper({}) }); + +// stripVTControlCharacters: fast path returns input when no ANSI codes +assert.strictEqual(util.stripVTControlCharacters('hello'), 'hello'); +assert.strictEqual(util.stripVTControlCharacters(''), ''); + +// stripVTControlCharacters: strips 7-bit ESC sequences +assert.strictEqual(util.stripVTControlCharacters('\u001B[31mfoo\u001B[39m'), 'foo'); + +// stripVTControlCharacters: strips 8-bit CSI sequences +assert.strictEqual(util.stripVTControlCharacters('\u009B31mfoo\u009B39m'), 'foo');