Skip to content

Conversation

@webbeef
Copy link
Contributor

@webbeef webbeef commented Nov 10, 2025

This implements character set restrictions both for the DOM API and when getting cookies from http/ws headers. This is a local workaround for rwf2/cookie-rs#243

We still fail some tests because hyper errors out when parsing headers with %x1 characters.

This patch also makes a minor change to 'ServoCookie::from_cookie_string()' to avoid some string cloning when possible.

Testing: wpt tests expectations are updated

This implements character set restrictions both for the DOM API
and when getting cookies from http/ws headers. This is a local
workaround for rwf2/cookie-rs#243

We still fail some tests because hyper errors out when parsing
headers with %x1 characters.

This patch also makes a minor change to 'ServoCookie::from_cookie_string()' to
avoid some string cloning when possible.

Signed-off-by: webbeef <me@webbeef.org>
@webbeef webbeef requested a review from gterzian as a code owner November 10, 2025 22:18
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Nov 10, 2025
Copy link
Member

@yezhizhen yezhizhen left a comment

Choose a reason for hiding this comment

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

Thank you hero.

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Nov 10, 2025
@yezhizhen yezhizhen added the T-linux-wpt Do a try run of the WPT label Nov 10, 2025
@github-actions github-actions bot removed the T-linux-wpt Do a try run of the WPT label Nov 10, 2025
@github-actions
Copy link

