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) {
throw MakeTypeError(kIncompatibleMethodReceiver,
'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) {
throw MakeTypeError(kArrayBufferSpeciesThis);
}
......
......@@ -117,6 +117,8 @@ class CallSite {
T(DebuggerType, "Debugger: Parameters have wrong types.") \
T(DeclarationMissingInitializer, "Missing initializer in % declaration") \
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(ExtendsValueGenerator, \
"Class extends value % may not be a generator function") \
......
......@@ -28,6 +28,14 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
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));
size_t start = 0, target_length = 0;
RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
......
......@@ -119,7 +119,7 @@ bytecodes: [
B(TestEqualStrict), R(12),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(12),
B(LdaConstant), U8(8),
B(Star), R(13),
......@@ -302,7 +302,7 @@ bytecodes: [
B(TestEqualStrict), R(13),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(13),
B(LdaConstant), U8(8),
B(Star), R(14),
......@@ -499,7 +499,7 @@ bytecodes: [
B(TestEqualStrict), R(12),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(12),
B(LdaConstant), U8(8),
B(Star), R(13),
......@@ -686,7 +686,7 @@ bytecodes: [
B(TestEqualStrict), R(11),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(11),
B(LdaConstant), U8(10),
B(Star), R(12),
......
......@@ -501,7 +501,7 @@ bytecodes: [
B(TestEqualStrict), R(10),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Wide), B(LdaSmi), U16(130),
B(Star), R(10),
B(LdaConstant), U8(14),
B(Star), R(11),
......
......@@ -724,7 +724,7 @@ bytecodes: [
B(InvokeIntrinsic), U16(Runtime::k_IsJSReceiver), R(3), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(16),
B(LdaSmi), U8(60),
B(LdaSmi), U8(61),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(4),
......
......@@ -41,19 +41,21 @@ assertThrows(function() {
var buffer5 = new ArrayBuffer(100 * 1024);
var buffer6 = buffer5.slice({valueOf : function() {
%ArrayBufferNeuter(buffer5);
return 0;
}}, 100 * 1024 * 1024);
assertEquals(0, buffer6.byteLength);
assertThrows(function() {
buffer5.slice({valueOf : function() {
%ArrayBufferNeuter(buffer5);
return 0;
}}, 100 * 1024 * 1024);
}, TypeError);
var buffer7 = new ArrayBuffer(100 * 1024 * 1024);
var buffer8 = buffer7.slice(0, {valueOf : function() {
%ArrayBufferNeuter(buffer7);
return 100 * 1024 * 1024;
}});
assertEquals(0, buffer8.byteLength);
assertThrows(function() {
buffer7.slice(0, {valueOf : function() {
%ArrayBufferNeuter(buffer7);
return 100 * 1024 * 1024;
}});
}, TypeError);
var buffer9 = new ArrayBuffer(1024);
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