Skip to content

fix(runtime): stringify ArrayBuffer views with object tags - #10966

Closed
proggeramlug wants to merge 3 commits into
PerryTS:mainfrom
proggeramlug:fix/10927-arraybuffer-string
Closed

proggeramlug wants to merge 3 commits into
PerryTS:mainfrom
proggeramlug:fix/10927-arraybuffer-string

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #10927.

js_jsvalue_to_string treated every registered BufferHeader as a Node Buffer and decoded its bytes. ArrayBuffer, SharedArrayBuffer, and DataView use that storage too, but inherit Object.prototype.toString. Route those three through the existing object-tag implementation before any GC-header probe. Apply the same distinction in the argument-bearing toString helpers so .toString("hex") cannot decode their bytes.

The regression fixture covers String(value), template interpolation, .toString(), and .toString("hex") for all three views, plus Node Buffer decoding. Against the pre-fix compiler, the fixture prints "hi" for each view; pinned Node 26.5.1 prints their object tags.

Validation: cargo fmt --all --check; ./scripts/check_file_size.sh; python3 scripts/check_test_registration.py; cargo test -p perry-runtime --lib array_buffer_backed_values_use_their_object_tags -- --test-threads=1 (passed). The new fixture was compiled and run with this branch’s release compiler and runtime archive on an isolated perrymaster checkout; its output matched pinned Node 26.5.1 byte for byte. The pre-fix compiler rendered "hi" for all three views.

Summary by CodeRabbit

  • Bug Fixes
    • Corrected string conversion for ArrayBuffer, SharedArrayBuffer, and DataView values to return their standard object tags.
    • Ensured template interpolation and .toString() produce consistent results for these values.
    • Preserved byte decoding behavior for Node.js Buffer instances, including hexadecimal conversion.

CI note: the lint job on the initial push also failed benchmarks/ci_public_baseline_check.py with a public artifact source-fingerprint mismatch. This PR changes none of SOURCE_PATHS or the artifact in benchmarks/public_baseline.py; the same mismatch is present at its upstream/main base. The new file-size violation from the first push has been fixed, and the file-size gate passes locally.

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 704598aa-b92d-4d2c-80e4-9e9be79735d6

📥 Commits

Reviewing files that changed from the base of the PR and between eb84d76 and b01576c.

📒 Files selected for processing (3)
  • crates/perry-runtime/src/value/mod.rs
  • crates/perry-runtime/src/value/to_string.rs
  • crates/perry-runtime/src/value/to_string_buffer_tests.rs

Included review availability: Your plan provides up to 8 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

ArrayBuffer, SharedArrayBuffer, and DataView string conversion now returns branded object tags. Byte-indexed Buffer values still decode their contents. Runtime tests, an integration test, and a changelog entry cover the behavior.

Changes

Buffer string conversion

Layer / File(s) Summary
Runtime routing and validation
crates/perry-runtime/src/buffer/encode.rs, crates/perry-runtime/src/value/to_string.rs, crates/perry-runtime/src/value/mod.rs, crates/perry-runtime/src/value/to_string_buffer_tests.rs
String conversion dispatch recognizes byte-indexed buffers and preserves byte decoding for Buffer. Runtime tests verify branded object tags for ArrayBuffer, SharedArrayBuffer, and DataView, plus plain and hexadecimal Buffer conversion.
Integration regression coverage
test-files/test_gap_10927_arraybuffer_string.ts, changelog.d/10966-arraybuffer-string.md
The integration test covers String(), template interpolation, .toString(), and encoded conversion. The changelog records the corrected behavior.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to b0157

This change corrects string conversion for ArrayBuffer-backed values while preserving Buffer decoding. No actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Issue #10927 requires object-tag conversion for ArrayBuffer and SharedArrayBuffer, matching template interpolation, and unchanged Node Buffer decoding. js_value_to_string_with_encoding and its…
Out of Scope Changes check ✅ Passed The changes stay within issue #10927. DataView uses the same non-byte-indexed buffer classification and prevents the same incorrect byte decoding. The argument-bearing dispatch update supports the r…
Title check ✅ Passed The title clearly and concisely describes the main runtime change: stringifying ArrayBuffer views with object tags.
Description check ✅ Passed The description explains the bug, implementation, affected values, regression coverage, related issue, validation commands, and CI context. It does not reproduce the template headings or checklist, bu…
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Landed on main in merge train 256 (#11018, v0.5.1638), main f5cfbff882.

Carried at head b01576c60d. The landed tree is byte-identical to the validated train tree (9b108dd3c9), and CI on the train head passed every job except the known public-baseline lint step: all 6 gap shards, cargo-test, e2e-scoped, gc-stress, check, warnings and security-audit green.

Trains rebase-merge, so commits get new SHAs and GitHub cannot mark this PR merged. Closed as landed.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

String(arrayBuffer) returns the buffer bytes instead of [object ArrayBuffer] (also SharedArrayBuffer)

1 participant