From c8d039a872ee3b05a7fedfe423497faf75f8969c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Sat, 13 Feb 2021 20:17:39 +0100 Subject: [PATCH] buffer: make Blob's constructor more spec-compliant PR-URL: https://github.com/nodejs/node/pull/37361 Backport-PR-URL: https://github.com/nodejs/node/pull/39704 Fixes: https://github.com/nodejs/node/issues/37352 Fixes: https://github.com/nodejs/node/issues/37356 Reviewed-By: Antoine du Hamel Reviewed-By: James M Snell --- lib/internal/blob.js | 34 ++++++++-------------------------- test/parallel/test-blob.js | 23 ++++++++++------------- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/lib/internal/blob.js b/lib/internal/blob.js index 6ce6c35d8c7da7..927b9f54046bf2 100644 --- a/lib/internal/blob.js +++ b/lib/internal/blob.js @@ -50,7 +50,6 @@ const { const { validateObject, - validateString, isUint32, } = require('internal/validators'); @@ -76,22 +75,10 @@ function getSource(source, encoding) { if (isBlob(source)) return [source.size, source[kHandle]]; - if (typeof source === 'string') { - source = lazyBuffer().from(source, encoding); - } else if (isAnyArrayBuffer(source)) { + if (isAnyArrayBuffer(source)) { source = new Uint8Array(source); } else if (!isArrayBufferView(source)) { - throw new ERR_INVALID_ARG_TYPE( - 'source', - [ - 'string', - 'ArrayBuffer', - 'SharedArrayBuffer', - 'Buffer', - 'TypedArray', - 'DataView' - ], - source); + source = lazyBuffer().from(`${source}`, encoding); } // We copy into a new Uint8Array because the underlying @@ -112,19 +99,16 @@ class InternalBlob extends JSTransferable { } class Blob extends JSTransferable { - constructor(sources = [], options) { + constructor(sources = [], options = {}) { emitExperimentalWarning('buffer.Blob'); if (sources === null || typeof sources[SymbolIterator] !== 'function' || typeof sources === 'string') { throw new ERR_INVALID_ARG_TYPE('sources', 'Iterable', sources); } - if (options !== undefined) - validateObject(options, 'options'); - const { - encoding = 'utf8', - type = '', - } = { ...options }; + validateObject(options, 'options'); + const { encoding = 'utf8' } = options; + let { type = '' } = options; let length = 0; const sources_ = ArrayFrom(sources, (source) => { @@ -133,16 +117,14 @@ class Blob extends JSTransferable { return src; }); - // This is a MIME media type but we're not actively checking the syntax. - // But, to be fair, neither does Chrome. - validateString(type, 'options.type'); - if (!isUint32(length)) throw new ERR_BUFFER_TOO_LARGE(0xFFFFFFFF); super(); this[kHandle] = createBlob(sources_, length); this[kLength] = length; + + type = `${type}`; this[kType] = RegExpPrototypeTest(disallowedTypeCharacters, type) ? '' : StringPrototypeToLowerCase(type); } diff --git a/test/parallel/test-blob.js b/test/parallel/test-blob.js index 4abcab695c5155..0ae0384001a8b0 100644 --- a/test/parallel/test-blob.js +++ b/test/parallel/test-blob.js @@ -23,10 +23,6 @@ assert.throws(() => new Blob({}), { code: 'ERR_INVALID_ARG_TYPE' }); -assert.throws(() => new Blob(['test', 1]), { - code: 'ERR_INVALID_ARG_TYPE' -}); - { const b = new Blob([]); assert(b); @@ -44,15 +40,9 @@ assert.throws(() => new Blob(['test', 1]), { } { - assert.throws(() => new Blob([], { type: 1 }), { - code: 'ERR_INVALID_ARG_TYPE' - }); - assert.throws(() => new Blob([], { type: false }), { - code: 'ERR_INVALID_ARG_TYPE' - }); - assert.throws(() => new Blob([], { type: {} }), { - code: 'ERR_INVALID_ARG_TYPE' - }); + assert.strictEqual(new Blob([], { type: 1 }).type, '1'); + assert.strictEqual(new Blob([], { type: false }).type, 'false'); + assert.strictEqual(new Blob([], { type: {} }).type, '[object object]'); } { @@ -194,3 +184,10 @@ assert.throws(() => new Blob(['test', 1]), { writable: false }); } + +{ + const b = new Blob(['test', 42]); + b.text().then(common.mustCall((text) => { + assert.strictEqual(text, 'test42'); + })); +}