From 82e1f0490108415151b9e41d89c50e3e806fad1f Mon Sep 17 00:00:00 2001 From: Rob Hogan <2590098+robhogan@users.noreply.github.com> Date: Tue, 2 May 2023 14:13:31 +0100 Subject: [PATCH 1/6] 0642: JavaScriptCore-safe bundle URLs --- .../0642-JavaScriptCore-safe-bundle-URLs.md | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 proposals/0642-JavaScriptCore-safe-bundle-URLs.md diff --git a/proposals/0642-JavaScriptCore-safe-bundle-URLs.md b/proposals/0642-JavaScriptCore-safe-bundle-URLs.md new file mode 100644 index 00000000..c403c153 --- /dev/null +++ b/proposals/0642-JavaScriptCore-safe-bundle-URLs.md @@ -0,0 +1,68 @@ +--- +title: JavaScriptCore-safe bundle URLs +authors: +- Rob Hogan (@robhogan) +- Moti Zilberman (@motiz88) +date: 2023-05-02 +--- + +# RFC0642: JavaScriptCore-safe bundle URLs + +## Summary + +Add support for a query-string-free URL format to bundlers, so that symbolication (etc.) is not broken by JavaScriptCore error stack manipulation. + +## Basic example + +`http://localhost:8080/project/index.bundle;&platform=ios` + +Should be supported by Metro (and other bundlers) equivalently and in addition to the current query-string form: + +`http://localhost:8080/project/index.bundle?platform=ios` + +## Motivation + +Recent versions of JavaScriptCore strip query strings from source URLs in stack traces (`Error.prototype.stack`). + +To implement features such as Metro's `/symbolicate` endpoint correctly, we must be able to derive (a close approximation of) the source that was executed the client. To rebuild that source correctly we need to use the same build parameters. + +Ideally, for maximal compatibility with debuggers (etc.) that may intercept the raw error stack, the source URLs in the error stack should be sufficient, and should be valid URLs, without any post-processing or external context. + +## Detailed design + +Use a character sequence from the "reserved" set specified in RFC 3986, namely `;&`, as an alternative delimiter in place of `?`, and URL-encode any `?` characters appearing within the subsequent query string so that the result is a valid [`path`](https://www.rfc-editor.org/rfc/rfc3986#section-3.3). + +If the client sends a URL in this format, Metro should respond as if `?` was seen in place of the alternative delimiter, with the following exceptions: + - Wherever the bundle itself encodes its own URL, source map URL, or the URLs of other bundles on the same server (such as for lazy bundling), those should use the alternative format for any included query strings *if and only if* the original bundle request used the alternative format. Otherwise, standard query strings starting with `?` should be emitted. + - URLs of mixed format with `;&` preceding ?, i.e. `.../path;&foo=bar?foo=baz&bar=quux` should be interpreted leniently, as if they were given fully in the alternative format, i.e. `.../path;&foo=bar&foo=baz&bar=quux`. + +Because the alternative delimiter is made of reserved characters, it does not create ambiguity with standard URLs and may be escaped by percent-encoding for use as a param value, path component, etc. In particular, this supports the edge case of a valid POSIX file path containing the substring `;&` being the subject of a bundle request. + +## Drawbacks + + - The proposed URL format is unfamiliar, and standard libraries/tools won't be able to encode/decord build parameters into/from paths in this format. An exposed API or package would help mitigate. + - Maintenance/complexity of supporting an additional URL format. + - Forking of bundle URL generation in React Native by platform/engine, assuming we target this URLs as narrowly as possible. + +## Alternatives + +## Encode+decode within React Native runtime +Encode the source URL passed to JavaScriptCore to a format that won't be stripped, and need not be a URL (eg, base64-encode the entire URL), catch errors within the runtime close to where they are thrown, and post-process stacks to decode and restore the original URLs before sending a `/symbolicate` request. + +Pros: + - No changes required to Metro, fix closely coupled to specific issue and may be removed if/when it becomes unnecessary. + +Cons: + - Relies on being able to catch and decoding the stack - not a solution for all potential consumers of error stacks, (eg., remote debugging with Safari). + +## Adoption strategy + +Metro and React Native patch releases will be required. No change is required from the users. + +## How we teach this + +React Native users don't need to be aware of this explicitly. This RFC is intended to communicate the change with maintainers of CLIs and bundlers that may need to make changes to accommodate new URLs. + +## Unresolved questions + + - How do we expose functions for encoding/decoding? Is a `metro` export sufficient? Should we publish a new package? Or document a pseudo-code algorithm? From 1836b17f10152ad6ca04775f6764f1881347dd1b Mon Sep 17 00:00:00 2001 From: Rob Hogan <2590098+robhogan@users.noreply.github.com> Date: Tue, 2 May 2023 17:54:30 +0100 Subject: [PATCH 2/6] Update 0642-JavaScriptCore-safe-bundle-URLs.md --- .../0642-JavaScriptCore-safe-bundle-URLs.md | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/proposals/0642-JavaScriptCore-safe-bundle-URLs.md b/proposals/0642-JavaScriptCore-safe-bundle-URLs.md index c403c153..5e6b5436 100644 --- a/proposals/0642-JavaScriptCore-safe-bundle-URLs.md +++ b/proposals/0642-JavaScriptCore-safe-bundle-URLs.md @@ -24,45 +24,41 @@ Should be supported by Metro (and other bundlers) equivalently and in addition t Recent versions of JavaScriptCore strip query strings from source URLs in stack traces (`Error.prototype.stack`). -To implement features such as Metro's `/symbolicate` endpoint correctly, we must be able to derive (a close approximation of) the source that was executed the client. To rebuild that source correctly we need to use the same build parameters. +To implement features such as Metro's `/symbolicate` endpoint correctly, we must be able to derive (a close approximation of) the source that was executed the client. To do so correctly we need to know the build parameters the client used originally. Ideally, for maximal compatibility with debuggers (etc.) that may intercept the raw error stack, the source URLs in the error stack should be sufficient, and should be valid URLs, without any post-processing or external context. ## Detailed design -Use a character sequence from the "reserved" set specified in RFC 3986, namely `;&`, as an alternative delimiter in place of `?`, and URL-encode any `?` characters appearing within the subsequent query string so that the result is a valid [`path`](https://www.rfc-editor.org/rfc/rfc3986#section-3.3). +Use a character sequence from the "reserved" set specified in RFC 3986, namely `;&`, as an alternative delimiter in place of `?`, and URL-encode any `?` characters appearing within the subsequent query string, so that the result is a valid [`path`](https://www.rfc-editor.org/rfc/rfc3986#section-3.3). If the client sends a URL in this format, Metro should respond as if `?` was seen in place of the alternative delimiter, with the following exceptions: - Wherever the bundle itself encodes its own URL, source map URL, or the URLs of other bundles on the same server (such as for lazy bundling), those should use the alternative format for any included query strings *if and only if* the original bundle request used the alternative format. Otherwise, standard query strings starting with `?` should be emitted. - - URLs of mixed format with `;&` preceding ?, i.e. `.../path;&foo=bar?foo=baz&bar=quux` should be interpreted leniently, as if they were given fully in the alternative format, i.e. `.../path;&foo=bar&foo=baz&bar=quux`. + - URLs of mixed format with `;&` preceding `?`, i.e. `.../path;&foo=bar?foo=baz&bar=quux` should be interpreted leniently, as if they were given fully in the alternative format, i.e. `.../path;&foo=bar&foo=baz&bar=quux`. Because the alternative delimiter is made of reserved characters, it does not create ambiguity with standard URLs and may be escaped by percent-encoding for use as a param value, path component, etc. In particular, this supports the edge case of a valid POSIX file path containing the substring `;&` being the subject of a bundle request. ## Drawbacks - - The proposed URL format is unfamiliar, and standard libraries/tools won't be able to encode/decord build parameters into/from paths in this format. An exposed API or package would help mitigate. + - The proposed URL format is unfamiliar, and standard libraries and tools won't be able to encode/decode build parameters into/from URLs in this format. An exposed API or package would help mitigate. - Maintenance/complexity of supporting an additional URL format. - - Forking of bundle URL generation in React Native by platform/engine, assuming we target this URLs as narrowly as possible. + - Forking of bundle URL generation in React Native by platform/engine, assuming we use this new format on as narrow a range of target engines as possible. ## Alternatives ## Encode+decode within React Native runtime -Encode the source URL passed to JavaScriptCore to a format that won't be stripped, and need not be a URL (eg, base64-encode the entire URL), catch errors within the runtime close to where they are thrown, and post-process stacks to decode and restore the original URLs before sending a `/symbolicate` request. +Encode the source URL passed to JavaScriptCore to a format that won't be stripped, and need not be a URL (e.g., base64-encode the entire URL), catch errors within the runtime close to where they are thrown, and post-process stacks to decode and restore the original URLs before sending a `/symbolicate` request. Pros: - No changes required to Metro, fix closely coupled to specific issue and may be removed if/when it becomes unnecessary. Cons: - - Relies on being able to catch and decoding the stack - not a solution for all potential consumers of error stacks, (eg., remote debugging with Safari). + - Relies on being able to catch and decode the stack before consumption - not a solution for all potential consumers of error stacks, (eg., errors caught within user code, uses of `new Error().stack`, remote debugging with Safari). ## Adoption strategy -Metro and React Native patch releases will be required. No change is required from the users. +Metro and React Native patch releases will be required. No change is required from users. ## How we teach this React Native users don't need to be aware of this explicitly. This RFC is intended to communicate the change with maintainers of CLIs and bundlers that may need to make changes to accommodate new URLs. - -## Unresolved questions - - - How do we expose functions for encoding/decoding? Is a `metro` export sufficient? Should we publish a new package? Or document a pseudo-code algorithm? From 673b44418ef674a1fd49a6deca5ab2ca2fefa903 Mon Sep 17 00:00:00 2001 From: Rob Hogan <2590098+robhogan@users.noreply.github.com> Date: Tue, 2 May 2023 20:40:52 +0100 Subject: [PATCH 3/6] Add links to motivating issues + JSC change --- proposals/0642-JavaScriptCore-safe-bundle-URLs.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/0642-JavaScriptCore-safe-bundle-URLs.md b/proposals/0642-JavaScriptCore-safe-bundle-URLs.md index 5e6b5436..942f1cc0 100644 --- a/proposals/0642-JavaScriptCore-safe-bundle-URLs.md +++ b/proposals/0642-JavaScriptCore-safe-bundle-URLs.md @@ -10,7 +10,7 @@ date: 2023-05-02 ## Summary -Add support for a query-string-free URL format to bundlers, so that symbolication (etc.) is not broken by JavaScriptCore error stack manipulation. +Add support for a query-string-free URL format to bundlers, so that symbolication (etc.) is not broken by JavaScriptCore error stack manipulation introduced in https://github.com/WebKit/WebKit/commit/71985aa1520560154a329e5b54159fff3173cf22 (first appearing in iOS 16.4). ## Basic example @@ -22,9 +22,9 @@ Should be supported by Metro (and other bundlers) equivalently and in addition t ## Motivation -Recent versions of JavaScriptCore strip query strings from source URLs in stack traces (`Error.prototype.stack`). +Recent versions of JavaScriptCore strip query strings from source URLs in stack traces (`Error.prototype.stack`). This had led to issues for React Native and Expo users -To implement features such as Metro's `/symbolicate` endpoint correctly, we must be able to derive (a close approximation of) the source that was executed the client. To do so correctly we need to know the build parameters the client used originally. +To implement features such as Metro's `/symbolicate` endpoint, we must be able to derive (a close approximation of) the source that was executed the client. To do so correctly we need to know the build parameters the client used originally. Those parameters being stripped (and defaults used instead) has manifested as obscure resolution errors for React Native users, on both Expo and the community CLI ([1](https://github.com/facebook/react-native/issues/36794), [2](https://github.com/expo/expo/issues/22008)). Ideally, for maximal compatibility with debuggers (etc.) that may intercept the raw error stack, the source URLs in the error stack should be sufficient, and should be valid URLs, without any post-processing or external context. @@ -46,7 +46,7 @@ Because the alternative delimiter is made of reserved characters, it does not cr ## Alternatives -## Encode+decode within React Native runtime +### Encode+decode within React Native runtime Encode the source URL passed to JavaScriptCore to a format that won't be stripped, and need not be a URL (e.g., base64-encode the entire URL), catch errors within the runtime close to where they are thrown, and post-process stacks to decode and restore the original URLs before sending a `/symbolicate` request. Pros: From a9ca8cc3b059be6fe2b6bad728a4e5ee2ea38f73 Mon Sep 17 00:00:00 2001 From: Rob Hogan <2590098+robhogan@users.noreply.github.com> Date: Thu, 4 May 2023 11:06:54 +0100 Subject: [PATCH 4/6] Remove redundant sentence fragment, prefer "percent-encoding" over "URL-encoding" --- proposals/0642-JavaScriptCore-safe-bundle-URLs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/0642-JavaScriptCore-safe-bundle-URLs.md b/proposals/0642-JavaScriptCore-safe-bundle-URLs.md index 942f1cc0..38bcedd2 100644 --- a/proposals/0642-JavaScriptCore-safe-bundle-URLs.md +++ b/proposals/0642-JavaScriptCore-safe-bundle-URLs.md @@ -22,7 +22,7 @@ Should be supported by Metro (and other bundlers) equivalently and in addition t ## Motivation -Recent versions of JavaScriptCore strip query strings from source URLs in stack traces (`Error.prototype.stack`). This had led to issues for React Native and Expo users +Recent versions of JavaScriptCore strip query strings from source URLs in stack traces (`Error.prototype.stack`). To implement features such as Metro's `/symbolicate` endpoint, we must be able to derive (a close approximation of) the source that was executed the client. To do so correctly we need to know the build parameters the client used originally. Those parameters being stripped (and defaults used instead) has manifested as obscure resolution errors for React Native users, on both Expo and the community CLI ([1](https://github.com/facebook/react-native/issues/36794), [2](https://github.com/expo/expo/issues/22008)). @@ -30,7 +30,7 @@ Ideally, for maximal compatibility with debuggers (etc.) that may intercept the ## Detailed design -Use a character sequence from the "reserved" set specified in RFC 3986, namely `;&`, as an alternative delimiter in place of `?`, and URL-encode any `?` characters appearing within the subsequent query string, so that the result is a valid [`path`](https://www.rfc-editor.org/rfc/rfc3986#section-3.3). +Use a character sequence from the "reserved" set specified in RFC 3986, namely `;&`, as an alternative delimiter in place of `?`, and percent-encode any `?` characters appearing within the subsequent query string, so that the result is a valid [`path`](https://www.rfc-editor.org/rfc/rfc3986#section-3.3). If the client sends a URL in this format, Metro should respond as if `?` was seen in place of the alternative delimiter, with the following exceptions: - Wherever the bundle itself encodes its own URL, source map URL, or the URLs of other bundles on the same server (such as for lazy bundling), those should use the alternative format for any included query strings *if and only if* the original bundle request used the alternative format. Otherwise, standard query strings starting with `?` should be emitted. From a96139248c84255d6d558e98b693a7a74baeb9c0 Mon Sep 17 00:00:00 2001 From: Rob Hogan <2590098+robhogan@users.noreply.github.com> Date: Thu, 18 May 2023 15:41:56 +0100 Subject: [PATCH 5/6] Change delimiter to `//&`, propose use of `Content-Location` --- .../0642-JavaScriptCore-safe-bundle-URLs.md | 64 -------------- .../0642-JavaScriptCore-safe-source-URLs.md | 85 +++++++++++++++++++ 2 files changed, 85 insertions(+), 64 deletions(-) delete mode 100644 proposals/0642-JavaScriptCore-safe-bundle-URLs.md create mode 100644 proposals/0642-JavaScriptCore-safe-source-URLs.md diff --git a/proposals/0642-JavaScriptCore-safe-bundle-URLs.md b/proposals/0642-JavaScriptCore-safe-bundle-URLs.md deleted file mode 100644 index 38bcedd2..00000000 --- a/proposals/0642-JavaScriptCore-safe-bundle-URLs.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: JavaScriptCore-safe bundle URLs -authors: -- Rob Hogan (@robhogan) -- Moti Zilberman (@motiz88) -date: 2023-05-02 ---- - -# RFC0642: JavaScriptCore-safe bundle URLs - -## Summary - -Add support for a query-string-free URL format to bundlers, so that symbolication (etc.) is not broken by JavaScriptCore error stack manipulation introduced in https://github.com/WebKit/WebKit/commit/71985aa1520560154a329e5b54159fff3173cf22 (first appearing in iOS 16.4). - -## Basic example - -`http://localhost:8080/project/index.bundle;&platform=ios` - -Should be supported by Metro (and other bundlers) equivalently and in addition to the current query-string form: - -`http://localhost:8080/project/index.bundle?platform=ios` - -## Motivation - -Recent versions of JavaScriptCore strip query strings from source URLs in stack traces (`Error.prototype.stack`). - -To implement features such as Metro's `/symbolicate` endpoint, we must be able to derive (a close approximation of) the source that was executed the client. To do so correctly we need to know the build parameters the client used originally. Those parameters being stripped (and defaults used instead) has manifested as obscure resolution errors for React Native users, on both Expo and the community CLI ([1](https://github.com/facebook/react-native/issues/36794), [2](https://github.com/expo/expo/issues/22008)). - -Ideally, for maximal compatibility with debuggers (etc.) that may intercept the raw error stack, the source URLs in the error stack should be sufficient, and should be valid URLs, without any post-processing or external context. - -## Detailed design - -Use a character sequence from the "reserved" set specified in RFC 3986, namely `;&`, as an alternative delimiter in place of `?`, and percent-encode any `?` characters appearing within the subsequent query string, so that the result is a valid [`path`](https://www.rfc-editor.org/rfc/rfc3986#section-3.3). - -If the client sends a URL in this format, Metro should respond as if `?` was seen in place of the alternative delimiter, with the following exceptions: - - Wherever the bundle itself encodes its own URL, source map URL, or the URLs of other bundles on the same server (such as for lazy bundling), those should use the alternative format for any included query strings *if and only if* the original bundle request used the alternative format. Otherwise, standard query strings starting with `?` should be emitted. - - URLs of mixed format with `;&` preceding `?`, i.e. `.../path;&foo=bar?foo=baz&bar=quux` should be interpreted leniently, as if they were given fully in the alternative format, i.e. `.../path;&foo=bar&foo=baz&bar=quux`. - -Because the alternative delimiter is made of reserved characters, it does not create ambiguity with standard URLs and may be escaped by percent-encoding for use as a param value, path component, etc. In particular, this supports the edge case of a valid POSIX file path containing the substring `;&` being the subject of a bundle request. - -## Drawbacks - - - The proposed URL format is unfamiliar, and standard libraries and tools won't be able to encode/decode build parameters into/from URLs in this format. An exposed API or package would help mitigate. - - Maintenance/complexity of supporting an additional URL format. - - Forking of bundle URL generation in React Native by platform/engine, assuming we use this new format on as narrow a range of target engines as possible. - -## Alternatives - -### Encode+decode within React Native runtime -Encode the source URL passed to JavaScriptCore to a format that won't be stripped, and need not be a URL (e.g., base64-encode the entire URL), catch errors within the runtime close to where they are thrown, and post-process stacks to decode and restore the original URLs before sending a `/symbolicate` request. - -Pros: - - No changes required to Metro, fix closely coupled to specific issue and may be removed if/when it becomes unnecessary. - -Cons: - - Relies on being able to catch and decode the stack before consumption - not a solution for all potential consumers of error stacks, (eg., errors caught within user code, uses of `new Error().stack`, remote debugging with Safari). - -## Adoption strategy - -Metro and React Native patch releases will be required. No change is required from users. - -## How we teach this - -React Native users don't need to be aware of this explicitly. This RFC is intended to communicate the change with maintainers of CLIs and bundlers that may need to make changes to accommodate new URLs. diff --git a/proposals/0642-JavaScriptCore-safe-source-URLs.md b/proposals/0642-JavaScriptCore-safe-source-URLs.md new file mode 100644 index 00000000..00a15937 --- /dev/null +++ b/proposals/0642-JavaScriptCore-safe-source-URLs.md @@ -0,0 +1,85 @@ +--- +title: JavaScriptCore-safe bundle URLs +authors: +- Rob Hogan (@robhogan) +- Moti Zilberman (@motiz88) +date: 2023-05-02 +--- + +# RFC0642: JavaScriptCore-safe source URLs + +## Summary + +Add support for a query-string-free URL format to bundlers, so that symbolication (etc.) is not broken by JavaScriptCore error stack manipulation introduced in https://github.com/WebKit/WebKit/commit/71985aa1520560154a329e5b54159fff3173cf22 (first appearing in iOS 16.4). + +## Basic example + +`http://localhost:8080/project/index.bundle//&platform=ios` + +Should be supported by Metro (and other bundlers) equivalently and in addition to the current query-string form: + +`http://localhost:8080/project/index.bundle?platform=ios` + +## Motivation + +Recent versions of JavaScriptCore strip query strings from source URLs in stack traces (`Error.prototype.stack`). + +To implement features such as Metro's `/symbolicate` endpoint, we must be able to derive (a close approximation of) the source that was executed the client. To do so correctly we need to know the build parameters the client used originally. Those parameters being stripped (and defaults used instead) has manifested as obscure resolution errors for React Native users, on both Expo and the community CLI ([1](https://github.com/facebook/react-native/issues/36794), [2](https://github.com/expo/expo/issues/22008)). + +Ideally, for maximal compatibility with debuggers (etc.) that may intercept the raw error stack, the source URLs in the error stack should be sufficient, and should be valid URLs, without any post-processing or external context. + +## Detailed design + +Use a character sequence that would not otherwise appear in the [`path`](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component of an HTTP request to the bundler, namely `//&`, as an alternative delimiter in place of `?`, and percent-encode any `?` characters appearing within the subsequent query string, so that the result is a valid `path`, encoding both the original path and query string data. + +### Handling by bundlers +If the client sends a URL in this format, the bundler should respond as if `?` was seen in place of the alternative delimiter, with the following exception: + - URLs of mixed format with `//&` preceding `?`, i.e. `.../path//&foo=bar?foo=baz&bar=quux` should be interpreted leniently, as if they were given fully in the alternative format, i.e. `.../path//&foo=bar&foo=baz&bar=quux`. + +By construction (see "Choice of delimiter" below), there is no ambiguity introduced with standard URLs - the presence of the delimiter in the path is sufficient to infer that the input is encoded according to this RFC. + +In addition, bundlers should *emit* URLs encoded in this form in any "source URLs" provided to the client, including in HMR payloads and `//# sourceURL` comments. The client will be expected to pass these encoded source URLs to the engine, where applicable, so that they are emitted in Error stacks, etc. + +Bundlers *may* emit an encoded "source URL" in response to an HTTP bundle request via the `Content-Location` HTTP header, matching (after URL resolution) any `//# sourceURL` in the bundle output. By passing this encoded URL to the JavaScript engine (and in particular, JavaScriptCore), the client can generate usable stack traces without any change to the URL on which it *requests* the bundle. + +## Drawbacks + + - The proposed URL format is unfamiliar, and standard libraries and tools won't be able to encode/decode build parameters into/from URLs in this format. An exposed API or package would help mitigate. + - Maintenance/complexity of supporting an additional URL format. + +## Alternatives + +### Encode+decode within React Native runtime +Encode the source URL passed to JavaScriptCore to a format that won't be stripped, and need not be a URL (e.g., base64-encode the entire URL), catch errors within the runtime close to where they are thrown, and post-process stacks to decode and restore the original URLs before sending a `/symbolicate` request. + +Pros: + - No changes required to Metro, fix closely coupled to specific issue and may be removed if/when it becomes unnecessary. + +Cons: + - Relies on being able to catch and decode the stack before consumption - not a solution for all potential consumers of error stacks, (eg., errors caught within user code, uses of `new Error().stack`, remote debugging with Safari). + +### Choice of delimiter +Bundle requests begin with a representation of the project-root-relative path of an entry file on the file system, with directory separators represented as `/` (URL path separators). Clients are not required to percent-encode characters within the file path except as required by RFC3986. Because of this, and the almost unconstrained range of characters permitted in POSIX file paths, there are very few options for a delimiter that will not collide with potentially pre-existing bundle request URLs, and allow a non-breaking implementation of this RFC. + +However, there are a small number of potentially useful constraints on POSIX file path segments: + 1. They may not contain a `null` character, so the corresponding percent-encoding `%00` will never appear in the path component of a bundle URL. + 2. They may not be empty strings, so consecutive path separators `//` should never appear. + 3. (If we further assume that the bundle URL only ever contains a "normalised" file path, the sequence `/./` should never appear.) + +For future-proofing, we would like to choose a delimeter that allows encoding of the [`Fragment`](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) (which is also stripped by JSC) in a consistent fashion, though doing so is beyond the scope of this RFC as fragments are not currently in use in bundle URLs. + +`%00` may be used to terminate a POSIX path, but it could not be used to separate an encoded query string from an encoded fragment, due to potential ambiguity with an encoded `null` within a query string, with the fact that it is already percent-encoded. + +`/./` makes the arguably fragile assumption of normalisation, and is more verbose than `//`. + +`//` may be used to separate query from fragment if we required that this sequence *within* a query string must be percent-encoded. In order to distinguish a query delimiter from a fragment delimiter, so that either one or both may appear in a JSC-safe URL, we may add a character to the sequence, such as `//&` for queries and `//_` for fragments. The use of `//&` is chosen for readability and consistency with a query string of `&`-separated `key=value` pairs. + +One notable caveat is that `//` may not be used at the very start of a path, due to ambiguity with the start of [`authority`](https://www.rfc-editor.org/rfc/rfc3986#section-3) (e.g. `//example.com`). Bundle URLs may not have empty paths, so handling this case is not in scope for this RFC, but potentially a combination of the above, such as a path beginning `%00//`, (a "null" path) could be used in this case. + +## Adoption strategy + +Metro and React Native patch releases will be required. No change is required from users. + +## How we teach this + +React Native users don't need to be aware of this explicitly. This RFC is intended to communicate the change with maintainers of CLIs and bundlers that may need to make changes to accommodate new URLs. From 25b34aa83662c820b584c72c376838ea8320df9c Mon Sep 17 00:00:00 2001 From: Rob Hogan <2590098+robhogan@users.noreply.github.com> Date: Thu, 18 May 2023 15:54:46 +0100 Subject: [PATCH 6/6] Renumber and rename file to match PR number --- ...source-URLs.md => 0646-JavaScriptCore-safe-source-URLs.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename proposals/{0642-JavaScriptCore-safe-source-URLs.md => 0646-JavaScriptCore-safe-source-URLs.md} (98%) diff --git a/proposals/0642-JavaScriptCore-safe-source-URLs.md b/proposals/0646-JavaScriptCore-safe-source-URLs.md similarity index 98% rename from proposals/0642-JavaScriptCore-safe-source-URLs.md rename to proposals/0646-JavaScriptCore-safe-source-URLs.md index 00a15937..73b57816 100644 --- a/proposals/0642-JavaScriptCore-safe-source-URLs.md +++ b/proposals/0646-JavaScriptCore-safe-source-URLs.md @@ -1,12 +1,12 @@ --- -title: JavaScriptCore-safe bundle URLs +title: JavaScriptCore-safe source URLs authors: - Rob Hogan (@robhogan) - Moti Zilberman (@motiz88) date: 2023-05-02 --- -# RFC0642: JavaScriptCore-safe source URLs +# RFC0646: JavaScriptCore-safe source URLs ## Summary