Skip to content

fix: prevent re-interpretation of % in formatted output - #1028

Open
abhu85 wants to merge 1 commit into
debug-js:masterfrom
abhu85:fix/766-percent-in-formatted-output
Open

fix: prevent re-interpretation of % in formatted output#1028
abhu85 wants to merge 1 commit into
debug-js:masterfrom
abhu85:fix/766-percent-in-formatted-output

Conversation

@abhu85

@abhu85 abhu85 commented Apr 29, 2026

Copy link
Copy Markdown

Summary

Prevent % characters in formatted object output from being re-interpreted as format specifiers.

Problem

When %o or %O formats an object containing % in its keys or values, the stringified output is passed directly into args[0]. The downstream logger (util.formatWithOptions in Node.js, or console.log in browsers) then re-scans the formatted string for %s, %d, %j, etc. specifiers found inside the already-formatted object, consuming subsequent arguments and producing garbled output.

For example:

debug('%o', { '%j': '%j %j %%' }, 1, 2, 3);
// Before: test { '1': '2 3 %' }   (garbled — %j consumed args 1, 2)
// After:  test { '%j': '%j %j %%' } 1 2 3   (correct)

Solution

Instead of inlining the formatter output directly into args[0] and removing the original argument, we now replace the original argument in-place with the formatted string and substitute %s as a placeholder in the format string. This delegates the final substitution to the downstream logger (util.formatWithOptions / console.log), which processes %s by consuming the next argument — the pre-formatted string — without re-scanning its contents for additional specifiers.

This is a minimal change (3 lines replaced) that preserves backward compatibility with all existing format specifiers.

Test Plan

  • debug('%o', {'%j': '%j'}) outputs object literally
  • debug('%o', {'key': '100%'}) preserves the percent
  • Mixed specifiers with % in objects work correctly
  • Existing format specifier tests pass (16 pre-existing + 5 new)
  • Normal %o / %O formatting unchanged for objects without %

Fixes #766
Fixes #687

注册 for free to join this conversation on GitHub. Already have an account? 登录 to comment

标签

None yet

Development

Successfully merging this pull request may close these issues.

% symbol in object interpreted as formatter when %j exists in a formatted object, it pulls in the timestamp/delta

1 participant