Skip to content

Commit

Permalink
buffer: make Blob's constructor more spec-compliant
Browse files Browse the repository at this point in the history
PR-URL: nodejs#37361
Fixes: nodejs#37352
Fixes: nodejs#37356
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
targos committed Aug 8, 2021
1 parent 884e691 commit 6f27c02
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 39 deletions.
34 changes: 8 additions & 26 deletions lib/internal/blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ const {

const {
validateObject,
validateString,
isUint32,
} = require('internal/validators');

Expand All @@ -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
Expand All @@ -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) => {
Expand All @@ -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);
}
Expand Down
23 changes: 10 additions & 13 deletions test/parallel/test-blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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]');
}

{
Expand Down Expand Up @@ -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');
}));
}

0 comments on commit 6f27c02

Please sign in to comment.