tc39 / proposal-arraybuffer-base64

TC39 proposal for Uint8Array<->base64/hex

Home Page:https://tc39.github.io/proposal-arraybuffer-base64/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pre-Stage-3 spec review

linusg opened this issue · comments

  • Use of GetOptionsObject from ECMA-402 is good but should go one step further: also borrow GetOption (like Temporal already does), which handles type/value checking and default values. This is unnecessarily verbose given we have an established abstraction:

    - 4. Let alphabet be ? Get(opts, "alphabet").
    - 5. If alphabet is undefined, set alphabet to "base64".
    - 6. If alphabet is not a String, throw a TypeError exception.
    - 7. If alphabet is neither "base64" nor "base64url", throw a TypeError exception.
    + 4. Let alphabet be ? GetOption(opts, "alphabet", "string", « "base64", "base64url" », "base64").

    The main difference here is the lack of a ToString call, which I understand is intentional (see here). Instead of spelling these steps out repeatedly I propose that GetOption is altered to support different coercion behavior instead.

  • Notably the above causes String objects to be rejected as option values. Of course no one will use { alphabet: new String("base64") }, but if provided from elsewhere this might be problematic. If intentional I'd like to see it included in how-we-work (this PR).

  • AllocateTypedArray is being used incorrectly twice, the default prototype must be passed as a string:

    - 12. Let ta be ? AllocateTypedArray("Uint8Array", %Uint8Array%, %Uint8Array.prototype%, resultLength).
    + 12. Let ta be ? AllocateTypedArray("Uint8Array", %Uint8Array%, "%Uint8Array.prototype%", resultLength).
  • ValidateUint8Array should be used consistently, Uint8Array.fromBase64Into() and Uint8Array.fromHexInto() currently perform the same steps manually:

    - 2. Perform ? RequireInternalSlot(into, [[TypedArrayName]]).
    - 3. If into.[[TypedArrayName]] is not "Uint8Array", throw a TypeError exception.
    + 2. Perform ? ValidateUint8Array(into).

    Arguably the AO could also be dropped, replacing two lines with one doesn't seem like a huge win.

  • ValidateUint8Array and GetUint8ArrayBytes are not grouped into the Helpers section, for no apparent reason.

Thanks for the review!

Instead of spelling these steps out repeatedly I propose that GetOption is altered to support different coercion behavior instead.

I agree we should have an AO for reading options without coercing, though I think what we will actually do is have two versions, like GetObject and GetObjectWithCoercion or something. But it's hard to juggle that while all the things are still just proposals, so I'm going to keep it simpler in the spec for the moment.

If intentional I'd like to see it included in how-we-work

It is intentional; I haven't updated the linked PR to cover the case of not coercing objects to non-boolean primitives yet (which was decided only at the last meeting), but I will make sure to explicitly note that this applies to boxed primitives as well.

AllocateTypedArray is being used incorrectly twice

ValidateUint8Array should be used consistently, Uint8Array.fromBase64Into() and Uint8Array.fromHexInto() currently perform the same steps manually:

These were fixed in #39.

ValidateUint8Array and GetUint8ArrayBytes are not grouped into the Helpers section, for no apparent reason.

Ah, yeah, that's just an oversight. But the Helpers section will go away when upstreaming anyway, so I'm not going to worry about the organization for the moment.

I suspect the GetOptionsObject refactor will happen as a separate change upstream at some point so probably fine to close this.