Skip to content

Commit e49b938

Browse files
committed
Added missing detached array checks.
1 parent 2e248ea commit e49b938

File tree

9 files changed

+102
-0
lines changed

9 files changed

+102
-0
lines changed

src/njs_buffer.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,6 +1913,11 @@ njs_buffer_fill_typed_array(njs_vm_t *vm, const njs_value_t *value,
19131913
buffer = njs_typed_array_buffer(array);
19141914

19151915
arr_from = njs_typed_array(value);
1916+
if (njs_slow_path(njs_is_detached_buffer(arr_from->buffer))) {
1917+
njs_type_error(vm, "detached buffer");
1918+
return NJS_ERROR;
1919+
}
1920+
19161921
byte_length = arr_from->byte_length;
19171922
from = &njs_typed_array_buffer(arr_from)->u.u8[arr_from->offset];
19181923

src/njs_encoding.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
199199
end = start + str.length;
200200

201201
array = njs_typed_array(dest);
202+
if (njs_slow_path(njs_is_detached_buffer(array->buffer))) {
203+
njs_type_error(vm, "detached buffer");
204+
return NJS_ERROR;
205+
}
206+
202207
to = njs_typed_array_start(array);
203208
to_end = to + array->byte_length;
204209

@@ -512,6 +517,10 @@ njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
512517

513518
if (njs_is_typed_array(value)) {
514519
array = njs_typed_array(value);
520+
if (njs_slow_path(njs_is_detached_buffer(array->buffer))) {
521+
njs_type_error(vm, "detached buffer");
522+
return NJS_ERROR;
523+
}
515524

516525
start = njs_typed_array_start(array);
517526
end = start + array->byte_length;

src/njs_object.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,11 @@ njs_object_enumerate_typed_array(njs_vm_t *vm, const njs_typed_array_t *array,
661661
njs_value_t *item;
662662
njs_array_t *entry;
663663

664+
if (njs_slow_path(njs_is_detached_buffer(array->buffer))) {
665+
njs_type_error(vm, "detached buffer");
666+
return NJS_ERROR;
667+
}
668+
664669
length = njs_typed_array_length(array);
665670

666671
ret = njs_array_expand(vm, items, 0, length);

src/njs_typed_array.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,6 +2070,11 @@ njs_typed_array_to_chain(njs_vm_t *vm, njs_chb_t *chain,
20702070
uint32_t i;
20712071
njs_string_prop_t separator;
20722072

2073+
if (njs_slow_path(njs_is_detached_buffer(array->buffer))) {
2074+
njs_chb_append(chain, "<detached buffer>", 18);
2075+
return;
2076+
}
2077+
20732078
if (sep != NULL && njs_is_string(sep)) {
20742079
(void) njs_string_prop(vm, &separator, sep);
20752080

src/test/njs_unit_test.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6259,6 +6259,11 @@ static njs_unit_test_t njs_test[] =
62596259
" try {a.set(init,Infinity)} catch (e) {return e.name == 'RangeError'};})"),
62606260
njs_str("true") },
62616261

6262+
{ njs_str(NJS_INT_TYPED_ARRAY_LIST
6263+
".map(v=>{try { var a = new v(1); $262.detachArrayBuffer(a.buffer); Object.entries(a)} "
6264+
"catch (e) {return e.name}}).every(v=>v === 'TypeError')"),
6265+
njs_str("true") },
6266+
62626267
{ njs_str("[-1,-1.00001,-Infinity]"
62636268
".every(v=>{ try {(new Uint8Array(10)).set([], v)} catch (ee) {return ee.name === 'RangeError'}})"),
62646269
njs_str("true") },

test/buffer.t.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ let fill_tsuite = {
254254
name: "buf.fill() tests",
255255
skip: () => (!has_buffer()),
256256
T: async (params) => {
257+
if (params.detach_value) {
258+
detach(params.value.buffer);
259+
}
260+
257261
let r = params.buf.fill(params.value, params.offset, params.end);
258262

259263
if (r.toString() !== params.expected) {
@@ -274,6 +278,8 @@ let fill_tsuite = {
274278
exception: 'TypeError: "utf-128" encoding is not supported' },
275279
{ buf: Buffer.from('abc'), value: 'ABCD', offset: 1, expected: 'aAB' },
276280
{ buf: Buffer.from('abc'), value: Buffer.from('def'), expected: 'def' },
281+
{ buf: Buffer.from('abc'), value: Buffer.from('def'), detach_value: true,
282+
exception: 'TypeError: detached buffer' },
277283
{ buf: Buffer.from('def'),
278284
value: Buffer.from(new Uint8Array([0x60, 0x61, 0x62, 0x63]).buffer, 1),
279285
expected: 'abc' },

test/harness/runTsuite.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,10 @@ function merge(to, from) {
9595
return r;
9696
}
9797

98+
function detach(ab) {
99+
$262.detachArrayBuffer(ab);
100+
}
101+
102+
function is_detach_available() {
103+
return (typeof $262 !== 'undefined' && typeof $262.detachArrayBuffer === 'function');
104+
}

test/text_decoder.t.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,40 @@ let ignoreBOM_tsuite = {
133133
],
134134
};
135135

136+
let detached_tsuite = {
137+
name: "TextDecoder() detached buffer test",
138+
skip: () => !is_detach_available(),
139+
140+
T: async (params) => {
141+
let td = new TextDecoder('utf-8');
142+
let uint8 = new Uint8Array([0]);
143+
144+
detach(uint8.buffer);
145+
146+
try {
147+
td.decode(uint8);
148+
149+
} catch (e) {
150+
if (e.toString().startsWith('TypeError:')) {
151+
return 'SUCCESS';
152+
} else {
153+
throw e;
154+
}
155+
}
156+
157+
throw Error('Expected TypeError not thrown');
158+
},
159+
160+
tests: [
161+
{ },
162+
],
163+
};
164+
136165

137166
run([
138167
stream_tsuite,
139168
fatal_tsuite,
140169
ignoreBOM_tsuite,
170+
detached_tsuite,
141171
])
142172
.then($DONE, $DONE);

test/text_encoder.t.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,38 @@ let encodeinto_tsuite = {
6767
],
6868
};
6969

70+
let detached_tsuite = {
71+
name: "TextEncoder() with detached buffer tests",
72+
skip: () => (!is_detach_available()),
73+
74+
T: async (params) => {
75+
let td = new TextEncoder();
76+
let uint8 = new Uint8Array(10);
77+
78+
detach(uint8.buffer);
79+
80+
try {
81+
td.encodeInto("test", uint8);
82+
83+
} catch (e) {
84+
if (e.toString().startsWith('TypeError:')) {
85+
return 'SUCCESS';
86+
} else {
87+
throw e;
88+
}
89+
}
90+
91+
throw Error('Expected TypeError not thrown');
92+
},
93+
94+
tests: [
95+
{ },
96+
],
97+
};
98+
7099
run([
71100
encode_tsuite,
72101
encodeinto_tsuite,
102+
detached_tsuite,
73103
])
74104
.then($DONE, $DONE);

0 commit comments

Comments
 (0)