Skip to content

Commit a3ac445

Browse files
daeyeonruyadorno
authored andcommitted
stream: fix isDetachedBuffer validations
Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com PR-URL: #44114 Refs: #43866 Reviewed-By: LiviaMedeiros <livia@cirno.name> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent bce8041 commit a3ac445

3 files changed

Lines changed: 57 additions & 21 deletions

File tree

‎lib/internal/webstreams/readablestream.js‎

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const {
5959
}=require('v8');
6060

6161
const{
62+
validateBuffer,
6263
validateObject,
6364
}=require('internal/validators');
6465

@@ -101,6 +102,7 @@ const {
101102
extractHighWaterMark,
102103
extractSizeAlgorithm,
103104
lazyTransfer,
105+
isDetachedBuffer,
104106
isViewedArrayBufferDetached,
105107
isBrandCheck,
106108
resetQueue,
@@ -658,11 +660,13 @@ class ReadableStreamBYOBRequest {
658660
constviewBuffer=ArrayBufferViewGetBuffer(view);
659661
constviewBufferByteLength=ArrayBufferGetByteLength(viewBuffer);
660662

661-
if(viewByteLength===0||viewBufferByteLength===0){
662-
thrownewERR_INVALID_STATE.TypeError(
663-
'View ArrayBuffer is zero-length or detached');
663+
if(isDetachedBuffer(viewBuffer)){
664+
thrownewERR_INVALID_STATE.TypeError('Viewed ArrayBuffer is detached');
664665
}
665666

667+
assert(viewByteLength>0);
668+
assert(viewBufferByteLength>0);
669+
666670
readableByteStreamControllerRespond(controller,bytesWritten);
667671
}
668672

@@ -681,6 +685,8 @@ class ReadableStreamBYOBRequest {
681685
'This BYOB request has been invalidated');
682686
}
683687

688+
validateBuffer(view,'view');
689+
684690
if(isViewedArrayBufferDetached(view)){
685691
thrownewERR_INVALID_STATE.TypeError('Viewed ArrayBuffer is detached');
686692
}
@@ -894,15 +900,19 @@ class ReadableStreamBYOBReader {
894900
],
895901
view));
896902
}
903+
897904
constviewByteLength=ArrayBufferViewGetByteLength(view);
898905
constviewBuffer=ArrayBufferViewGetBuffer(view);
899906
constviewBufferByteLength=ArrayBufferGetByteLength(viewBuffer);
900907

901908
if(viewByteLength===0||viewBufferByteLength===0){
902909
returnPromiseReject(
903910
newERR_INVALID_STATE.TypeError(
904-
'View ArrayBuffer is zero-length or detached'));
911+
'View or Viewed ArrayBuffer is zero-length or detached',
912+
),
913+
);
905914
}
915+
906916
// Supposed to assert here that the view's buffer is not
907917
// detached, but there's no API available to use to check that.
908918
if(this[kState].stream===undefined){
@@ -2298,11 +2308,10 @@ function readableByteStreamControllerEnqueue(
22982308
if(pendingPullIntos.length){
22992309
constfirstPendingPullInto=pendingPullIntos[0];
23002310

2301-
constpendingBufferByteLength=
2302-
ArrayBufferGetByteLength(firstPendingPullInto.buffer);
2303-
if(pendingBufferByteLength===0){
2311+
if(isDetachedBuffer(firstPendingPullInto.buffer)){
23042312
thrownewERR_INVALID_STATE.TypeError(
2305-
'Destination ArrayBuffer is zero-length or detached');
2313+
'Destination ArrayBuffer is detached',
2314+
);
23062315
}
23072316

23082317
firstPendingPullInto.buffer=
@@ -2501,16 +2510,6 @@ function readableByteStreamControllerRespondWithNewView(controller, view) {
25012510
constdesc=pendingPullIntos[0];
25022511
assert(stream[kState].state!=='errored');
25032512

2504-
if(!isArrayBufferView(view)){
2505-
thrownewERR_INVALID_ARG_TYPE(
2506-
'view',
2507-
[
2508-
'Buffer',
2509-
'TypedArray',
2510-
'DataView',
2511-
],
2512-
view);
2513-
}
25142513
constviewByteLength=ArrayBufferViewGetByteLength(view);
25152514
constviewByteOffset=ArrayBufferViewGetByteOffset(view);
25162515
constviewBuffer=ArrayBufferViewGetBuffer(view);

‎lib/internal/webstreams/util.js‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,13 @@ function transferArrayBuffer(buffer) {
129129
returnres;
130130
}
131131

132-
functionisArrayBufferDetached(buffer){
132+
functionisDetachedBuffer(buffer){
133133
if(ArrayBufferGetByteLength(buffer)===0){
134+
// TODO(daeyeon): Consider using C++ builtin to improve performance.
134135
try{
135136
newUint8Array(buffer);
136-
}catch{
137+
}catch(error){
138+
assert(error.name==='TypeError');
137139
returntrue;
138140
}
139141
}
@@ -143,7 +145,7 @@ function isArrayBufferDetached(buffer) {
143145
functionisViewedArrayBufferDetached(view){
144146
return(
145147
ArrayBufferViewGetByteLength(view)===0&&
146-
isArrayBufferDetached(ArrayBufferViewGetBuffer(view))
148+
isDetachedBuffer(ArrayBufferViewGetBuffer(view))
147149
);
148150
}
149151

@@ -243,6 +245,7 @@ module.exports = {
243245
extractSizeAlgorithm,
244246
lazyTransfer,
245247
isBrandCheck,
248+
isDetachedBuffer,
246249
isPromisePending,
247250
isViewedArrayBufferDetached,
248251
peekQueueValue,

‎test/parallel/test-whatwg-readablebytestream-bad-buffers-and-views.js‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,38 @@ let pass = 0;
5151
reader.read(newUint8Array([4,5,6]));
5252
}
5353

54+
{
55+
conststream=newReadableStream({
56+
start(c){
57+
c.enqueue(newUint8Array([1,2,3]));
58+
},
59+
type: 'bytes',
60+
});
61+
constreader=stream.getReader({mode: 'byob'});
62+
constview=newUint8Array();
63+
assert
64+
.rejects(reader.read(view),{
65+
code: 'ERR_INVALID_STATE',
66+
name: 'TypeError',
67+
})
68+
.then(common.mustCall());
69+
}
70+
71+
{
72+
conststream=newReadableStream({
73+
start(c){
74+
c.enqueue(newUint8Array([1,2,3]));
75+
},
76+
type: 'bytes',
77+
});
78+
constreader=stream.getReader({mode: 'byob'});
79+
constview=newUint8Array(newArrayBuffer(10),0,0);
80+
assert
81+
.rejects(reader.read(view),{
82+
code: 'ERR_INVALID_STATE',
83+
name: 'TypeError',
84+
})
85+
.then(common.mustCall());
86+
}
87+
5488
process.on('exit',()=>assert.strictEqual(pass,2));

0 commit comments

Comments
 (0)