From d218a6eb7f1488a1b8b01ec7d153e5a812f98554 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Sat, 28 Sep 2019 09:26:39 +0200 Subject: [PATCH] Revert JSON modules As explained at https://github.com/w3c/webcomponents/issues/839 the current setup is insecure. This reverts db03474b8b87aab3454ff7d5c1f4a5f044b4395c. --- source | 442 ++++++++++++++++++++++++++------------------------------- 1 file changed, 199 insertions(+), 243 deletions(-) diff --git a/source b/source index 5699ab6fbee..ce5835fc314 100644 --- a/source +++ b/source @@ -2924,10 +2924,6 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • converting to a sequence of Unicode scalar values
  • overload resolution algorithm
  • -
  • CreateSyntheticModule
  • -
  • SetSyntheticModuleExport
  • -
  • Synthetic Module Record
  • -
  • exposed
  • The Web IDL also defines the following types that are used in Web IDL fragments @@ -3134,7 +3130,6 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute

    User agents that support JavaScript must also implement the BigInt proposal.

    - @@ -58057,14 +58052,11 @@ interface HTMLScriptElement : HTMLElement { redundantly setting it.

  • Setting the attribute to an ASCII case-insensitive match for the string - "module" means that the script is a module script. If it has - a JavaScript MIME type, or if the script is embedded inline, then it will be - interpreted as a JavaScript module script according to the JavaScript Module top-level production; if it has a JSON MIME - type, then it will be interpreted as a JSON module script. Module scripts - are not affected by the defer attribute, but are - affected by the async attribute (regardless of the state - of the src attribute).

  • + "module" means that the script is a module script, to be + interpreted according to the JavaScript Module top-level + production. Module scripts are not affected by the defer + attribute, but are affected by the async attribute + (regardless of the state of the src attribute).

  • Setting the attribute to any other value means that the script is a data block, which is not processed. None of the script attributes (except HTMLScriptElement : HTMLElement { scripts. By using a valid MIME type string now, you ensure that your data block will not ever be reinterpreted as a different script type, even in future user agents.

    -

    Classic scripts and JavaScript module scripts can be embedded inline, or be imported from an external - file using the Classic scripts and module + scripts may either be embedded inline or may be imported from an external file using the + src attribute, which if specified gives the URL of the external script resource to use. If src is specified, - it must be a valid non-empty URL potentially surrounded by spaces.

    - -

    The contents of inline script elements, or the external script resource, must - conform with the requirements of the JavaScript specification's Script or Module productions, for classic scripts and JavaScript module scripts respectively.

    - -

    The contents of the external script resource for JSON module - scripts must conform to the requirements of the JSON specification .

    + it must be a valid non-empty URL potentially surrounded by spaces. The contents of + inline script elements, or the external script resource, must conform with the + requirements of the JavaScript specification's Script or Module productions, for classic + scripts and module scripts respectively.

    When used to include data blocks, the data must be embedded inline, the format of the data must be given using the type @@ -58335,7 +58323,7 @@ o............A....e

    The following sample shows how a script element can be used to include an - external JavaScript module script. + external module script.

    <script type="module" src="app.mjs"></script>
    @@ -58346,37 +58334,37 @@ o............A....e

    Additionally, if code from another script element in the same Window imports the module from app.mjs (e.g. via import - "./app.mjs";), then the same JavaScript module script created by the + "./app.mjs";), then the same module script created by the former script element will be imported.

    -

    This example shows how to include a JavaScript module script for modern user - agents, and a classic script for older user agents:

    +

    This example shows how to include a module script for modern user agents, and a + classic script for older user agents:

    <script type="module" src="app.mjs"></script>
     <script nomodule defer src="classic-app-bundle.js"></script>
    -

    In modern user agents that support JavaScript module - scripts, the script element with the nomodule attribute will be ignored, and the +

    In modern user agents that support module scripts, the + script element with the nomodule attribute + will be ignored, and the script element with a type of "module" will be fetched and + evaluated (as a module script). Conversely, older user agents will ignore the script element with a type of "module" will be fetched and evaluated (as a JavaScript module - script). Conversely, older user agents will ignore the script element with a - type of "module", as that is an - unknown script type for them — but they will have no problem fetching and evaluating the other - script element (as a classic script), since they do not implement the - nomodule attribute.

    + data-x="">module
    ", as that is an unknown script type for them — but they will have no + problem fetching and evaluating the other script element (as a classic + script), since they do not implement the nomodule attribute.

    The following sample shows how a script element can be used to write an inline - JavaScript module script that performs a number of substitutions on the document's - text, in order to make for a more interesting reading experience (e.g. on a news site): module script that performs a number of substitutions on the document's text, in + order to make for a more interesting reading experience (e.g. on a news site):

    <script type="module">
    @@ -58408,30 +58396,12 @@ o............A....e
      walkAllTextNodeDescendants(document.body, substitute);
     </script>
    -

    Some notable features gained by using a JavaScript module script include the ability to import - functions from other JavaScript modules, strict mode by default, and how top-level declarations - do not introduce new properties onto the global object. Also note that no matter - where this script element appears in the document, it will not be evaluated until - both document parsing has complete and its dependency (dom-utils.mjs) has - been fetched and evaluated.

    - -
    - -
    - -

    The following sample shows how to you can import a JSON module script from inside - a JavaScript module script:

    - -
    <script type="module">
    -import peopleInSpace from "http://api.open-notify.org/astros.json";
    -
    -const list = document.querySelector("#people-in-space");
    -for (const { craft, name } of peopleInSpace.people) {
    -  const li = document.createElement("li");
    -  li.textContent = `${name} / ${craft}`;
    -  list.append(li);
    -}
    -</script>
    +

    Some notable features gained by using a module script include the ability to import functions + from other JavaScript modules, strict mode by default, and how top-level declarations do not + introduce new properties onto the global object. Also note that no matter where + this script element appears in the document, it will not be evaluated until both + document parsing has complete and its dependency (dom-utils.mjs) has been + fetched and evaluated.

    @@ -88081,7 +88051,7 @@ interface ApplicationCache : EventTarget {
    Definitions
    -

    A script is one of three possible A script is one of two possible structs. All scripts have:

    @@ -88092,22 +88062,10 @@ interface ApplicationCache : EventTarget {
    A record
    -
    -

    One of the following:

    - -
      -
    • a script record, for classic - scripts;

    • - -
    • a Source Text Module Record, for JavaScript module scripts;

    • - -
    • a Synthetic Module Record, for JSON - module scripts; or

    • - -
    • null, representing a parsing failure.

    • -
    -
    +

    Either a Script Record, for classic + scripts; a Source Text Module Record, for module scripts; or null. In the former two cases, it represents a parsed script; + null represents a failure parsing.

    A parse error
    @@ -88159,35 +88117,6 @@ interface ApplicationCache : EventTarget { data-x="concept-script">script. It has no additional items.

    -

    Module scripts can be classified into two types:

    - -
      -
    • A module script is a JavaScript module script if - its record is a Source Text Module - Record.

    • - -
    • -

      A module script is a JSON module script if its record is a Synthetic Module Record, and it - was created via the create a JSON module - script algorithm. JSON module scripts represent a parsed JSON document.

      - - -

      As JSON documents do not import dependent modules, and do not throw exceptions - on evaluation, the fetch options and - base URL of a JSON module script are - always null.

      -
    • -
    -

    The active script is determined by the following algorithm:

      @@ -89142,64 +89071,160 @@ interface ApplicationCache : EventTarget {
    1. response's status is not an ok status

    2. + +
    3. +

      The result of extracting a MIME type from + response's header list is not a + JavaScript MIME type

      + +

      For historical reasons, fetching a + classic script does not include MIME type checking. In contrast, module scripts will + fail to load if they are not of a correct MIME type.

      +
    4. -
    5. -

      Let type be the result of extracting a - MIME type from response's header - list.

      +
    6. Let source text be the result of UTF-8 + decoding response's body.

    7. -

      For historical reasons, fetching a - classic script does not include MIME type checking. In contrast, module scripts' - interpretation is driven by their MIME type, and they will fail to load if they are not of - a supported MIME type.

      - +
    8. Let module script be the result of creating a module script given + source text, module map settings object, response's url, and options.

    9. -

      Let module script be null.

      +

      Set moduleMap[url] to module + script, and asynchronously complete this algorithm with module script.

      -

      If the resource does not have a MIME type which HTML knows how to handle - as a module, then module script will remain null, which is interpreted as - failure.

      +

      It is intentional that the module map is keyed by the request URL, whereas the base URL for the module script is + set to the response URL. The former is used to + deduplicate fetches, while the latter is used for URL resolution.

    10. +
    + +

    To fetch the descendants of a module script module script, given a + fetch client settings object, a destination, and a visited set, + run these steps. The algorithm will asynchronously complete with either null (on failure) or + with module script (on success).

    + +
      +
    1. If module script's record is null, + then asynchronously complete this algorithm with module script and abort these + steps.

    2. + +
    3. Let record be module script's record.

    4. + +
    5. If record.[[RequestedModules]] is empty, + asynchronously complete this algorithm with module script.

    6. + +
    7. Let urls be a new empty list.

    8. -

      If type is a JavaScript MIME type, then:

      +

      For each string requested of + record.[[RequestedModules]],

      -
        -
      1. Let source text be the result of UTF-8 - decoding response's body.

      2. +
          +
        1. Let url be the result of resolving + a module specifier given module script's base URL and requested.

        2. -
        3. Set module script to the result of creating a JavaScript module - script given source text, module map settings object, - response's url, and - options.

        4. -
        +
      3. Assert: url is never failure, because resolving a module specifier must have been previously successful with these same two + arguments.

      4. + +
      5. +

        If visited set does not contain + url, then:

        + +
          +
        1. Append url to urls.

        2. + +
        3. Append url to visited + set.

        4. +
        +
      6. +
    9. +
    10. Let options be the descendant script fetch options for module + script's fetch options.

    11. +
    12. -

      If type is a JSON MIME type, then:

      +

      For each url in urls, perform the + internal module script graph fetching procedure given url, + fetch client settings object, destination, options, module + script's settings object, visited set, module script's + base URL, and with the top-level module + fetch flag unset. If the caller of this algorithm specified custom perform the fetch steps, pass those along + while performing the internal module script graph fetching procedure.

      -
        -
      1. Let source text be the result of UTF-8 - decoding response's body.

      2. +

        These invocations of the internal module script graph fetching procedure should + be performed in parallel to each other.

        -
      3. Set module script to the result of creating a JSON module - script given source text and module map settings object.

      4. -
      +

      If any of the invocations of the internal module script graph fetching procedure + asynchronously complete with null, asynchronously complete this algorithm with null, aborting + these steps.

      + +

      Otherwise, wait until all of the internal module script graph fetching procedure + invocations have asynchronously completed. Asynchronously complete this algorithm with + module script.

    13. +
    + +

    To fetch the descendants of and instantiate a module script module + script, given a fetch client settings object, a destination, and an + optional visited set, run these steps. The algorithm will asynchronously complete with + either null (on failure) or with module script (on success).

    + +
      +
    1. If visited set was not given, let it be an empty set.

    2. + +
    3. Fetch the descendants of + module script, given fetch client settings object, destination, + and visited set.

    4. + +
    5. Return from this algorithm, and run the following steps when fetching the descendants of a module script asynchronously + completes with result.

    6. -

      Set moduleMap[url] to module - script, and asynchronously complete this algorithm with module script.

      +

      If result is null, then asynchronously complete this algorithm with + result.

      -

      It is intentional that the module map is keyed by the request URL, whereas the base URL for the module script is - set to the response URL. The former is used to - deduplicate fetches, while the latter is used for URL resolution.

      +

      In this case, there was an error fetching one or more of the descendants. We + will not attempt to instantiate.

    7. + +
    8. Let parse error be the result of finding the first parse error + given result.

    9. + +
    10. If parse error is null, then:

      + +
        +
      1. Let record be result's record.

      2. + +
      3. +

        Perform record.Instantiate().

        + +

        This step will recursively call Instantiate on all of the module's uninstantiated + dependencies.

        + +

        If this throws an exception, set result's error to rethrow to that exception.

        +
      4. +
      +
    11. + +
    12. Otherwise, set result's error to + rethrow to parse error.

    13. + +
    14. Asynchronously complete this algorithm with result.

    To find the first parse error given a root @@ -89218,43 +89243,36 @@ interface ApplicationCache : EventTarget { then return moduleScript's parse error.

  • -
  • -

    If moduleScript's record is a - Cyclic Module Record:

    - -
      -
    1. Let childSpecifiers be the value of moduleScript's record's [[RequestedModules]] internal slot.

    2. +
    3. Let childSpecifiers be the value of moduleScript's record's [[RequestedModules]] internal slot.

    4. -
    5. Let childURLs be the list obtained by calling - resolve a module specifier once for each item of childSpecifiers, given - moduleScript's base URL and that item. - (None of these will ever fail, as otherwise moduleScript would have been marked as - itself having a parse error.)

    6. +
    7. Let childURLs be the list obtained by calling + resolve a module specifier once for each item of childSpecifiers, given + moduleScript's base URL and that item. + (None of these will ever fail, as otherwise moduleScript would have been marked as + itself having a parse error.)

    8. -
    9. Let childModules be the list obtained by getting each value in moduleMap whose key is given by an - item of childURLs.

    10. +
    11. Let childModules be the list obtained by getting each value in moduleMap whose key is given by an + item of childURLs.

    12. -
    13. -

      For each childModule of - childModules:

      +
    14. +

      For each childModule of + childModules:

      -
        -
      1. Assert: childModule is a module script (i.e., it is not "fetching" or null); by now all module - scripts in the graph rooted at moduleScript will have successfully been - fetched.

      2. +
          +
        1. Assert: childModule is a module script (i.e., it is not "fetching" or null); by now all module + scripts in the graph rooted at moduleScript will have successfully been + fetched.

        2. -
        3. If discoveredSet already contains - childModule, continue.

        4. +
        5. If discoveredSet already contains + childModule, continue.

        6. -
        7. Let childParseError be the result of finding the first parse - error given childModule and discoveredSet.

        8. +
        9. Let childParseError be the result of finding the first parse + error given childModule and discoveredSet.

        10. -
        11. If childParseError is not null, return childParseError.

        12. -
        - +
      3. If childParseError is not null, return childParseError.

    15. @@ -89318,10 +89336,10 @@ interface ApplicationCache : EventTarget {
    16. Return script.

    -

    To create a JavaScript module script, - given a JavaScript string source, an environment settings - object settings, a URL baseURL, and some script - fetch options options:

    +

    To create a module script, given a + JavaScript string source, an environment settings object + settings, a URL baseURL, and some script fetch + options options:

    1. If scripting is disabled for @@ -89397,53 +89415,6 @@ interface ApplicationCache : EventTarget {

    2. Return script.

    -

    To create a JSON module script, given a - string source and an environment settings object settings:

    - -
      -
    1. Let script be a new module script that this algorithm will - subsequently initialize.

    2. - -
    3. Set script's settings object to settings.

    4. - -
    5. Set script's base URL and - fetch options to null.

    6. - -
    7. Set script's parse error and - error to rethrow to null.

    8. - -
    9. -

      Let json be ? Call(%JSONParse%, undefined, - « source »).

      - -

      If this throws an exception, set script's parse error to that exception, and return - script.

      -
    10. - -
    11. Set script's record to the result - of creating a synthetic - module record with a default export of json with settings.

    12. - -
    13. Return script.

    14. -
    - -

    To create a synthetic module record with a default export of a JavaScript value - value with an environment settings object settings:

    - -
      -
    1. -

      Return CreateSyntheticModule(« "default" », the following steps, - settings's Realm, - value) with the following steps given module as an argument:

      - -
        -
      1. SetSyntheticModuleExport(module, "default", - module.[[HostDefined]]).
      2. -
      -
    2. -
    -
    Calling scripts

    To run a classic script given a classic script @@ -90555,9 +90526,6 @@ import "https://example.com/foo/../module2.mjs";

  • Set base URL to referencing script's base URL.

  • - -
  • Assert: base URL is not null, as referencing script is a - classic script or a JavaScript module script.

  • @@ -90631,10 +90599,6 @@ import "https://example.com/foo/../module2.mjs";
  • Set fetch options to the descendant script fetch options for referencing script's fetch options.

  • - -
  • Assert: Neither base URL nor fetch options is null, as - referencing script is a classic script or a JavaScript module - script.

  • As explained above for HostResolveImportedModule, in the common @@ -90683,10 +90647,6 @@ import "https://example.com/foo/../module2.mjs";

    1. Let module script be moduleRecord.[[HostDefined]].

    2. -
    3. Assert: module script's base - URL is not null, as module script is a JavaScript module - script.

    4. -
    5. Let urlString be module script's base URL, serialized.

    6. @@ -94092,9 +94052,6 @@ document.body.appendChild(frame)
    7. Let base URL be initiating script's base URL.

    8. -
    9. Assert: base URL is not null, as initiating script is a - classic script or a JavaScript module script.

    10. -
    11. Let fetch options be a script fetch options whose cryptographic nonce is initiating @@ -124817,7 +124774,6 @@ INSERT INTERFACES HERE 邱慕安 (Mu-An Chiou), Mukilan Thiyagarajan, Mustaq Ahmed, - Myles Borins, Nadia Heninger, NARUSE Yui, Navid Zolghadr,