Skip to content

fix(runtime): guard URLSearchParams shape probe against non-object receivers (Date.toString segv)#5997

Merged
proggeramlug merged 1 commit into
mainfrom
fix/t262-regr-date-tostring-segv
Jul 4, 2026
Merged

fix(runtime): guard URLSearchParams shape probe against non-object receivers (Date.toString segv)#5997
proggeramlug merged 1 commit into
mainfrom
fix/t262-regr-date-tostring-segv

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Problem

language/expressions/addition/S11.6.1_A2.2_T2.js regressed to a segfault (SIGSEGV, "no output") after #5964.

#5964 made native URLSearchParams methods reachable through dynamic access by probing the receiver in js_native_call_method for append/set/get/has/delete/toString. The probe masks the receiver bits into an *ObjectHeader and calls shape_is_url_search_params, which reads class_id / keys_array / length at ObjectHeader offsets.

But the receiver can be any pointer-tagged value. A Date value is a pointer to a GC_TYPE_DATE_CELL, whose bytes at those offsets are unrelated. Reading keys_array as a pointer and dereferencing its length faulted — so the test's date.toString() + date.toString() (two toString calls, each firing the probe) crashed.

Fix

Gate shape_is_url_search_params on the GC header type: proceed only when the allocation is GC_TYPE_OBJECT. A Date cell, array, buffer, closure, etc. now returns false immediately instead of reading ObjectHeader fields off a foreign layout. This protects every caller of the shared probe, not just the new toString arm — mirroring the is_plain_matcher_object GC-header check already used elsewhere.

Verification

Built on an internal Linux sweep host:

  • language/expressions/addition/S11.6.1_A2.2_T2.js passes (was SIGSEGV).
  • date.toString() + date.toString() no longer segfaults.
  • URLSearchParams dynamic get / toString / size still work (no regression to fix(runtime): #5961 — URLSearchParams methods reachable through dynamic access #5964's fix).
  • language/expressions/addition slice is clean; remaining built-ins/Date runtime-fails are pre-existing unrelated gaps (toTemporalInstant, MakeTime precision, etc.).

Refs #5961. Code-only (no version/changelog).

Summary by CodeRabbit

  • Bug Fixes
    • Improved safety when handling URL search parameters so invalid or non-object internal values are no longer misidentified.
    • Prevents crashes or incorrect behavior from type-erased/native method checks on unusual pointer-tagged inputs.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@proggeramlug, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 31 seconds

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d892c9f3-3148-4665-bf30-c980fa812537

📥 Commits

Reviewing files that changed from the base of the PR and between c2784c9 and 0963635.

📒 Files selected for processing (1)
  • crates/perry-runtime/src/url/search_params.rs
📝 Walkthrough

Walkthrough

The shape_is_url_search_params function was updated to add a safety check before performing existing type verification. It now confirms the pointer is large enough to contain a GC header and that the header's obj_type equals GC_TYPE_OBJECT prior to checking class_id and the _entries key.

Changes

Shape Detection Hardening

Layer / File(s) Summary
GC header validation guard
crates/perry-runtime/src/url/search_params.rs
Adds a pointer-size check and GC header obj_type verification (must equal GC_TYPE_OBJECT) before the existing class_id/_entries key checks in shape_is_url_search_params.

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

Possibly related PRs

  • PerryTS/perry#5108: Coercion logic uses try_read_as_search_params, which relies on the same shape_is_url_search_params detector hardened here.
  • PerryTS/perry#5650: Similarly adds a GC-type guard before reading a GcHeader in a different brand-probing function to prevent misclassification.
  • PerryTS/perry#5964: Also modifies search_params.rs and tightens usage of shape_is_url_search_params for correct native object dispatch.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the runtime fix for guarding URLSearchParams probing against non-object receivers.
Description check ✅ Passed The description covers the problem, fix, related issue, and verification, which satisfies the template's required information overall.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/t262-regr-date-tostring-segv

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/perry-runtime/src/url/search_params.rs`:
- Around line 830-837: Update shape_is_url_search_params to reject non-object
receivers before any GC-header dereference: the current guard only checks the
object pointer against GC_HEADER_SIZE, but this probe can be called with
type-erased receivers like registered buffers. Add the same raw-receiver
validation used elsewhere (the raw < 0x10000 and is_registered_buffer(raw)
check) before computing gc_header or reading obj_type, so non-object cells are
filtered out safely.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ab346e3c-bfb4-40e2-8891-40185fdc3847

📥 Commits

Reviewing files that changed from the base of the PR and between 95e4817 and c2784c9.

📒 Files selected for processing (1)
  • crates/perry-runtime/src/url/search_params.rs

Comment thread crates/perry-runtime/src/url/search_params.rs Outdated
…ceivers

PR #5964 made native URLSearchParams methods reachable through dynamic access
by probing the receiver in js_native_call_method for the method names
append/set/get/has/delete/toString. That probe masks the receiver bits into
an *ObjectHeader and calls shape_is_url_search_params, which reads class_id /
keys_array / length at ObjectHeader offsets.

But the receiver may be any pointer-tagged value, not an ordinary object. A
Date value is a pointer to a GC_TYPE_DATE_CELL, whose bytes at those offsets
are garbage. Reading keys_array as a pointer and dereferencing its length
segfaulted -- so any two Date.toString() calls (the probe fires on toString)
crashed:

  language/expressions/addition/S11.6.1_A2.2_T2.js

(the test does date.toString() + date.toString()).

Gate shape_is_url_search_params on the GC header type: only proceed when the
allocation is GC_TYPE_OBJECT. A Date cell (GC_TYPE_DATE_CELL), array, buffer,
closure, etc. now returns false immediately instead of reading ObjectHeader
fields off a foreign layout. This protects every caller of the shared probe,
not just the new toString arm.

Verified on an internal Linux sweep host: the addition test passes,
Date.toString()+Date.toString() no longer segfaults, and URLSearchParams
dynamic get/toString/size still work. The addition slice is clean; the
remaining Date runtime-fails are pre-existing unrelated gaps.

Refs #5961
@proggeramlug proggeramlug force-pushed the fix/t262-regr-date-tostring-segv branch from c2784c9 to 0963635 Compare July 4, 2026 20:37
@proggeramlug proggeramlug merged commit 3e218be into main Jul 4, 2026
16 of 17 checks passed
@proggeramlug proggeramlug deleted the fix/t262-regr-date-tostring-segv branch July 4, 2026 20:48
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.

1 participant