Skip to content

Commit

Permalink
Remove fragment identifiers from script url and scope url (#1251)
Browse files Browse the repository at this point in the history
The spec and the implementations did not agree on the behavior: the spec
didn't remove fragment identifiers and had ServiceWorker.scriptURL and
ServiceWorkerRegistration.scope return urls without stripping them.
Chrome, Firefox, and Edge don't return fragments.

This changes the spec to remove the fragment indentifiers from the
script url and scope url given to register() and getRegistration()
before storing them, in order to match the implementations.

Fixes #1249.
  • Loading branch information
jungkees authored Dec 22, 2017
1 parent 502d020 commit 58fd467
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
23 changes: 16 additions & 7 deletions docs/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. Let |client| be the <a>context object</a>'s [=ServiceWorkerContainer/service worker client=].
1. Let |clientURL| be the result of <a lt="URL parser">parsing</a> |clientURL| with the <a>context object</a>'s <a>relevant settings object</a>'s <a>API base URL</a>.
1. If |clientURL| is failure, return a <a>promise</a> rejected with a <code>TypeError</code>.
1. Set |clientURL|'s [=url/fragment=] to null.
1. If the [=environment settings object/origin=] of |clientURL| is not |client|'s [=environment settings object/origin=], return a |promise| rejected with a "{{SecurityError}}" {{DOMException}}.
1. Let |promise| be a new <a>promise</a>.
1. Run the following substeps <a>in parallel</a>:
Expand Down Expand Up @@ -2303,13 +2304,21 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
:: none

1. If |scriptURL| is failure, reject |promise| with a <code>TypeError</code> and abort these steps.
1. Set |scriptURL|'s [=url/fragment=] to null.

Note: The user agent does not store the [=url/fragment=] of the script's url. This means that the [=url/fragment=] does not have an effect on identifying [=/service workers=].

1. If |scriptURL|'s [=url/scheme=] is not one of "<code>http</code>" and "<code>https</code>", reject |promise| with a <code>TypeError</code> and abort these steps.
1. If any of the strings in |scriptURL|'s [=url/path=] contains either <a>ASCII case-insensitive</a> "<code>%2f</code>" or <a>ASCII case-insensitive</a> "<code>%5c</code>", reject |promise| with a <code>TypeError</code> and abort these steps.
1. If |scopeURL| is null, set |scopeURL| to the result of <a lt="URL parser">parsing</a> the string "<code>./</code>" with |scriptURL|.

Note: The scope url for the registration is set to the location of the service worker script by default.

1. If |scopeURL| is failure, reject |promise| with a <code>TypeError</code> and abort these steps.
1. Set |scopeURL|'s [=url/fragment=] to null.

Note: The user agent does not store the [=url/fragment=] of the scope url. This means that the [=url/fragment=] does not have an effect on identifying [=/service worker registrations=].

1. If |scopeURL|'s [=url/scheme=] is not one of "<code>http</code>" and "<code>https</code>", reject |promise| with a <code>TypeError</code> and abort these steps.
1. If any of the strings in |scopeURL|'s [=url/path=] contains either <a>ASCII case-insensitive</a> "<code>%2f</code>" or <a>ASCII case-insensitive</a> "<code>%5c</code>", reject |promise| with a <code>TypeError</code> and abort these steps.
1. Let |job| be the result of running [=Create Job=] with *register*, |scopeURL|, |scriptURL|, |promise|, and |client|.
Expand Down Expand Up @@ -2340,7 +2349,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. If |registration| is not null, then:
1. If |registration|'s <a>uninstalling flag</a> is set, unset it.
1. Let |newestWorker| be the result of running the <a>Get Newest Worker</a> algorithm passing |registration| as the argument.
1. If |newestWorker| is not null, |job|'s [=job/script url=] [=url/equals=] |newestWorker|'s [=service worker/script url=] with the *exclude fragments flag* set, and |job|'s [=job/update via cache mode=]'s value equals |registration|'s [=service worker registration/update via cache mode=], then:
1. If |newestWorker| is not null, |job|'s [=job/script url=] [=url/equals=] |newestWorker|'s [=service worker/script url=], and |job|'s [=job/update via cache mode=]'s value equals |registration|'s [=service worker registration/update via cache mode=], then:
1. Invoke [=Resolve Job Promise=] with |job| and |registration|.
1. Invoke <a>Finish Job</a> with |job| and abort these steps.
1. Else:
Expand All @@ -2361,7 +2370,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. Invoke [=Reject Job Promise=] with |job| and `TypeError`.
1. Invoke <a>Finish Job</a> with |job| and abort these steps.
1. Let |newestWorker| be the result of running <a>Get Newest Worker</a> algorithm passing |registration| as the argument.
1. If |job|'s <a>job type</a> is *update*, and |newestWorker|'s [=service worker/script url=] does not [=url/equal=] |job|'s [=job/script url=] with the *exclude fragments flag* set, then:
1. If |job|'s <a>job type</a> is *update*, and |newestWorker|'s [=service worker/script url=] does not [=url/equal=] |job|'s [=job/script url=], then:
1. Invoke [=Reject Job Promise=] with |job| and `TypeError`.
1. Invoke <a>Finish Job</a> with |job| and abort these steps.
1. Let |httpsState| be "<code>none</code>".
Expand Down Expand Up @@ -2430,7 +2439,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe

Else, continue the rest of these steps after the algorithm's asynchronous completion, with |script| being the asynchronous completion value.

1. If |newestWorker| is not null, |newestWorker|'s [=service worker/script url=] [=url/equals=] |job|'s [=job/script url=] with the *exclude fragments flag* set, and |script|'s [=source text=] is a byte-for-byte match with |newestWorker|'s [=script resource=]'s [=source text=], if |script| is a [=classic script=], and |script|'s [=module script/module record=]'s \[[ECMAScriptCode]] is a byte-for-byte match with |newestWorker|'s [=script resource=]'s [=module script/module record=]'s \[[ECMAScriptCode]] otherwise, then:
1. If |newestWorker| is not null, |newestWorker|'s [=service worker/script url=] [=url/equals=] |job|'s [=job/script url=], and |script|'s [=source text=] is a byte-for-byte match with |newestWorker|'s [=script resource=]'s [=source text=], if |script| is a [=classic script=], and |script|'s [=module script/module record=]'s \[[ECMAScriptCode]] is a byte-for-byte match with |newestWorker|'s [=script resource=]'s [=module script/module record=]'s \[[ECMAScriptCode]] otherwise, then:
1. Invoke [=Resolve Job Promise=] with |job| and |registration|.
1. Invoke <a>Finish Job</a> with |job| and abort these steps.
1. Else:
Expand Down Expand Up @@ -2877,7 +2886,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
:: |registration|, a [=/service worker registration=]

1. Run the following steps atomically.
1. Let |scopeString| be <a lt="URL serializer">serialized</a> |scope| with the *exclude fragment flag* set.
1. Let |scopeString| be [=URL serializer|serialized=] |scope| with the *exclude fragment flag* set.
1. Let |registration| be a new [=/service worker registration=] whose [=service worker registration/scope url=] is set to |scope| and [=service worker registration/update via cache mode=] is set to |updateViaCache|.
1. [=map/Set=] <a>scope to registration map</a>[|scopeString|] to |registration|.
1. Return |registration|.
Expand All @@ -2904,7 +2913,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. [=Terminate Service Worker|Terminate=] |registration|'s [=active worker=].
1. Run the <a>Update Worker State</a> algorithm passing |registration|'s [=active worker=] and *redundant* as the arguments.
1. Run the <a>Update Registration State</a> algorithm passing |registration|, "<code>active</code>" and null as the arguments.
1. Let |scopeString| be <a lt="URL serializer">serialized</a> |registration|'s [=service worker registration/scope url=] with the *exclude fragment flag* set.
1. Let |scopeString| be |registration|'s [=URL serializer|serialized=] [=service worker registration/scope url=].
1. [=map/Remove=] <a>scope to registration map</a>[|scopeString|].
</section>

Expand Down Expand Up @@ -3042,7 +3051,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe

1. Run the following steps atomically.
1. Let |scopeString| be the empty string.
1. If |scope| is not null, set |scopeString| to <a lt="URL serializer">serialized</a> |scope| with the *exclude fragment flag* set.
1. If |scope| is not null, set |scopeString| to [=URL serializer|serialized=] |scope| with the *exclude fragment flag* set.
1. Let |registration| be null.
1. [=map/For each=] |key| → |value| of <a>scope to registration map</a>:
1. If |scopeString| matches |key|, set |registration| to |value|.
Expand Down Expand Up @@ -3137,7 +3146,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. If |options|.{{CacheQueryOptions/ignoreSearch}} is true, then:
1. Set |cachedURL|'s [=url/query=] to the empty string.
1. Set |requestURL|'s [=url/query=] to the empty string.
1. If |cachedURL| [=url/equals=] |requestURL| with the *exclude fragments flag* set, then:
1. If |cachedURL| [=url/equals=] |requestURL| with the *exclude fragment flag* set, then:
1. Add a copy of |requestResponse|'s request to |requests|.
1. Add a copy of |requestResponse|'s response to |responses|.
1. Let |index| be zero.
Expand Down
23 changes: 16 additions & 7 deletions docs/v1/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,10 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. Let |client| be the <a>context object</a>'s [=ServiceWorkerContainer/service worker client=].
1. Let |scriptURL| be the result of <a lt="URL parser">parsing</a> |scriptURL| with the <a>context object</a>'s <a>relevant settings object</a>'s <a>API base URL</a>.
1. If |scriptURL| is failure, reject |p| with a <code>TypeError</code> and abort these steps.
1. Set |scriptURL|'s [=url/fragment=] to null.

Note: The user agent does not store the [=url/fragment=] of the script's url. This means that the [=url/fragment=] does not have an effect on identifying [=/service workers=].

1. If |scriptURL|'s [=url/scheme=] is not one of "<code>http</code>" and "<code>https</code>", reject |p| with a <code>TypeError</code> and abort these steps.
1. If any of the strings in |scriptURL|'s [=url/path=] contains either <a>ASCII case-insensitive</a> "<code>%2f</code>" or <a>ASCII case-insensitive</a> "<code>%5c</code>", reject |p| with a <code>TypeError</code> and abort these steps.
1. Let |scopeURL| be null.
Expand All @@ -615,6 +619,10 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe

1. Else, set |scopeURL| to the result of <a lt="url parser">parsing</a> |options|.{{RegistrationOptions/scope}} with the <a>context object</a>'s <a>relevant settings object</a>'s <a>API base URL</a>.
1. If |scopeURL| is failure, reject |p| with a <code>TypeError</code> and abort these steps.
1. Set |scopeURL|'s [=url/fragment=] to null.

Note: The user agent does not store the [=url/fragment=] of the scope url. This means that the [=url/fragment=] does not have an effect on identifying [=/service worker registrations=].

1. If |scopeURL|'s [=url/scheme=] is not one of "<code>http</code>" and "<code>https</code>", reject |p| with a <code>TypeError</code> and abort these steps.
1. If any of the strings in |scopeURL|'s [=url/path=] contains either <a>ASCII case-insensitive</a> "<code>%2f</code>" or <a>ASCII case-insensitive</a> "<code>%5c</code>", reject |p| with a <code>TypeError</code> and abort these steps.
1. Let |job| be the result of running <a>Create Job</a> with *register*, |scopeURL|, |scriptURL|, |p|, and |client|.
Expand All @@ -632,6 +640,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. Let |client| be the <a>context object</a>'s [=ServiceWorkerContainer/service worker client=].
1. Let |clientURL| be the result of <a lt="URL parser">parsing</a> |clientURL| with the <a>context object</a>'s <a>relevant settings object</a>'s <a>API base URL</a>.
1. If |clientURL| is failure, return a <a>promise</a> rejected with a <code>TypeError</code>.
1. Set |clientURL|'s [=url/fragment=] to null.
1. If the [=environment settings object/origin=] of |clientURL| is not |client|'s [=environment settings object/origin=], return a |promise| rejected with a "{{SecurityError}}" {{DOMException}}.
1. Let |promise| be a new <a>promise</a>.
1. Run the following substeps <a>in parallel</a>:
Expand Down Expand Up @@ -2229,7 +2238,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. If |registration| is not null, then:
1. If |registration|'s <a>uninstalling flag</a> is set, unset it.
1. Let |newestWorker| be the result of running the <a>Get Newest Worker</a> algorithm passing |registration| as the argument.
1. If |newestWorker| is not null, |job|'s [=job/script url=] [=url/equals=] |newestWorker|'s [=service worker/script url=] with the *exclude fragments flag* set, and |job|'s [=job/update via cache mode=]'s value equals |registration|'s [=service worker registration/update via cache mode=]'s value, then:
1. If |newestWorker| is not null, |job|'s [=job/script url=] [=url/equals=] |newestWorker|'s [=service worker/script url=], and |job|'s [=job/update via cache mode=]'s value equals |registration|'s [=service worker registration/update via cache mode=]'s value, then:
1. Invoke [=Resolve Job Promise=] with |job| and |registration|.
1. Invoke <a>Finish Job</a> with |job| and abort these steps.
1. Else:
Expand All @@ -2250,7 +2259,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. Invoke [=Reject Job Promise=] with |job| and `TypeError`.
1. Invoke <a>Finish Job</a> with |job| and abort these steps.
1. Let |newestWorker| be the result of running <a>Get Newest Worker</a> algorithm passing |registration| as the argument.
1. If |job|'s <a>job type</a> is *update*, and |newestWorker|'s [=service worker/script url=] does not [=url/equal=] |job|'s [=job/script url=] with the *exclude fragments flag* set, then:
1. If |job|'s <a>job type</a> is *update*, and |newestWorker|'s [=service worker/script url=] does not [=url/equal=] |job|'s [=job/script url=], then:
1. Invoke [=Reject Job Promise=] with |job| and `TypeError`.
1. Invoke <a>Finish Job</a> with |job| and abort these steps.
1. Let |httpsState| be "<code>none</code>".
Expand Down Expand Up @@ -2319,7 +2328,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe

Else, continue the rest of these steps after the algorithm's asynchronous completion, with |script| being the asynchronous completion value.

1. If |newestWorker| is not null, |newestWorker|'s [=service worker/script url=] [=url/equals=] |job|'s [=job/script url=] with the *exclude fragments flag* set, and |script|'s [=source text=] is a byte-for-byte match with |newestWorker|'s [=script resource=]'s [=source text=], if |script| is a [=classic script=], and |script|'s [=module script/module record=]'s \[[ECMAScriptCode]] is a byte-for-byte match with |newestWorker|'s [=script resource=]'s [=module script/module record=]'s \[[ECMAScriptCode]] otherwise, then:
1. If |newestWorker| is not null, |newestWorker|'s [=service worker/script url=] [=url/equals=] |job|'s [=job/script url=], and |script|'s [=source text=] is a byte-for-byte match with |newestWorker|'s [=script resource=]'s [=source text=], if |script| is a [=classic script=], and |script|'s [=module script/module record=]'s \[[ECMAScriptCode]] is a byte-for-byte match with |newestWorker|'s [=script resource=]'s [=module script/module record=]'s \[[ECMAScriptCode]] otherwise, then:
1. Invoke [=Resolve Job Promise=] with |job| and |registration|.
1. Invoke <a>Finish Job</a> with |job| and abort these steps.
1. Else:
Expand Down Expand Up @@ -2742,7 +2751,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
:: |registration|, a [=/service worker registration=]

1. Run the following steps atomically.
1. Let |scopeString| be <a lt="URL serializer">serialized</a> |scope| with the *exclude fragment flag* set.
1. Let |scopeString| be [=URL serializer|serialized=] |scope| with the *exclude fragment flag* set.
1. Let |registration| be a new [=/service worker registration=] whose [=service worker registration/scope url=] is set to |scope| and [=service worker registration/update via cache mode=] is set to |updateViaCache|.
1. [=map/Set=] <a>scope to registration map</a>[|scopeString|] to |registration|.
1. Return |registration|.
Expand All @@ -2769,7 +2778,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. [=Terminate Service Worker|Terminate=] |registration|'s [=active worker=].
1. Run the <a>Update Worker State</a> algorithm passing |registration|'s [=active worker=] and *redundant* as the arguments.
1. Run the <a>Update Registration State</a> algorithm passing |registration|, "<code>active</code>" and null as the arguments.
1. Let |scopeString| be <a lt="URL serializer">serialized</a> |registration|'s [=service worker registration/scope url=] with the *exclude fragment flag* set.
1. Let |scopeString| be |registration|'s [=URL serializer|serialized=] [=service worker registration/scope url=].
1. [=map/Remove=] <a>scope to registration map</a>[|scopeString|].
</section>

Expand Down Expand Up @@ -2907,7 +2916,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe

1. Run the following steps atomically.
1. Let |scopeString| be the empty string.
1. If |scope| is not null, set |scopeString| to <a lt="URL serializer">serialized</a> |scope| with the *exclude fragment flag* set.
1. If |scope| is not null, set |scopeString| to [=URL serializer|serialized=] |scope| with the *exclude fragment flag* set.
1. Let |registration| be null.
1. [=map/For each=] |key| → |value| of <a>scope to registration map</a>:
1. If |scopeString| matches |key|, set |registration| to |value|.
Expand Down Expand Up @@ -3002,7 +3011,7 @@ spec: webappsec-referrer-policy; urlPrefix: https://w3c.github.io/webappsec-refe
1. If |options|.{{CacheQueryOptions/ignoreSearch}} is true, then:
1. Set |cachedURL|'s [=url/query=] to the empty string.
1. Set |requestURL|'s [=url/query=] to the empty string.
1. If |cachedURL| [=url/equals=] |requestURL| with the *exclude fragments flag* set, then:
1. If |cachedURL| [=url/equals=] |requestURL| with the *exclude fragment flag* set, then:
1. Add a copy of |requestResponse|'s request to |requests|.
1. Add a copy of |requestResponse|'s response to |responses|.
1. Let |index| be zero.
Expand Down

0 comments on commit 58fd467

Please sign in to comment.