🔨 Triggering try run (#19249177817) for Linux (WPT)

@github-actions
Copy link

Test results for linux-wpt from try job (#19249177817):

Flaky unexpected result (35)
  • OK /IndexedDB/idbfactory_open.any.html
    • FAIL [expected PASS] subtest: Calling open() with version argument 1.5 should not throw.

      assert_equals: version expected 1 but got 9007199254740991
      

  • OK /_mozilla/mozilla/getBoundingClientRect.html (#39668)
    • FAIL [expected PASS] subtest: getBoundingClientRect 1

      assert_equals: expected 62 but got 60.35
      

  • OK /_mozilla/webxr/create_session.https.html
    • FAIL [expected PASS] subtest: create_session

      can't access property "simulateDeviceConnection", navigator.xr.test is undefined
      

  • OK /_mozilla/webxr/obtain_frame.https.html
    • FAIL [expected PASS] subtest: obtain_frame

      promise_test: Unhandled rejection with value: object "TypeError: can't access property "simulateDeviceConnection", navigator.xr.test is undefined"
      

  • ERROR [expected TIMEOUT] /_mozilla/webxr/sessionavailable.https.html
  • TIMEOUT [expected OK] /_webgl/conformance/canvas/canvas-zero-size.html
  • CRASH [expected OK] /_webgl/conformance/ogles/GL/struct/struct_025_to_032.html
  • TIMEOUT [expected OK] /credential-management/credentialscontainer-frame-basics.https.html (#39430)
    • TIMEOUT [expected FAIL] subtest: navigator.credentials should be undefined in documents generated from data: URLs.

      Test timed out
      

  • CRASH [expected OK] /credential-management/idlharness.https.window.html
  • OK /css/css-cascade/layer-font-face-override.html (#35935)
    • FAIL [expected PASS] subtest: @font-face override update with appended sheet 1

      assert_equals: expected "80px" but got "38.3166666666667px"
      

    • FAIL [expected PASS] subtest: @font-face override update with appended sheet 2

      assert_equals: expected "80px" but got "38.3166666666667px"
      

  • OK /css/css-fonts/generic-family-keywords-003.html (#38994)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(nastaliq) (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted ui-rounded (drawing text in a canvas)
  • OK /custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)
    • PASS [expected FAIL] subtest: Null value should submit nothing
    • PASS [expected FAIL] subtest: setFormValue with an empty FormData should submit nothing
    • PASS [expected FAIL] subtest: Newline normalization - \r\n in name (urlencoded)
    • PASS [expected FAIL] subtest: Newline normalization - \r\n in FormData filename (urlencoded)
  • TIMEOUT [expected FAIL] /dom/xslt/large-cdata.html (#38029)
  • TIMEOUT [expected OK] /fetch/api/redirect/redirect-keepalive.https.any.html (#32153)
    • TIMEOUT [expected PASS] subtest: [keepalive][iframe][load] mixed content redirect; setting up

      Test timed out
      

  • OK /fetch/fetch-later/permissions-policy/deferred-fetch-allowed-by-permissions-policy.https.window.html (#40478)
    • FAIL [expected PASS] subtest: Permissions policy header: "deferred-fetch=*" allows fetchLater() in the top-level document.

      assert_equals: Number of sent beacons does not match expected count: expected 1 but got 0
      

  • TIMEOUT /fetch/metadata/generated/css-images.https.sub.tentative.html
    • TIMEOUT [expected PASS] subtest: background-image sec-fetch-user

      Test timed out
      

  • OK [expected ERROR] /focus/focus-event-after-switching-iframes.sub.html (#40368)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-nosrc.html (#34819)
    • PASS [expected FAIL] subtest: link click
  • OK /html/browsers/history/the-history-interface/traverse_the_history_2.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • CRASH [expected OK] /html/browsers/windows/document-domain-nested-navigate.window.html
  • CRASH [expected OK] /html/browsers/windows/noreferrer-null-opener.html
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/update-the-rendering.html (#24145)
    • TIMEOUT [expected FAIL] subtest: "Flush autofocus candidates" should be happen before a scroll event and animation frame callbacks

      Test timed out
      

  • ERROR [expected OK] /html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html (#25046)
  • TIMEOUT [expected OK] /html/semantics/embedded-content/media-elements/src_object_blob.html (#40340)
    • TIMEOUT [expected PASS] subtest: HTMLMediaElement.srcObject blob

      Test timed out
      

  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-replace.html (#32604)
    • FAIL [expected PASS] subtest: Navigating iframe loading='lazy' before it is loaded: location.replace

      uncaught exception: Error: assert_equals: expected "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?nav" but got "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src"
      

  • TIMEOUT [expected ERROR] /html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener_base.html (#40347)
  • OK /html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.html (#33948)
    • FAIL [expected PASS] subtest: Revoking a blob URL immediately after calling import will not fail

      promise_test: Unhandled rejection with value: object "TypeError: Dynamic import failed"
      

  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • PASS [expected FAIL] subtest: Reload domComplete &gt; Original domComplete
    • PASS [expected FAIL] subtest: Reload domContentLoadedEventEnd &gt; Original domContentLoadedEventEnd
    • PASS [expected FAIL] subtest: Reload domContentLoadedEventStart &gt; Original domContentLoadedEventStart
    • PASS [expected FAIL] subtest: Reload fetchStart &gt; Original fetchStart
    • PASS [expected FAIL] subtest: Reload loadEventEnd &gt; Original loadEventEnd
    • PASS [expected FAIL] subtest: Reload loadEventStart &gt; Original loadEventStart
  • FAIL [expected PASS] /png/apng/fcTL-blend-source-nearly-transparent.html
  • ERROR /service-workers/idlharness.https.any.html (#36250)
    • PASS [expected TIMEOUT] subtest: ServiceWorkerContainer interface: operation register((TrustedScriptURL or USVString), optional RegistrationOptions)
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation enable()
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation disable()
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation setHeaderValue(ByteString)
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation getState()
  • CRASH [expected OK] /trusted-types/eval-function-constructor.html
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • PASS [expected FAIL] subtest: Navigate a frame via anchor with javascript:-urls in report-only mode.
    • PASS [expected TIMEOUT] subtest: Navigate a frame via anchor with javascript:-urls w/ default policy in report-only mode.
    • FAIL [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in enforcing mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

    • FAIL [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in report-only mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

  • CRASH [expected ERROR] /wasm/webapi/invalid-code.any.sharedworker.html
  • ERROR [expected OK] /workers/baseurl/alpha/import-in-moduleworker.html (#21315)
  • CRASH [expected OK] /workers/interfaces/WorkerGlobalScope/location/members.html
Stable unexpected results that are known to be intermittent (30)
  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.worker.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor

      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbobjectstore_getAll.any.html (#39276)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/key-conversion-exceptions.any.html (#39305)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys

      assert_throws_exactly: key conversion with throwing getter should rethrow function "() =&gt; {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • OK /IndexedDB/key-conversion-exceptions.any.worker.html (#39284)
    • FAIL [expected PASS] subtest: IDBCursor update() method with throwing/invalid keys

      assert_throws_exactly: throwing getter should rethrow during clone function "() =&gt; {
            cursor.update(value);
          }" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • FAIL [expected PASS] /_mozilla/mozilla/sslfail.html (#10760)
  • TIMEOUT [expected OK] /_mozilla/mozilla/window_resize_event.html (#36741)
    • TIMEOUT [expected PASS] subtest: Popup onresize event fires after resizeTo

      Test timed out
      

  • OK /content-security-policy/frame-ancestors/frame-ancestors-path-ignored.window.html (#36468)
    • PASS [expected FAIL] subtest: A 'frame-ancestors' CSP directive with a URL that includes a path should be ignored.
  • TIMEOUT /content-security-policy/inheritance/location-reload.html (#38983)
    • PASS [expected FAIL] subtest: location.reload() of empty iframe.
  • OK /cookies/value/value-ctl.html (#40338)
    • PASS [expected FAIL] subtest: Cookie with %x0 in value is rejected (DOM).
    • PASS [expected FAIL] subtest: Cookie with %x1 in value is rejected (DOM).
    • PASS [expected FAIL] subtest: Cookie with %x2 in value is rejected (DOM).
    • PASS [expected FAIL] subtest: Cookie with %x3 in value is rejected (DOM).
    • PASS [expected FAIL] subtest: Cookie with %x4 in value is rejected (DOM).
    • PASS [expected FAIL] subtest: Cookie with %x5 in value is rejected (DOM).
    • PASS [expected FAIL] subtest: Cookie with %x6 in value is rejected (DOM).
    • PASS [expected FAIL] subtest: Cookie with %x7 in value is rejected (DOM).
    • PASS [expected FAIL] subtest: Cookie with %x8 in value is rejected (DOM).
    • PASS [expected FAIL] subtest: Cookie with %xa in value is rejected (DOM).
    • And 22 more unexpected results...
  • OK /css/css-fonts/generic-family-keywords-001.html (#37467)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(khmer-mul)
  • OK /fetch/api/response/response-stream-with-broken-then.any.html (#35419)
    • PASS [expected FAIL] subtest: Attempt to inject {done: false, value: bye} via Object.prototype.then.
    • PASS [expected FAIL] subtest: Attempt to inject value: undefined via Object.prototype.then.
    • PASS [expected FAIL] subtest: Attempt to inject undefined via Object.prototype.then.
    • PASS [expected FAIL] subtest: Attempt to inject 8.2 via Object.prototype.then.
    • PASS [expected FAIL] subtest: intercepting arraybuffer to text conversion via Object.prototype.then should not be possible
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • PASS [expected FAIL] subtest: sec-fetch-dest
  • OK /fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)
    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Not sent to non-trustworthy same-site destination
    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Not sent to non-trustworthy cross-site destination

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /fetch/metadata/generated/element-img-environment-change.https.sub.html (#30111)
    • PASS [expected FAIL] subtest: sec-fetch-site - Cross-site, no attributes
    • FAIL [expected PASS] subtest: sec-fetch-site - Same site, no attributes

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Origin -&gt; Cross-Site -&gt; Same-Origin redirect, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-site - Cross-Site -&gt; Same Origin, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-site - Cross-Site -&gt; Cross-Site, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Origin -&gt; Same-Site, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Site -&gt; Same Origin, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Site -&gt; Cross-Site, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-mode - attributes: crossorigin
    • PASS [expected FAIL] subtest: sec-fetch-mode - attributes: crossorigin=use-credentials
    • And 2 more unexpected results...
  • OK /fetch/metadata/generated/element-img-environment-change.sub.html (#30111)
    • PASS [expected FAIL] subtest: sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-dest - Not sent to non-trustworthy cross-site destination, no attributes
  • ERROR /fetch/metadata/generated/serviceworker.https.sub.html (#36247)
    • FAIL [expected PASS] subtest: sec-fetch-site - Same origin, no options - registration

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)
    • FAIL [expected PASS] subtest: Link with onclick navigation and href navigation

      assert_equals: expected "href" but got "click"
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.html (#29049)
    • PASS [expected FAIL] subtest: Same-origin navigation started from unload handler must be ignored
  • OK /html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/a-click.html (#28697)
    • PASS [expected FAIL] subtest: aElement.click() before the load event must NOT replace
  • OK /html/browsers/history/the-history-interface/traverse_the_history_3.html (#21383)
    • FAIL [expected PASS] subtest: Multiple history traversals, last would be aborted

      assert_array_equals: Pages opened during history navigation expected property 1 to be 3 but got 1 (expected array [6, 3] got [6, 1])
      

  • OK /html/browsers/history/the-history-interface/traverse_the_history_4.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/windows/embedded-opener-remove-frame.html (#23867)
    • FAIL [expected PASS] subtest: opener of discarded auxiliary browsing context

      assert_object_equals: property "get" expected function "function opener() {
          [native code]
      }" got function "function opener() {
          [native code]
      }"
      

  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • FAIL [expected PASS] subtest: text/plain: Basic test (formdata event)

      assert_equals: expected "basic=test\r\n" but got ""
      

  • OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: Basic File test (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in value (formdata event)
  • OK [expected CRASH] /html/semantics/forms/the-fieldset-element/disabled-003.html (#31730, #39631)
  • OK /html/webappapis/user-prompts/print-during-unload.html (#35944)
    • PASS [expected FAIL] subtest: print() during unload
  • OK /preload/preload-error.sub.html (#37177)
    • PASS [expected FAIL] subtest: 404 (fetch): main
    • PASS [expected FAIL] subtest: CORS (fetch): main
  • OK /trusted-types/trusted-types-navigation.html?26-30 (#38807)
    • PASS [expected FAIL] subtest: Navigate a window via form-submission with javascript:-urls in report-only mode.
    • PASS [expected FAIL] subtest: Navigate a frame via form-submission with javascript:-urls in enforcing mode.
  • TIMEOUT /trusted-types/trusted-types-navigation.html?31-35 (#38034)
    • TIMEOUT [expected FAIL] subtest: Navigate a frame via form-submission with javascript:-urls in report-only mode.

      Test timed out
      

    • NOTRUN [expected TIMEOUT] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in report-only mode.

@github-actions
Copy link

✨ Try run (#19249177817) succeeded.

@yezhizhen yezhizhen added this pull request to the merge queue Nov 11, 2025
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Nov 11, 2025
Merged via the queue into servo:main with commit 29bfb3a Nov 11, 2025
74 checks passed
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Nov 11, 2025
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.

3 participants