Skip to content

util: fix OSC 8 hyperlink stripping in stripVTControlCharacters#64319

Open
dushyant-hada-90 wants to merge 3 commits into
nodejs:mainfrom
dushyant-hada-90:fix/strip-vt-osc-8-uri-chars
Open

util: fix OSC 8 hyperlink stripping in stripVTControlCharacters#64319
dushyant-hada-90 wants to merge 3 commits into
nodejs:mainfrom
dushyant-hada-90:fix/strip-vt-osc-8-uri-chars

Conversation

@dushyant-hada-90

Copy link
Copy Markdown

Fixes: #64313

Summary

The bundled ansi-regex OSC pattern used by stripVTControlCharacters() relied on a restrictive URI character class that failed when OSC 8 hyperlink URIs contained RFC 3986-valid characters such as (, ), !, +, [ and ].

This updates OSC handling to match sequences generically as:

ESC ] ... ST

aligned with ansi-regex v6.2.0.

Problem

stripVTControlCharacters() failed to correctly strip OSC 8 hyperlinks whose URI contained characters omitted from the previous regex character class:

[-a-zA-Z\d/#&.:=?%@~_]

Example:

import { stripVTControlCharacters } from 'node:util';

const link =
  '\u001B]8;;https://example.com/(foo\u0007label\u001B]8;;\u0007';

console.log(stripVTControlCharacters(link));

Actual

ttps://example.com/(foo\u0007label

Expected

label

The OSC match terminated early at (, leaving most of the escape sequence in the output.

Changes

  • Replace the restrictive OSC URI matcher with generic OSC matching up to the first string terminator (BEL, ESC \, or 0x9C)
  • Sync the bundled regex behavior with ansi-regex v6.2.0
  • Preserve existing CSI handling logic

Tests

Added regression coverage in:

test/parallel/test-util-stripvtcontrolcharacters.js

for OSC 8 hyperlinks containing:

  • (
  • )
  • !
  • +
  • [ ]

across all supported OSC string terminators.

Notes

  • Existing CSI handling is unchanged
  • Fast-path behavior is unchanged
  • Embedded OSC terminators inside URIs retain previous behavior

The bundled ansi-regex OSC pattern used a restrictive URI character class that failed when URIs contained RFC 3986-valid characters such as parentheses. Match OSC sequences generically as ESC ] ... ST, aligned with ansi-regex v6.2.0.

Co-authored-by: Cursor <cursoragent@cursor.com>
@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module. labels Jul 6, 2026
Comment thread lib/internal/util/inspect.js Outdated
'[\\dA-PR-TZcf-nq-uy=><~]))', 'g',
'(?:\\u001B\\][\\s\\S]*?(?:\\u0007|\\u001B\\u005C|\\u009C))' +
'|[\\u001B\\u009B][[\\]()#;?]*' +
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?' +

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not complete consistent with
(?:;\d{0,4})*
(?:[;:]\d{0,4})*

Comment thread lib/internal/util/inspect.js Outdated
dushyant-hada-90 and others added 2 commits July 8, 2026 11:02
Co-authored-by: Archkon <180910180+Archkon@users.noreply.github.com>
Signed-off-by: dushyant <dushyanthada90@gmail.com>
Signed-off-by: dushyant <dushyanthada90@gmail.com>
@dushyant-hada-90 dushyant-hada-90 force-pushed the fix/strip-vt-osc-8-uri-chars branch from e3d3cb8 to 9da6ef2 Compare July 8, 2026 05:40
@dushyant-hada-90

Copy link
Copy Markdown
Author

Pushed updates addressing the feedback:

Accepted the [;:] CSI parameter separator suggestion (@Archkon) and reworded the commit to follow commit message guidelines
Added regression tests for the remaining RFC 3986 characters ($ ' * ,), colon-delimited CSI sub-parameters, and an unterminated-OSC edge case

Verified the final regex against every added test case and confirmed it now matches upstream ansi-regex v6.2.0 exactly.
Ready for another look

@dushyant-hada-90 dushyant-hada-90 requested a review from Archkon July 8, 2026 05:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

util.stripVTControlCharacters() fails to strip OSC 8 hyperlinks whose URI contains characters like "("

3 participants