Skip to content

fix: sort query parameter names by UTF-16 code unit#130

Merged
OmarAlJarrah merged 2 commits into
mainfrom
a2-sort-order
Jul 19, 2026
Merged

fix: sort query parameter names by UTF-16 code unit#130
OmarAlJarrah merged 2 commits into
mainfrom
a2-sort-order

Conversation

@OmarAlJarrah

Copy link
Copy Markdown
Member

Summary

  • QueryParametersBuilder.sort() combined UTF-16 surrogate pairs into code points before comparing parameter names, so every supplementary-plane name (any character above U+FFFF) sorted after every BMP name.
  • The WHATWG URL spec defines URLSearchParams.sort() over raw UTF-16 code units, not code points, and under code-unit order a supplementary name's leading surrogate can sort below a BMP character, reversing that relative order.
  • Switched the comparator to plain String.compareTo (no surrogate decoding) and updated the SPEC.md [QUERY-18] wording to match; removed the now-unused code-point comparison helper.

Test plan

  • Added a regression test using the real WPT urlsearchparams-sort vector cited in the issue (U+FB03 vs U+1F308 🌈), confirmed order reverses from code-point order.
  • Added the issue's own reproduction (U+1F600 😀 vs U+FFFF ) by updating the existing test that had encoded the old (incorrect) code-point-order expectation.
  • Confirmed both new/updated tests fail against the pre-fix comparator, then pass after the fix.
  • ./gradlew :kuri:jvmTest :kuri:ktlintCheck :kuri:detekt
  • ./gradlew :kuri:jsNodeTest (commonMain touched)
  • ./gradlew :kuri:macosArm64Test (native target compiles and passes)
  • ./gradlew :kuri:apiCheck — not runnable in this environment (androidApiBuild fails on missing ANDROID_HOME; confirmed this is pre-existing on origin/main too, unrelated to this change). No public API changed (sort() signature is unchanged; only a private helper was removed), so no apiDump regeneration is needed.

Closes #87

QueryParametersBuilder.sort() combined surrogate pairs into code points
before comparing names, so every supplementary-plane character sorted
after every BMP character. The WHATWG URL spec defines
URLSearchParams.sort() over raw UTF-16 code units instead, where a
supplementary name's leading surrogate can sort below a BMP character
and reverse that ordering. Compare with plain String.compareTo to match
observed browser/Node behavior, and add the WPT urlsearchparams-sort
ligature/rainbow vector plus the code-unit reproduction as regression
tests.

Closes #87
CONF-103 in the §13 conformance list still described sort() as
code-point (surrogate-aware) ordering, the exact behavior QUERY-18 was
just corrected away from. Update CONF-103 and its Appendix A index row
to state the same UTF-16 code-unit order as QUERY-18, and refresh the
three sort() test comments that still described the removed manual
code-point scan.
@OmarAlJarrah
OmarAlJarrah merged commit 0604b01 into main Jul 19, 2026
12 checks passed
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.

kuri: QueryParametersBuilder.sort() uses code-point order, not the WHATWG-mandated UTF-16 code-unit order

1 participant