From 18c98195b3f9ac0e24069b7c60dcbcb88d0e64f2 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 13 Dec 2024 14:30:16 +0100 Subject: [PATCH 1/2] Accept async_sequence in crypto.subtle.digest --- spec/Overview.html | 199 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 173 insertions(+), 26 deletions(-) diff --git a/spec/Overview.html b/spec/Overview.html index 7b7f68a..502e9b9 100644 --- a/spec/Overview.html +++ b/spec/Overview.html @@ -1271,7 +1271,7 @@

SubtleCrypto interface

); Promise<ArrayBuffer> digest( AlgorithmIdentifier algorithm, - BufferSource data + (BufferSource or async_sequence<BufferSource>) data ); Promise<(CryptoKey or CryptoKeyPair)> generateKey( @@ -1845,9 +1845,7 @@

The digest method

  • - Let |data| be the result of - [= get a copy of the buffer source | - getting a copy of the bytes held by =] the `data` parameter passed to the + Let |data| be the `data` parameter passed to the {{SubtleCrypto/digest()}} method.

  • @@ -1865,6 +1863,133 @@

    The digest method

    |normalizedAlgorithm|.

    +
  • +

    + Let |bytesPromise| be a new Promise. +

    +
  • +
  • +
    +
    If |data| is a {{BufferSource}}:
    +
    +
      +
    1. +

      + Let |bytes| be the result of + [= get a copy of the buffer source | + getting a copy of the bytes held by =] |data|. +

      +
    2. +
    3. +

      + Resolve |bytesPromise| with |bytes|. +

      +
    4. +
    +
    + Otherwise: +
    +
    +
    +

    + In this case, |data| is an [= async sequence type | async sequence =] of {{BufferSource}}s. +

    +
    +
      +
    1. +

      + Let |bytes| be an empty [= byte sequence =]. +

      +
    2. +
    3. +

      + Let |iterator| be the result of [= open an async sequence | opening =] |data|. +

      +
    4. +
    5. +

      + If an error occurred, reject |bytesPromise| with + |iterator| and terminate these steps. +

      +
    6. +
    7. +

      + Let |getValueSteps| be the following list of steps: +

      +
        +
      1. +

        + Let |next| be the result of [= get an async iterator next value | getting the next value =] of |iterator|. +

        +
      2. +
      3. +

        + [= promise/React =] to |next|: +

        +
        +
        If |next| was rejected with |reason|:
        +
        +
          +
        1. +

          + Reject |bytesPromise| with |reason|. +

          +
        2. +
        +
        +
        If |next| was fulfilled with |value|:
        +
        +
          +
        1. +

          + If |value| is [= end of iteration =], + resolve |bytesPromise| with |bytes| + and terminate these steps. +

          +
        2. +
        3. +

          + Append the result of [= get a copy of the buffer source | + getting a copy of the bytes held by =] |value| + to |bytes|. +

          +
        4. +
        5. +

          + Perform |getValueSteps|. +

          +
        6. +
        +
        +
        +
      4. +
      +
    8. +
    9. +

      + [= Queue a microtask =] to perform |getValueSteps|. +

      +
    10. +
    +
    +

    + The implementation may wish to compute the hash digest + incrementally, instead of waiting until all data is + available, in order to conserve memory. +

    +

    + Additionally, if the |iterator| returned by + [= open an async sequence | opening =] |data| + is the iterator defined by `ReadableStream`, + the implementation may wish to optimize the steps + above, for example by reading the stream directly, + and/or transferring + the stream to the [= in parallel | parallel =] steps below. +

    +
    +
    +
    +
  • Let |realm| be the [= relevant realm =] of [= this =]. @@ -1892,29 +2017,51 @@

    The digest method

  • - Let |digest| be the result of performing the digest - operation specified by |normalizedAlgorithm| using - |algorithm|, with |data| - as |message|. -

    -
  • -
  • -

    - [= Queue a global task =] on the [= crypto task source =], - given |realm|'s global object, to perform the remaining steps. -

    -
  • -
  • -

    - Let |result| be the result of [= ArrayBuffer/create | creating =] an {{ArrayBuffer}} - in |realm|, containing |digest|. -

    -
  • -
  • -

    - Resolve |promise| with - |result|. + [= promise/React =] to |bytesPromise|:

    +
    +
    If |bytesPromise| was rejected with |reason|:
    +
    +
      +
    1. +

      + [= exception/Throw =] |reason|. +

      +
    2. +
    +
    +
    If |bytesPromise| was fulfilled with value |bytes|:
    +
    +
      +
    1. +

      + Let |digest| be the result of performing the digest + operation specified by |normalizedAlgorithm| using + |algorithm|, with |bytes| + as |message|. +

      +
    2. +
    3. +

      + [= Queue a global task =] on the [= crypto task source =], + given |realm|'s global object, to perform the remaining steps. +

      +
    4. +
    5. +

      + Let |result| be the result of [= ArrayBuffer/create | creating =] an {{ArrayBuffer}} + in |realm|, containing |digest|. +

      +
    6. +
    7. +

      + Resolve |promise| with + |result|. +

      +
    8. +
    +
    +
  • From b1a5966daa2dda77aca75675461e14cf45107614 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Mon, 11 Aug 2025 16:57:00 +0200 Subject: [PATCH 2/2] Update spec/Overview.html Co-authored-by: Mattias Buelens <649348+MattiasBuelens@users.noreply.github.com> --- spec/Overview.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Overview.html b/spec/Overview.html index 502e9b9..7063da2 100644 --- a/spec/Overview.html +++ b/spec/Overview.html @@ -1983,7 +1983,7 @@

    The digest method

    is the iterator defined by `ReadableStream`, the implementation may wish to optimize the steps above, for example by reading the stream directly, - and/or transferring + and/or transferring the stream to the [= in parallel | parallel =] steps below.