Skip to content

Commit 43be7a6

Browse files
committed
lib: fix sequence argument handling in Blob constructor
This uses the existing WebIDL infrastructure to handle the iteration over the argument correctly according to the specification. Note that we can't avoid looping over the input twice: we only know the value of the 'endings' option after converting the blob parts into an array.
1 parent 70b3570 commit 43be7a6

File tree

2 files changed

+18
-22
lines changed

2 files changed

+18
-22
lines changed

lib/internal/blob.js

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
const {
4-
ArrayFrom,
54
MathMax,
65
MathMin,
76
ObjectDefineProperties,
@@ -15,7 +14,6 @@ const {
1514
StringPrototypeSplit,
1615
StringPrototypeToLowerCase,
1716
Symbol,
18-
SymbolIterator,
1917
SymbolToStringTag,
2018
Uint8Array,
2119
} = primordials;
@@ -54,12 +52,15 @@ const {
5452
lazyDOMException,
5553
} = require('internal/util');
5654
const { inspect } = require('internal/util/inspect');
57-
const { convertToInt } = require('internal/webidl');
55+
const {
56+
converters,
57+
convertToInt,
58+
createSequenceConverter,
59+
} = require('internal/webidl');
5860

5961
const {
6062
codes: {
6163
ERR_BUFFER_TOO_LARGE,
62-
ERR_INVALID_ARG_TYPE,
6364
ERR_INVALID_ARG_VALUE,
6465
ERR_INVALID_STATE,
6566
ERR_INVALID_THIS,
@@ -112,7 +113,6 @@ function getSource(source, endings) {
112113
if (isAnyArrayBuffer(source)) {
113114
source = new Uint8Array(source);
114115
} else if (!isArrayBufferView(source)) {
115-
source = `${source}`;
116116
if (endings === 'native')
117117
source = RegExpPrototypeSymbolReplace(/\n|\r\n/g, source, EOL);
118118
source = enc.encode(source);
@@ -126,6 +126,13 @@ function getSource(source, endings) {
126126
return [byteLength, new Uint8Array(slice)];
127127
}
128128

129+
const sourcesConverter = createSequenceConverter((source, opts = kEmptyObject) => {
130+
if (isBlob(source) || isAnyArrayBuffer(source) || isArrayBufferView(source)) {
131+
return source;
132+
}
133+
return converters.DOMString(source, opts);
134+
});
135+
129136
class Blob {
130137
/**
131138
* @typedef {string|ArrayBuffer|ArrayBufferView|Blob} SourcePart
@@ -142,11 +149,8 @@ class Blob {
142149
constructor(sources = [], options) {
143150
markTransferMode(this, true, false);
144151

145-
if (sources === null ||
146-
typeof sources[SymbolIterator] !== 'function' ||
147-
typeof sources === 'string') {
148-
throw new ERR_INVALID_ARG_TYPE('sources', 'a sequence', sources);
149-
}
152+
const sources_ = sourcesConverter(sources);
153+
150154
validateDictionary(options, 'options');
151155
let {
152156
endings = 'transparent',
@@ -158,11 +162,11 @@ class Blob {
158162
throw new ERR_INVALID_ARG_VALUE('options.endings', endings);
159163

160164
let length = 0;
161-
const sources_ = ArrayFrom(sources, (source) => {
162-
const { 0: len, 1: src } = getSource(source, endings);
165+
for (let i = 0; i < sources_.length; ++i) {
166+
const { 0: len, 1: src } = getSource(sources_[i], endings);
163167
length += len;
164-
return src;
165-
});
168+
sources_[i] = src;
169+
}
166170

167171
if (length > kMaxLength)
168172
throw new ERR_BUFFER_TOO_LARGE(kMaxLength);

test/wpt/status/FileAPI/blob.json

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,6 @@
44
},
55
"Blob-constructor.any.js": {
66
"fail": {
7-
"expected": [
8-
"blobParts not an object: boolean with Boolean.prototype[Symbol.iterator]",
9-
"blobParts not an object: number with Number.prototype[Symbol.iterator]",
10-
"blobParts not an object: BigInt with BigInt.prototype[Symbol.iterator]",
11-
"blobParts not an object: Symbol with Symbol.prototype[Symbol.iterator]",
12-
"Getters and value conversions should happen in order until an exception is thrown.",
13-
"Arguments should be evaluated from left to right."
14-
],
157
"flaky": [
168
"Passing typed arrays as elements of the blobParts array should work.",
179
"Passing a Float16Array as element of the blobParts array should work.",

0 commit comments

Comments
 (0)