Skip to content

console.table: escape newlines/tabs in string cells - #29084

Closed
robobun wants to merge 11 commits into
mainfrom
farm/29b1cc9e/console-table-newline-escape
Closed

robobun wants to merge 11 commits into
mainfrom
farm/29b1cc9e/console-table-newline-escape

Conversation

@robobun

@robobun robobun commented Apr 9, 2026

Copy link
Copy Markdown
Collaborator

Fixes #29082.

Repro

$ bun -e 'console.table([{ foo: 123, bar: "Hello\nWorld"}])'
┌───┬─────┬────────────┐
│   │ foo │ bar        │
├───┼─────┼────────────┤
│ 0 │ 123 │ Hello
World │
└───┴─────┴────────────┘

The embedded \n lands in the middle of the row and breaks the table border.

Cause

TablePrinter.printRow / getWidthForValue unconditionally set
quote_strings = false for string cells — Bun's stylistic choice is to render
plain strings unquoted in console.table. That's fine for ordinary strings,
but raw \n/\r/\t break the fixed-width layout: the cell's visible
width no longer matches what the writer emits.

Fix

src/bun.js/ConsoleObject.zig: add shouldQuoteStringCell — when a string
cell contains \n, \r, or \t, promote it to the quoted JSON-escaped form
(matching Node.js' 'Hello\\nWorld'). Plain strings still render without
quotes, preserving Bun's existing style:

┌───┬─────┬────────────────┐
│   │ foo │ bar            │
├───┼─────┼────────────────┤
│ 0 │ 123 │ "Hello\nWorld" │
└───┴─────┴────────────────┘

The same check runs in both getWidthForValue (column sizing) and
printRow (actual render), so the width calculation and the output stay
in sync.

Verification

  • bun bd test test/regression/issue/29082.test.ts → 9 pass
  • USE_SYSTEM_BUN=1 bun test test/regression/issue/29082.test.ts → 8 fail
  • Manual: Map values, Set values, primitive arrays, the properties arg,
    mixed newline + plain rows — all render with a rectangular table.

@robobun

robobun commented Apr 9, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 8:06 AM PT - May 5th, 2026

❌ @autofix-ci[bot], your commit 581f051 has 1 failures in Build #51669 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 29084

That installs a local version of the PR into your bun-29084 executable, so you can run:

bun-29084 --bun

@coderabbitai

coderabbitai Bot commented Apr 9, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a regression test for console.table handling of embedded C0 control characters and modifies TablePrinter to quote/escape string cells only when they contain layout-breaking C0 controls, applying that decision consistently to width calculation and rendering.

Changes

Cohort / File(s) Summary
Regression tests for console.table
test/regression/issue/29082.test.ts
New test suite that spawns a Bun process to validate console.table behavior with control characters (\n, \r, \t, \v, \f, NUL, other 0x00–0x1F) and ANSI ESC; asserts escaped representations, absence of raw disruptive bytes, rectangular table layout via assertRectangular, and successful exit. Covers arrays, Maps, Sets, primitive arrays, and console.table(data, columns).
Console table rendering logic
src/bun.js/ConsoleObject.zig
Introduces TablePrinter.shouldQuoteStringCell and stringHasLayoutBreakingControlChar; adds getWidthForValueWithTag, rowKeyWidth, jsonQuotedStringWidth, and writeRowKey; ensures quote/escape decisions (excluding ESC 0x1B) are reused for width measurement and formatting so index and data cells render consistently.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: escaping newlines/tabs in string cells of console.table output, which directly addresses the core problem reported in issue #29082.
Description check ✅ Passed The pull request description comprehensively addresses both template sections: it explains what the PR does (fixes console.table control character handling), includes a repro, root cause analysis, fix explanation, and verification results matching the template structure.
Linked Issues check ✅ Passed The PR fully addresses the primary objective from issue #29082: fixing console.table misbehavior where multiline strings break table borders. The implementation chooses the quoted JSON-escaped approach and applies it consistently to data cells and index columns.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing console.table control character handling. The regression test suite comprehensively validates the fix across multiple table types, and the ConsoleObject.zig modifications directly implement the required control character detection and quoted rendering logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/regression/issue/29082.test.ts`:
- Around line 2-8: In the regression test file issue/29082.test.ts, remove the
multi-line historical bug-description comment block and leave only the
single-line issue URL reference; ensure any remaining comment explains test
rationale (not bug history) and keep the test body unchanged—target the leading
comment block that currently begins with the backtick-marked explanation about
console.table and replace it with a concise one-line reference to the issue.
- Around line 20-22: The helper runTable currently awaits proc.stdout.text() and
proc.exited and asserts expect(exitCode).To allow callers to assert stdout
before exit, remove the internal exit assertion from runTable, have it return
both stdout and exitCode (e.g., return { stdout, exitCode } or a tuple) by
awaiting Promise.all([proc.stdout.text(), proc.exited]) and returning both
values, and update call sites to assert output first then expect(exitCode).
Ensure references to runTable, stdout, exitCode, and proc are used to locate and
update the code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9b4ab70a-be17-4d8f-b90d-7bcd65867372

📥 Commits

Reviewing files that changed from the base of the PR and between 700fc11 and 879420a.

📒 Files selected for processing (2)
  • src/bun.js/ConsoleObject.zig
  • test/regression/issue/29082.test.ts

Comment thread test/regression/issue/29082.test.ts Outdated
Comment thread test/regression/issue/29082.test.ts Outdated

@claude claude Bot left a comment

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.


Additional findings (outside current diff — PR may have been updated during review):

  • 🟡 src/bun.js/ConsoleObject.zig:341-343 — The shouldQuoteStringCell check only covers \n, \r, and \t, leaving other C0 control characters (\v, \f, \0, 0x01–0x08, 0x0E–0x1F, 0x7F) unhandled — strings containing those chars are still emitted raw, potentially breaking the table border. Broadening the check to any codepoint < 0x20 or == 0x7F would close the gap.

    Extended reasoning...

    What the bug is

    shouldQuoteStringCell (lines 341–343) checks for exactly three ASCII control characters: \n (0x0A), \r (0x0D), and \t (0x09). The broader class of C0 control characters — \v (0x0B, vertical tab), \f (0x0C, form feed), \0 (NUL, 0x00), and all of 0x01–0x08 and 0x0E–0x1F — is never tested. DEL (0x7F) is also omitted.

    The code path that triggers it

    When shouldQuoteStringCell returns false, value_formatter.quote_strings is set to false in both getWidthForValue (line 359) and printRow (line 506). With quote_strings = false, the formatter takes the unquoted path and calls writer.writeAll(slice) verbatim — no escaping occurs. Meanwhile, VisibleCharacterCounter counts those characters as zero visible width (because visible.zig's isZeroWidthCodepointType treats all cp ≤ 0x1F as zero-width), so the computed column width is narrower than the raw bytes actually written. The width inconsistency breaks the table border.

    Why existing code doesn't prevent it

    The PR correctly handles the most commonly reported characters from issue #29082, but the guard is written as three explicit indexOfAsciiChar checks rather than a range test. There is no fallback that catches other control characters. The writeJSONString path (triggered when quote_strings = true) would fully escape every C0 character via JSON escaping, so the fix exists — it just is not triggered for the missing chars.

    Impact

    A string like "foo\vbar" passed to console.table would produce a visually broken table in any terminal that interprets vertical tab (0x0B) as cursor movement. Similarly, \f (0x0C) and other C0 chars cause real cursor displacement in many terminal emulators. NUL (0x00) can silently truncate output in some environments. These characters are rare in real-world usage, making this a low-priority nit.

    Step-by-step proof

    1. console.table([{ a: 'foo\vbar' }]) is called.
    2. getWidthForValue calls shouldQuoteStringCell for 'foo\vbar'.
    3. The string contains \v (0x0B). indexOfAsciiChar('\n') → null; indexOfAsciiChar('\r') → null; indexOfAsciiChar('\t') → null. Function returns false.
    4. value_formatter.quote_strings = false. The VisibleCharacterCounter counts 6 visible characters (foo + bar; \v is zero-width), returning width 6.
    5. In printRow, same path: shouldQuoteStringCell → false, raw slice foo\vbar is written.
    6. The terminal receives \v mid-row and moves the cursor down one line, fragmenting the table border.

    How to fix

    Replace the three indexOfAsciiChar calls with a range check: return true if any byte in the string satisfies b < 0x20 or b == 0x7F. This matches the full set of characters that VisibleCharacterCounter treats as zero-width and that terminals may interpret as control sequences.

Comment thread test/regression/issue/29082.test.ts Outdated
Comment thread test/regression/issue/29082.test.ts Outdated
Comment thread test/regression/issue/29082.test.ts Outdated
Comment thread test/regression/issue/29082.test.ts Outdated
Comment thread src/jsc/ConsoleObject.zig
Comment thread src/bun.js/ConsoleObject.zig Outdated
Comment thread test/regression/issue/29082.test.ts Outdated
Comment thread src/jsc/ConsoleObject.zig
Comment on lines +342 to 361
fn shouldQuoteStringCell(this: *TablePrinter, value: JSValue, tag: ConsoleObject.Formatter.Tag.Result) bun.JSError!bool {
if (!(tag.tag == .String or tag.tag == .StringPossiblyFormatted)) return true;
if (!value.isString()) return false;
var str: bun.String = try bun.String.fromJS(value, this.globalObject);
defer str.deref();
if (str.isUTF16()) {
for (str.utf16()) |c| {
if (c < 0x20) return true;
}
} else {
for (str.byteSlice()) |b| {
if (b < 0x20) return true;
}
}
return false;
}

/// Compute how much horizontal space will take a JSValue when printed
fn getWidthForValue(this: *TablePrinter, value: JSValue) bun.JSError!u32 {
var width: usize = 0;

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.

🟣 The PR's control-character escaping fix is incomplete: column header names are printed raw at line 646 with writer.print("{f}", .{col.name}) and no equivalent of shouldQuoteStringCell. A JS property name containing \n (e.g. console.table([{['a\nb']: 123}])) will emit a literal newline into the header row, breaking the table border in exactly the same way the original issue did for data cells. This is a pre-existing gap in the same TablePrinter rendering path — the PR didn't introduce it, but it's an opportunity to extend the same fix to headers.

Extended reasoning...

What the bug is and how it manifests

The PR introduces shouldQuoteStringCell and applies it to two places in TablePrinter: getWidthForValue (for column sizing) and printRow (for rendering). Both now correctly quote/escape string cells containing C0 control characters. However, a third place in the same struct — the column header printing path in printTable — is entirely untouched. At line 646, column names are emitted directly: try writer.print("{f}", .{col.name}). JavaScript property names are arbitrary strings, including computed property keys like ['a\nb'], so a column header can contain a raw newline.

The specific code path that triggers it

  1. User calls console.table([{['a\nb']: 123}]).
  2. The JS property key 'a\nb' is converted to a column name at line 429: const col_str = String.init(col_key).
  3. Column width is measured at line 627 via col.name.visibleWidthExcludeANSIColors(false) — this counts visible characters in the raw bytes; the embedded \n has zero visible width and does not account for the line-splitting effect.
  4. At line 646, writer.print("{f}", .{col.name}) emits the raw column name bytes, including the literal newline, directly into the header row.
  5. The terminal moves the cursor to the next line mid-header, splitting the header row and misaligning all subsequent borders.

Why existing code doesn't prevent it

The shouldQuoteStringCell function added by this PR only gates the quote_strings flag inside getWidthForValue and printRow. The header printing loop in printTable has no analogous check — col.name is always printed raw regardless of its contents. The width measurement via visibleWidthExcludeANSIColors similarly does not model the line-splitting effect of \n, so the measured column width and the actual rendered width diverge.

Impact

Any console.table call with a property key containing a C0 control character (most practically \n via template literals or String.fromCharCode) will produce a broken table border — the same visual corruption as the original issue #29082. In practice, computed property keys with embedded newlines are rare, but they are valid JavaScript and deserve the same protection that data cells now get.

How to fix

Apply the same escaping logic to the header printing path: before printing col.name, check if it contains any byte < 0x20 (mirroring shouldQuoteStringCell), and if so write the JSON-escaped form instead. The width measurement at line 627 should likewise use the escaped length when the name would be quoted, to keep sizing and rendering in sync.

Step-by-step proof

  1. console.table([{["a\nb"]: 123}]) — property key is 'a\nb' (3 bytes: 0x61, 0x0A, 0x62).
  2. Column name stored as col.name = 'a\nb'.
  3. Width measured: visibleWidthExcludeANSIColors('a\nb') counts 'a' (1) + '\n' (0) + 'b' (1) = 2 visible chars. Column sized for 2-char header.
  4. Header row starts: │ │ a — then literal newline emitted at character 7.
  5. Terminal cursor moves to next line. Rest of header (b │ ...) prints on line 2.
  6. Table borders are completely misaligned from this point forward — same visual corruption as the original bug for data cells.
  7. Data cells (e.g. the value 123) were fixed by this PR — but the header for the same column is still broken.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Confirmed — a property key like ["a\nb"] breaks the header row for the same underlying reason. This is a pre-existing gap (the PR did not introduce it) and the header code path has its own width + render flow with a bun.String column name, not a JSValue. Leaving this one out of scope for this PR to keep it focused on the cell fix from #29082; happy to file a follow-up if you'd like it tracked.

@claude claude Bot left a comment

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.

LGTM — all previously raised issues resolved.

Extended reasoning...

Overview

This PR fixes console.table rendering corruption caused by C0 control characters in string cells (issue #29082). Changes touch src/bun.js/ConsoleObject.zig (adds shouldQuoteStringCell, getWidthForValueWithTag) and a new regression test file. The final commit (a75b85b) incorporates all review feedback.

Security risks

None. This is a display/formatting path with no auth, crypto, or permission logic.

Level of scrutiny

Moderate: the change is in the JS console rendering path, not a hot or security-sensitive path. The fix is well-scoped — it only affects string cells containing C0 bytes (excluding ESC to preserve ANSI colors). Width calculation and render now use the same quote_strings decision, so they stay in sync.

Other factors

All issues I previously raised were addressed: ANSI regression fixed, double-scan eliminated, stderr drained, tests run concurrently, positive assertion added to the C0 test. The pre-existing index-column gap flagged by the bug hunter predates this PR and is out of scope. Test suite passes 9/9 with the fixed build.

Comment thread src/jsc/ConsoleObject.zig
Comment thread src/bun.js/ConsoleObject.zig Outdated

@claude claude Bot left a comment

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.

LGTM — all review feedback addressed across multiple rounds; the implementation correctly handles control characters in both data cells and index column, excludes ESC for ANSI compatibility, and deduplicates the byte scans.

Extended reasoning...

Overview

This PR fixes breaking when string cells contain C0 control characters (, , , etc.) by introducing / and routing both width calculation and rendering through the same quoting decision. It also covers the index column (object property keys) and adds a comprehensive regression test suite.

Security risks

None. This is purely a display/formatting fix with no security surface.

Level of scrutiny

Low — the change is scoped to rendering, a non-security, non-critical debug utility. The logic is well-contained and the test suite is thorough.

Other factors

After five rounds of review covering: accidental revert of the Zig fix, ANSI color regression (ESC in C0 range), double-scan inefficiency, index column gap, missing positive test assertions, stderr deadlock risk, and concurrent test usage — all issues have been resolved in the final commits. The pre-existing header-name gap was explicitly scoped out by the author. The current HEAD state is correct.

robobun and others added 8 commits May 5, 2026 05:04
Fixes #29082.

Before: cells containing \n landed a literal newline in the middle of
the row, breaking the table border:

    $ bun -e 'console.table([{ foo: 123, bar: "Hello\nWorld"}])'
    ┌───┬─────┬────────────┐
    │   │ foo │ bar        │
    ├───┼─────┼────────────┤
    │ 0 │ 123 │ Hello
    World │
    └───┴─────┴────────────┘

After: strings containing \n, \r, or \t are rendered in the quoted
JSON-escaped form (matching Node.js), so the row stays on one line:

    ┌───┬─────┬────────────────┐
    │   │ foo │ bar            │
    ├───┼─────┼────────────────┤
    │ 0 │ 123 │ "Hello\nWorld" │
    └───┴─────┴────────────────┘

TablePrinter.printRow / getWidthForValue previously set
quote_strings = false unconditionally for string cells. Bun's stylistic
choice is to print plain strings unquoted — that's fine for ordinary
strings, but raw control characters break the fixed-width layout because
the cell's visible width no longer matches what the writer emits.
Promote to the quoted form only when the cell string contains a
layout-breaking control character; plain strings still render without
quotes.
- trim multi-line bug history to a single issue reference
- move exitCode assertion out of runTable so callers check
  stdout first, matching Bun's test convention
The prior commit accidentally reverted src/bun.js/ConsoleObject.zig
while cleaning up the test file — restore shouldQuoteStringCell and
both of its call sites, and broaden the check from just \n/\r/\t
to every C0 control character (0x00–0x1F). \v and \f move the
cursor in real terminals the same way \n does; \0 and the rest
are counted as zero visible width but emitted as literal bytes,
which still mismatches the column width calculation.

Test changes:
- drain stderr in runTable so a future caller emitting >64KB
  of stderr doesn't deadlock on the pipe buffer
- describe.concurrent so the 10 subprocess spawns run in parallel
- drop the tautological dataRows.length==2 assertion (it was true
  in both the fixed and unfixed states — a leaked \n splits one
  row into two lines but only the first starts with the │ border)
- add a coverage case for \v, \f, and NUL
Three fixes from review:

1. Exclude 0x1B (ESC) from the C0 range check. Before: chalk.red('FAIL')
   output was JSON-escaped as '\u001b[31mFAIL\u001b[0m', destroying
   terminal colors and massively oversizing the column. ANSI sequences
   are already stripped from visible-width measurement by
   VisibleCharacterCounter (exclude_ansi_colors), so raw ESC and the
   width calculation agree — same rationale as 0x7F. Add a regression
   test for chalk-style output.

2. Avoid calling shouldQuoteStringCell twice per cell in printRow. The
   helper does bun.String.fromJS + a byte scan, and was running once
   inside getWidthForValue and again directly. Split into
   getWidthForValueWithTag (takes the already-decided flag) with a thin
   wrapper that keeps the old signature for updateColumnsForRow.

3. Add a positive toContain assertion to the C0 control-char test —
   it previously only had a negative not.toMatch which would pass even
   if the cell value were silently dropped.
Addresses review note about the index column (column 0) using the old
unprotected path: width was measured via visibleWidthExcludeANSIColors
(counts \n as zero width) and output via writer.print({f}), which
emits raw bytes. console.table({ ['a\nb']: 1 }) still produced a
literal newline in the index column after the initial fix, breaking
the row border in exactly the same way as the original #29082 bug
did for data cells.

Extract the shared C0 control-char scan into stringHasLayoutBreakingControlChar
(bun.String) and reuse it in three new helpers:
- rowKeyWidth: width of a RowKey, accounting for JSON-quoted form
- jsonQuotedStringWidth: width of a bun.String when rendered via
  writeJSONString, measured through VisibleCharacterCounter so it
  matches the cell-width measurement path
- writeRowKey: render a RowKey, calling writeJSONString for string
  keys with layout-breaking chars and falling back to raw print
  otherwise

updateColumnsForRow and printRow now route the index column through
these helpers. Add a regression test for the object-key case.
Same pattern as the data-cell dedup from the previous commit: printRow
was calling rowKeyWidth + writeRowKey, each of which independently
scanned the bun.String for layout-breaking control chars. Split into
rowKeyWithQuote / writeRowKeyWithQuote variants that take the flag
from the caller, plus thin wrappers that resolve it internally for
the first-pass width computation in updateColumnsForRow. Also
extracted the UTF-8 / UTF-16 writeJSONString dispatch into a shared
writeQuotedBunString helper since both jsonQuotedStringWidth and
writeRowKeyWithQuote need it.
@robobun
robobun force-pushed the farm/29b1cc9e/console-table-newline-escape branch from ecdf328 to 49b78a4 Compare May 5, 2026 05:06

@claude claude Bot left a comment

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.

All prior feedback has been addressed and I didn't find anything new, but the final Zig changes are non-trivial (~140 LOC of new TablePrinter helpers, including the UTF-16 @ptrCast path in writeQuotedBunString), so this is worth a human pass before merge.

Extended reasoning...

Overview

This PR fixes #29082 by promoting console.table string cells (and index-column keys) that contain C0 control characters to quoted/JSON-escaped form so the table stays rectangular. It touches src/jsc/ConsoleObject.zig (~140 net new lines across TablePrinter: shouldQuoteStringCell, stringHasLayoutBreakingControlChar, getWidthForValueWithTag, rowKeyWidth[WithQuote], jsonQuotedStringWidth, writeQuotedBunString, writeRowKeyWithQuote) and adds a 12-test regression suite at test/regression/issue/29082.test.ts.

Security risks

None. This is purely output-formatting logic for console.table; no auth, crypto, parsing of untrusted input into privileged state, or filesystem/network access. The only pointer-level operation is a @ptrCast of a []const u16 slice to [*]const u8 for writeJSONString(.utf16), which is a read-only reinterpretation with an explicitly computed length (len * 2).

Level of scrutiny

Medium. console.table is a debug utility, not a hot or security-critical path, so the blast radius of a regression is cosmetic. However, the change is not mechanical: it introduces seven new helpers, restructures the width/render flow for both data cells and the index column, makes a deliberate design carve-out for ESC (0x1B) to preserve ANSI colors, and adds a UTF-16 byte-reinterpretation branch. These are the kinds of changes that benefit from a quick human read of the Zig, particularly writeQuotedBunString and the width/render symmetry between getWidthForValueWithTag and rowKeyWidthWithQuote.

Other factors

The PR went through five rounds of bot review and the author addressed every point: stderr draining, exit-code assertion ordering, describe.concurrent, an accidental revert of the Zig fix, the ESC/ANSI regression, double-scan dedup for both data cells and row keys, missing positive assertions, and extending the fix to the index column. One pre-existing gap (column header names with control chars) was explicitly and reasonably scoped out for a follow-up. CI failures reported by robobun (webview-chrome.test.ts, fetch.upgrade.test.ts) are unrelated to this change. Given the accumulated complexity and the number of iterations it took to converge, I'm deferring rather than auto-approving so a human can confirm the final shape of the Zig helpers.

Comment thread test/regression/issue/29082.test.ts Outdated
robobun and others added 2 commits May 5, 2026 07:36
Per the repo convention (test/CLAUDE.md, root CLAUDE.md), test/regression/issue/N.test.ts
is reserved for true regressions — behavior that worked in a previous release
and then broke. console.table never escaped control characters before this
PR (quote_strings was unconditionally false for string cells), so this is
never-correct behavior, not a regression, and belongs in the module's
existing feature test file.

Append the 12 cases as a new describe.concurrent block in
test/js/bun/console/console-table.test.ts, reusing that file's existing
runTable subprocess helper so subprocess startup stays parallelized. Keep
the discriminating assertRectangular + toContain pattern — they pinpoint
the escaping regression without depending on snapshot diffs.
@yus-ham

yus-ham commented May 24, 2026

Copy link
Copy Markdown

bang @Jarred-Sumner dkk, naikin ini dong

@robobun

robobun commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by #32224, which applies the same control-character escaping in the current Rust `TablePrinter` (this PR targets `src/jsc/ConsoleObject.zig`, which was removed when the runtime was ported to Rust). #32224 also covers the ANSI case from #32223 and carries a regression test for the newline/tab cases from #29082.

@robobun

robobun commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator Author

Closing: this PR's implementation lives entirely in Zig source files that have since been removed from the tree as part of the Rust migration. The change can no longer merge cleanly and the files it edits no longer exist on main.

If the underlying issue is still present, it will need a fresh fix against the Rust implementation.

@robobun robobun closed this Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Console.table not respecting multiline strings

2 participants