Skip to content

URLParser: do not re-parse a String::MaxLength input under ASSERT_ENABLED - #621

Open
robobun wants to merge 1 commit into
mainfrom
robobun/a49693d9/urlparser-maxlength-assert
Open

URLParser: do not re-parse a String::MaxLength input under ASSERT_ENABLED#621
robobun wants to merge 1 commit into
mainfrom
robobun/a49693d9/urlparser-maxlength-assert

Conversation

@robobun

@robobun robobun commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Problem

  • A WTF::URL built from a string of exactly String::MaxLength (2147483647) characters aborts the process in a build with assertions on. Release builds are not affected. In Bun, new URL(s) and new WebSocket(s) with such a string exit 134 on a debug build and throw on a release build.
  • The cause is the URLParser constructor (Source/WTF/wtf/URLParser.cpp:1572). After a parse that saw no syntax violation it re-parses makeString(' ', inputString) and compares the two results. tryMakeString sums the adapter lengths into a CheckedInt32, so 1 + 2147483647 overflows and it returns a null String. makeString then calls CRASH().
#4  WTF::makeString (...) at Source/WTF/wtf/text/MakeString.h:105
#5  WTF::URLParser::URLParser (this=..., result=..., input=..., base=..., nonUTF8QueryEncoding=0x0)
    at Source/WTF/wtf/URLParser.cpp:1572

Fix

  • Build the string with tryMakeString and skip the check when it returns a null String. Every shorter input still gets the second parse.
  • Correct because the re-parse only exists to compare two parses of the same URL. An input with no room for a leading space cannot be given one, so there is nothing to compare. There is no other way to force the syntax violation, because forcing it is what adds the character.
  • The branch sits directly on dfd696443b, the commit Bun pins, so the preview build differs from the pin by this change only.

Verification

  • Source/WTF/wtf/URLParser.cpp compiles with the flags from the pinned build's compile_commands.json (clang++-21 -std=c++23 -fsyntax-only, ASSERT_ENABLED on).
  • End to end in Bun, debug build, against this PR's preview build (autobuild-preview-pr-621-b620d880):
const s = "a".repeat(2147483647);
new URL(s);                 // before: exit 134 (SIGABRT).  after: throws TypeError
new WebSocket(s);           // before: exit 134 (SIGABRT).  after: throws SyntaxError
  • test/js/web/url/ on the same build: 138 pass, 16 skip, 0 fail.
  • The check still runs for every shorter input. On the preview build, a breakpoint on URLParser::allValuesEqual is hit
    3 times for one new URL("https://example.com/a?b#c").
  • No Bun-side regression test comes with this. The only input that reaches the bug is a 2 GB string, and one new URL() call on it takes 5m54s and 2.4 GB of RSS in a debug build.

Notes

…BLED

After a parse that saw no syntax violation, the URLParser constructor
re-parses makeString(' ', inputString) and compares the two results. For
an input that is already String::MaxLength (2147483647) characters long
the length sum overflows int32_t, tryMakeString returns a null String,
and makeString calls CRASH(). Every WTF::URL built from a maximum length
string then aborts the process in a build with assertions on.

Build the string with tryMakeString and skip the check when it returns
a null String.

@claude claude 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.

LGTM — small, debug-only fix that swaps makeString for tryMakeString and skips the self-check when allocation fails.

What was reviewed:

  • Confirmed the change is entirely inside the #if ASSERT_ENABLED block; release behavior is unchanged.
  • Verified tryMakeString is in scope (<wtf/text/MakeString.h> is already included and it is exported into the global namespace) and that WTF::move is defined in StdLibExtras.h and accepts the lvalue here.
  • Checked that all shorter inputs still take the identical re-parse-and-compare path as before; only the null-result case is newly skipped.
Extended reasoning...

Overview

The PR touches a single file, Source/WTF/wtf/URLParser.cpp, and only the #if ASSERT_ENABLED self-check block inside the URLParser constructor. Previously, after a parse with no syntax violation the constructor called makeString(' ', inputString) to force a syntax violation and re-parse for comparison. When inputString is exactly String::MaxLength characters, the length sum overflows the CheckedInt32 inside tryMakeStringFromAdapters, tryMakeString returns null, and makeString calls CRASH(). The fix builds the string with tryMakeString directly, skips the comparison when it returns null, and moves the resulting string into the nested parser instead of copying.

Security risks

None. The modified code is compiled only when ASSERT_ENABLED is set, so release builds are byte-for-byte unaffected. The change strictly narrows the behavior of a debug self-check (skip instead of abort) for one degenerate input length; no parsing, canonicalization, or output logic changes. There is no new untrusted input handling, no auth/crypto/permission surface.

Level of scrutiny

Low. This is a 10-line, mechanical change in a debug-only assertion path with clear intent. I confirmed tryMakeString is already available via the existing #include <wtf/text/MakeString.h> (and exported with using WTF::tryMakeString;), and that WTF::move is the codebase's std::move wrapper in wtf/StdLibExtras.h whose is_lvalue_reference static_assert is satisfied by the named local. The nested URLParser constructor takes String&&, so the move matches the previous rvalue-temporary binding. For every input shorter than String::MaxLength, tryMakeString returns a non-null string and the re-parse-and-compare check runs exactly as before.

Other factors

No CODEOWNERS entry covers Source/WTF/wtf/URLParser.cpp. There are no prior reviews or outstanding objections on the PR. The bug hunter exited on dry_streak with no findings and no ruled-out candidates. The PR description's reasoning (overflow in CheckedInt32 → null → CRASH() in makeString) matches the implementation in MakeString.h.

@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Essentials

Run ID: 3b58ba02-8924-4a84-bd46-9018b79e3ad9

📥 Commits

Reviewing files that changed from the base of the PR and between 4b9ff99 and b620d88.

📒 Files selected for processing (1)
  • Source/WTF/wtf/URLParser.cpp

Included review availability: Your plan provides up to 5 included reviews per hour; 1 remains after this review.


Walkthrough

Changes

URL parser equivalence check

Layer / File(s) Summary
Fallible test input handling
Source/WTF/wtf/URLParser.cpp
The debug check uses tryMakeString for the leading-space input and skips parsing when allocation fails.

Merge Risk: ⚪ Minimal · up to b620d

Maximum-length URL inputs now avoid the assertion abort while shorter inputs retain the equivalence check. No actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description check ✅ Passed The description clearly explains the problem, root cause, fix, scope, and verification results. It does not include the template's Bugzilla link, review line, or explicit changed-file/function list, b…
Title check ✅ Passed The title clearly and concisely identifies the URLParser change and the String::MaxLength assertion-enabled failure it prevents.

Warning

Git: CodeRabbit could not clone the repository, so clone-backed analysis was skipped and this review may be incomplete. Verify repository clone access, such as SSH credentials, before requesting another full review. If clone access is intentionally unavailable, use path_filters to narrow the review scope.


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

@github-actions

Copy link
Copy Markdown

Preview Builds

Commit Release Date
b620d880 autobuild-preview-pr-621-b620d880 2026-09-10 17:20:11 UTC

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