Commit 3d66e5d1 authored by littledan's avatar littledan Committed by Commit bot

Add checks for detached ArrayBuffers to ArrayBuffer.prototype.slice

These checks ensure that a TypeError is thrown, per spec, rather than
a runtime assert failure.

BUG=v8:4964
R=adamk
LOG=Y

Review-Url: https://codereview.chromium.org/1929123002
Cr-Commit-Position: refs/heads/master@{#35885}
parent a4fa471a
...@@ -70,7 +70,9 @@ function ArrayBufferSlice(start, end) { ...@@ -70,7 +70,9 @@ function ArrayBufferSlice(start, end) {
throw MakeTypeError(kIncompatibleMethodReceiver, throw MakeTypeError(kIncompatibleMethodReceiver,
'ArrayBuffer.prototype.slice', result); 'ArrayBuffer.prototype.slice', result);
} }
// TODO(littledan): Check for a detached ArrayBuffer // Checks for detached source/target ArrayBuffers are done inside of
// %ArrayBufferSliceImpl; the reordering of checks does not violate
// the spec because all exceptions thrown are TypeErrors.
if (result === this) { if (result === this) {
throw MakeTypeError(kArrayBufferSpeciesThis); throw MakeTypeError(kArrayBufferSpeciesThis);
} }
......
...@@ -117,6 +117,8 @@ class CallSite { ...@@ -117,6 +117,8 @@ class CallSite {
T(DebuggerType, "Debugger: Parameters have wrong types.") \ T(DebuggerType, "Debugger: Parameters have wrong types.") \
T(DeclarationMissingInitializer, "Missing initializer in % declaration") \ T(DeclarationMissingInitializer, "Missing initializer in % declaration") \
T(DefineDisallowed, "Cannot define property:%, object is not extensible.") \ T(DefineDisallowed, "Cannot define property:%, object is not extensible.") \
T(DetachedOperation, \
"Cannot perform % on a detached ArrayBuffer") \
T(DuplicateTemplateProperty, "Object template has duplicate property '%'") \ T(DuplicateTemplateProperty, "Object template has duplicate property '%'") \
T(ExtendsValueGenerator, \ T(ExtendsValueGenerator, \
"Class extends value % may not be a generator function") \ "Class extends value % may not be a generator function") \
......
...@@ -28,6 +28,14 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) { ...@@ -28,6 +28,14 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1); CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2); CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3); CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
if (source->was_neutered() || target->was_neutered()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kDetachedOperation,
isolate->factory()->NewStringFromAsciiChecked(
"ArrayBuffer.prototype.slice")));
}
RUNTIME_ASSERT(!source.is_identical_to(target)); RUNTIME_ASSERT(!source.is_identical_to(target));
size_t start = 0, target_length = 0; size_t start = 0, target_length = 0;
RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start)); RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
......
...@@ -119,7 +119,7 @@ bytecodes: [ ...@@ -119,7 +119,7 @@ bytecodes: [
B(TestEqualStrict), R(12), B(TestEqualStrict), R(12),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129), B(Wide), B(LdaSmi), U16(130),
B(Star), R(12), B(Star), R(12),
B(LdaConstant), U8(8), B(LdaConstant), U8(8),
B(Star), R(13), B(Star), R(13),
...@@ -302,7 +302,7 @@ bytecodes: [ ...@@ -302,7 +302,7 @@ bytecodes: [
B(TestEqualStrict), R(13), B(TestEqualStrict), R(13),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129), B(Wide), B(LdaSmi), U16(130),
B(Star), R(13), B(Star), R(13),
B(LdaConstant), U8(8), B(LdaConstant), U8(8),
B(Star), R(14), B(Star), R(14),
...@@ -499,7 +499,7 @@ bytecodes: [ ...@@ -499,7 +499,7 @@ bytecodes: [
B(TestEqualStrict), R(12), B(TestEqualStrict), R(12),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129), B(Wide), B(LdaSmi), U16(130),
B(Star), R(12), B(Star), R(12),
B(LdaConstant), U8(8), B(LdaConstant), U8(8),
B(Star), R(13), B(Star), R(13),
...@@ -686,7 +686,7 @@ bytecodes: [ ...@@ -686,7 +686,7 @@ bytecodes: [
B(TestEqualStrict), R(11), B(TestEqualStrict), R(11),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129), B(Wide), B(LdaSmi), U16(130),
B(Star), R(11), B(Star), R(11),
B(LdaConstant), U8(10), B(LdaConstant), U8(10),
B(Star), R(12), B(Star), R(12),
......
...@@ -501,7 +501,7 @@ bytecodes: [ ...@@ -501,7 +501,7 @@ bytecodes: [
B(TestEqualStrict), R(10), B(TestEqualStrict), R(10),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129), B(Wide), B(LdaSmi), U16(130),
B(Star), R(10), B(Star), R(10),
B(LdaConstant), U8(14), B(LdaConstant), U8(14),
B(Star), R(11), B(Star), R(11),
......
...@@ -724,7 +724,7 @@ bytecodes: [ ...@@ -724,7 +724,7 @@ bytecodes: [
B(InvokeIntrinsic), U16(Runtime::k_IsJSReceiver), R(3), U8(1), B(InvokeIntrinsic), U16(Runtime::k_IsJSReceiver), R(3), U8(1),
B(JumpIfToBooleanFalse), U8(4), B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(16), B(Jump), U8(16),
B(LdaSmi), U8(60), B(LdaSmi), U8(61),
B(Star), R(3), B(Star), R(3),
B(LdaConstant), U8(0), B(LdaConstant), U8(0),
B(Star), R(4), B(Star), R(4),
......
...@@ -41,19 +41,21 @@ assertThrows(function() { ...@@ -41,19 +41,21 @@ assertThrows(function() {
var buffer5 = new ArrayBuffer(100 * 1024); var buffer5 = new ArrayBuffer(100 * 1024);
var buffer6 = buffer5.slice({valueOf : function() { assertThrows(function() {
%ArrayBufferNeuter(buffer5); buffer5.slice({valueOf : function() {
return 0; %ArrayBufferNeuter(buffer5);
}}, 100 * 1024 * 1024); return 0;
assertEquals(0, buffer6.byteLength); }}, 100 * 1024 * 1024);
}, TypeError);
var buffer7 = new ArrayBuffer(100 * 1024 * 1024); var buffer7 = new ArrayBuffer(100 * 1024 * 1024);
var buffer8 = buffer7.slice(0, {valueOf : function() { assertThrows(function() {
%ArrayBufferNeuter(buffer7); buffer7.slice(0, {valueOf : function() {
return 100 * 1024 * 1024; %ArrayBufferNeuter(buffer7);
}}); return 100 * 1024 * 1024;
assertEquals(0, buffer8.byteLength); }});
}, TypeError);
var buffer9 = new ArrayBuffer(1024); var buffer9 = new ArrayBuffer(1024);
var array9 = new Uint8Array(buffer9); var array9 = new Uint8Array(buffer9);
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Neutered source
var ab = new ArrayBuffer(10);
ab.constructor = { get [Symbol.species]() { %ArrayBufferNeuter(ab); return ArrayBuffer; } };
assertThrows(() => ab.slice(0), TypeError);
// Neutered target
class NeuteredArrayBuffer extends ArrayBuffer {
constructor(...args) {
super(...args);
%ArrayBufferNeuter(this);
}
}
var ab2 = new ArrayBuffer(10);
ab2.constructor = NeuteredArrayBuffer;
assertThrows(() => ab2.slice(0), TypeError);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment