lib: fix sequence argument handling in Blob constructor · nodejs/node@9b95c41
11'use strict';
2233const {
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');
5654const { inspect } = require('internal/util/inspect');
57-const { convertToInt } = require('internal/webidl');
55+const {
56+ converters,
57+ convertToInt,
58+ createSequenceConverter,
59+} = require('internal/webidl');
58605961const {
6062codes: {
6163ERR_BUFFER_TOO_LARGE,
62-ERR_INVALID_ARG_TYPE,
6364ERR_INVALID_ARG_VALUE,
6465ERR_INVALID_STATE,
6566ERR_INVALID_THIS,
@@ -112,7 +113,6 @@ function getSource(source, endings) {
112113if (isAnyArrayBuffer(source)) {
113114source = new Uint8Array(source);
114115} else if (!isArrayBufferView(source)) {
115-source = `${source}`;
116116if (endings === 'native')
117117source = RegExpPrototypeSymbolReplace(/\n|\r\n/g, source, EOL);
118118source = enc.encode(source);
@@ -126,6 +126,13 @@ function getSource(source, endings) {
126126return [byteLength, new Uint8Array(slice)];
127127}
128128129+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+129136class Blob {
130137/**
131138 * @typedef {string|ArrayBuffer|ArrayBufferView|Blob} SourcePart
@@ -142,11 +149,8 @@ class Blob {
142149constructor(sources = [], options) {
143150markTransferMode(this, true, false);
144151145-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+150154validateDictionary(options, 'options');
151155let {
152156 endings = 'transparent',
@@ -158,11 +162,11 @@ class Blob {
158162throw new ERR_INVALID_ARG_VALUE('options.endings', endings);
159163160164let 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);
163167length += len;
164-return src;
165-});
168+sources_[i] = src;
169+}
166170167171if (length > kMaxLength)
168172throw new ERR_BUFFER_TOO_LARGE(kMaxLength);