◐ Shell
clean mode source ↗

lib: reject SharedArrayBuffer in web APIs per spec · nodejs/node@3d18162

1+

'use strict';

2+

// Flags: --expose-internals

3+

const common = require('../common');

4+

const assert = require('assert');

5+

const test = require('node:test');

6+

const { ReadableStream } = require('stream/web');

7+8+

const sab = new SharedArrayBuffer(8);

9+

const sabView = new Uint8Array(sab);

10+

const sabDataView = new DataView(sab);

11+12+

// -- ReadableStreamBYOBReader.read() --

13+14+

test('ReadableStreamBYOBReader.read() rejects SAB-backed Uint8Array', async () => {

15+

const rs = new ReadableStream({

16+

type: 'bytes',

17+

pull(controller) {

18+

controller.enqueue(new Uint8Array([1, 2, 3]));

19+

},

20+

});

21+

const reader = rs.getReader({ mode: 'byob' });

22+

await assert.rejects(

23+

reader.read(new Uint8Array(sab)),

24+

{ code: 'ERR_INVALID_ARG_VALUE' },

25+

);

26+

reader.releaseLock();

27+

});

28+29+

test('ReadableStreamBYOBReader.read() rejects SAB-backed DataView', async () => {

30+

const rs = new ReadableStream({

31+

type: 'bytes',

32+

pull(controller) {

33+

controller.enqueue(new Uint8Array([1, 2, 3]));

34+

},

35+

});

36+

const reader = rs.getReader({ mode: 'byob' });

37+

await assert.rejects(

38+

reader.read(sabDataView),

39+

{ code: 'ERR_INVALID_ARG_VALUE' },

40+

);

41+

reader.releaseLock();

42+

});

43+44+

test('ReadableStreamBYOBReader.read() accepts regular view', async () => {

45+

const rs = new ReadableStream({

46+

type: 'bytes',

47+

pull(controller) {

48+

controller.enqueue(new Uint8Array([1, 2, 3]));

49+

},

50+

});

51+

const reader = rs.getReader({ mode: 'byob' });

52+

const { value, done } = await reader.read(new Uint8Array(3));

53+

assert.strictEqual(done, false);

54+

assert.deepStrictEqual(value, new Uint8Array([1, 2, 3]));

55+

reader.releaseLock();

56+

});

57+58+

// -- ReadableByteStreamController.enqueue() --

59+60+

test('ReadableByteStreamController.enqueue() rejects SAB-backed Uint8Array', async () => {

61+

const sabForEnqueue = new SharedArrayBuffer(4);

62+

const sabViewForEnqueue = new Uint8Array(sabForEnqueue);

63+

sabViewForEnqueue[0] = 42;

64+65+

const rs = new ReadableStream({

66+

type: 'bytes',

67+

pull: common.mustCall((controller) => {

68+

assert.throws(

69+

() => controller.enqueue(sabViewForEnqueue),

70+

{ code: 'ERR_INVALID_ARG_VALUE' },

71+

);

72+

controller.enqueue(new Uint8Array([1]));

73+

}),

74+

});

75+

const reader = rs.getReader();

76+

const { value } = await reader.read();

77+

assert.deepStrictEqual(value, new Uint8Array([1]));

78+

reader.releaseLock();

79+

});

80+81+

test('ReadableByteStreamController.enqueue() rejects SAB-backed DataView', async () => {

82+

const sabForDv = new SharedArrayBuffer(4);

83+

const dvForEnqueue = new DataView(sabForDv);

84+85+

const rs = new ReadableStream({

86+

type: 'bytes',

87+

pull: common.mustCall((controller) => {

88+

assert.throws(

89+

() => controller.enqueue(dvForEnqueue),

90+

{ code: 'ERR_INVALID_ARG_VALUE' },

91+

);

92+

controller.enqueue(new Uint8Array([2]));

93+

}),

94+

});

95+

const reader = rs.getReader();

96+

const { value } = await reader.read();

97+

assert.deepStrictEqual(value, new Uint8Array([2]));

98+

reader.releaseLock();

99+

});

100+101+

// -- SharedWebIDL converters --

102+103+

const { converters } = require('internal/webidl');

104+105+

test('webidl converters.BufferSource rejects SharedArrayBuffer', () => {

106+

assert.throws(

107+

() => converters.BufferSource(sab),

108+

{ code: 'ERR_INVALID_ARG_TYPE' },

109+

);

110+

});

111+112+

test('webidl converters.BufferSource rejects SAB-backed Uint8Array', () => {

113+

assert.throws(

114+

() => converters.BufferSource(sabView),

115+

{ code: 'ERR_INVALID_ARG_TYPE' },

116+

);

117+

});

118+119+

test('webidl converters.BufferSource rejects SAB-backed DataView', () => {

120+

assert.throws(

121+

() => converters.BufferSource(sabDataView),

122+

{ code: 'ERR_INVALID_ARG_TYPE' },

123+

);

124+

});

125+126+

test('webidl converters.BufferSource accepts ArrayBuffer', () => {

127+

const ab = new ArrayBuffer(4);

128+

assert.strictEqual(converters.BufferSource(ab), ab);

129+

});

130+131+

test('webidl converters.BufferSource accepts regular TypedArray', () => {

132+

const ta = new Uint8Array(4);

133+

assert.strictEqual(converters.BufferSource(ta), ta);

134+

});

135+136+

test('webidl converters.ArrayBufferView rejects SAB-backed Uint8Array', () => {

137+

assert.throws(

138+

() => converters.ArrayBufferView(sabView),

139+

{ code: 'ERR_INVALID_ARG_TYPE' },

140+

);

141+

});

142+143+

test('webidl converters.ArrayBufferView rejects SAB-backed DataView', () => {

144+

assert.throws(

145+

() => converters.ArrayBufferView(sabDataView),

146+

{ code: 'ERR_INVALID_ARG_TYPE' },

147+

);

148+

});

149+150+

test('webidl converters.ArrayBufferView rejects non-view', () => {

151+

assert.throws(

152+

() => converters.ArrayBufferView('not a view'),

153+

{ code: 'ERR_INVALID_ARG_TYPE' },

154+

);

155+

});

156+157+

test('webidl converters.ArrayBufferView accepts regular Uint8Array', () => {

158+

const ta = new Uint8Array(4);

159+

assert.strictEqual(converters.ArrayBufferView(ta), ta);

160+

});

161+162+

test('webidl converters.ArrayBufferView accepts regular DataView', () => {

163+

const dv = new DataView(new ArrayBuffer(4));

164+

assert.strictEqual(converters.ArrayBufferView(dv), dv);

165+

});