Skip to content

Commit a60df87

Browse files
authored
Normative: prohibit using setFromBase64/setFromHex on immutable-backed Uint8Arrays (#62)
1 parent 6c051ce commit a60df87

2 files changed

Lines changed: 86 additions & 1 deletion

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
},
1717
"license": "MIT",
1818
"devDependencies": {
19-
"@tc39/ecma262-biblio": "2.1.2862",
19+
"@tc39/ecma262-biblio": "2.1.3025",
2020
"ecmarkup": "^21.2.0",
2121
"jsdom": "^25.0.1",
2222
"parse5-html-rewriting-stream": "^7.0.0",

spec.emu

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,91 @@ markEffects: true
590590
</emu-clause>
591591
</emu-clause>
592592
</emu-clause>
593+
594+
<emu-clause id="sec-uint8array">
595+
<h1>Uint8Array Objects</h1>
596+
597+
<emu-clause id="sec-additional-properties-of-the-uint8array-prototype-object" number="2">
598+
<h1>Additional Properties of the Uint8Array Prototype Object</h1>
599+
600+
<emu-clause id="sec-uint8array.prototype.setfrombase64">
601+
<h1>Uint8Array.prototype.setFromBase64 ( _string_ [ , _options_ ] )</h1>
602+
<emu-alg>
603+
1. Let _into_ be the *this* value.
604+
1. Perform ? ValidateUint8Array(_into_<ins>, ~write~</ins>).
605+
1. If _string_ is not a String, throw a *TypeError* exception.
606+
1. Let _opts_ be ? GetOptionsObject(_options_).
607+
1. Let _alphabet_ be ? Get(_opts_, *"alphabet"*).
608+
1. If _alphabet_ is *undefined*, set _alphabet_ to *"base64"*.
609+
1. If _alphabet_ is neither *"base64"* nor *"base64url"*, throw a *TypeError* exception.
610+
1. Let _lastChunkHandling_ be ? Get(_opts_, *"lastChunkHandling"*).
611+
1. If _lastChunkHandling_ is *undefined*, set _lastChunkHandling_ to *"loose"*.
612+
1. If _lastChunkHandling_ is not one of *"loose"*, *"strict"*, or *"stop-before-partial"*, throw a *TypeError* exception.
613+
1. Let _taRecord_ be MakeTypedArrayWithBufferWitnessRecord(_into_, ~seq-cst~).
614+
1. If IsTypedArrayOutOfBounds(_taRecord_) is *true*, throw a *TypeError* exception.
615+
1. Let _byteLength_ be TypedArrayLength(_taRecord_).
616+
1. Let _result_ be FromBase64(_string_, _alphabet_, _lastChunkHandling_, _byteLength_).
617+
1. Let _bytes_ be _result_.[[Bytes]].
618+
1. Let _written_ be the number of elements in _bytes_.
619+
1. NOTE: FromBase64 does not invoke any user code, so the ArrayBuffer backing _into_ cannot have been detached or shrunk.
620+
1. Assert: _written_ ≤ _byteLength_.
621+
1. Perform SetUint8ArrayBytes(_into_, _bytes_).
622+
1. If _result_.[[Error]] is not ~none~, then
623+
1. Return ThrowCompletion(_result_.[[Error]]).
624+
1. Let _resultObject_ be OrdinaryObjectCreate(%Object.prototype%).
625+
1. Perform ! CreateDataPropertyOrThrow(_resultObject_, *"read"*, 𝔽(_result_.[[Read]])).
626+
1. Perform ! CreateDataPropertyOrThrow(_resultObject_, *"written"*, 𝔽(_written_)).
627+
1. Return _resultObject_.
628+
</emu-alg>
629+
</emu-clause>
630+
631+
<emu-clause id="sec-uint8array.prototype.setfromhex">
632+
<h1>Uint8Array.prototype.setFromHex ( _string_ )</h1>
633+
<emu-alg>
634+
1. Let _into_ be the *this* value.
635+
1. Perform ? ValidateUint8Array(_into_<ins>, ~write~</ins>).
636+
1. If _string_ is not a String, throw a *TypeError* exception.
637+
1. Let _taRecord_ be MakeTypedArrayWithBufferWitnessRecord(_into_, ~seq-cst~).
638+
1. If IsTypedArrayOutOfBounds(_taRecord_) is *true*, throw a *TypeError* exception.
639+
1. Let _byteLength_ be TypedArrayLength(_taRecord_).
640+
1. Let _result_ be FromHex(_string_, _byteLength_).
641+
1. Let _bytes_ be _result_.[[Bytes]].
642+
1. Let _written_ be the number of elements in _bytes_.
643+
1. NOTE: FromHex does not invoke any user code, so the ArrayBuffer backing _into_ cannot have been detached or shrunk.
644+
1. Assert: _written_ ≤ _byteLength_.
645+
1. Perform SetUint8ArrayBytes(_into_, _bytes_).
646+
1. If _result_.[[Error]] is not ~none~, then
647+
1. Return ThrowCompletion(_result_.[[Error]]).
648+
1. Let _resultObject_ be OrdinaryObjectCreate(%Object.prototype%).
649+
1. Perform ! CreateDataPropertyOrThrow(_resultObject_, *"read"*, 𝔽(_result_.[[Read]])).
650+
1. Perform ! CreateDataPropertyOrThrow(_resultObject_, *"written"*, 𝔽(_written_)).
651+
1. Return _resultObject_.
652+
</emu-alg>
653+
</emu-clause>
654+
</emu-clause>
655+
656+
<emu-clause id="sec-abstract-operations-for-uint8array-objects">
657+
<h1>Abstract Operations for Uint8Array Objects</h1>
658+
659+
<emu-clause id="sec-validateuint8array" type="abstract operation">
660+
<h1>
661+
ValidateUint8Array (
662+
_ta_: an ECMAScript language value,
663+
<ins>optional _accessMode_: ~read~ or ~write~,</ins>
664+
): either a normal completion containing ~unused~ or a throw completion
665+
</h1>
666+
<dl class="header"></dl>
667+
<emu-alg>
668+
1. <ins>If _accessMode_ is not present, set _accessMode_ to ~read~.</ins>
669+
1. Perform ? RequireInternalSlot(_ta_, [[TypedArrayName]]).
670+
1. If _ta_.[[TypedArrayName]] is not *"Uint8Array"*, throw a *TypeError* exception.
671+
1. <ins>Assert: _ta_ has a [[ViewedArrayBuffer]] internal slot.</ins>
672+
1. <ins>If _accessMode_ is ~write~ and IsImmutableBuffer(_ta_.[[ViewedArrayBuffer]]) is *true*, throw a *TypeError* exception.</ins>
673+
1. Return ~unused~.
674+
</emu-alg>
675+
</emu-clause>
676+
</emu-clause>
677+
</emu-clause>
593678
</emu-clause>
594679

595680
<emu-clause id="sec-structured-data" number="25">

0 commit comments

Comments
 (0)