Never freeze/seal/preventExtensions objects with interceptors
BUG=v8:6163 R=verwaest@chromium.org Change-Id: Ieaec78c806cc3d459488a8491e77b7b5a8047079 Reviewed-on: https://chromium-review.googlesource.com/461903 Commit-Queue: Jochen Eisinger <jochen@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#44228}
This commit is contained in:
parent
1cbda23565
commit
f8deca1c86
@ -4599,8 +4599,8 @@ Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
|
|||||||
auto self = Utils::OpenHandle(this);
|
auto self = Utils::OpenHandle(this);
|
||||||
i::JSReceiver::IntegrityLevel i_level =
|
i::JSReceiver::IntegrityLevel i_level =
|
||||||
level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
|
level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
|
||||||
Maybe<bool> result =
|
Maybe<bool> result = i::JSReceiver::SetIntegrityLevel(
|
||||||
i::JSReceiver::SetIntegrityLevel(self, i_level, i::Object::DONT_THROW);
|
self, i_level, i::Object::THROW_ON_ERROR);
|
||||||
has_pending_exception = result.IsNothing();
|
has_pending_exception = result.IsNothing();
|
||||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
||||||
return result;
|
return result;
|
||||||
|
@ -280,8 +280,10 @@ class ErrorUtils : public AllStatic {
|
|||||||
T(CallSiteMethod, "CallSite method % expects CallSite as receiver") \
|
T(CallSiteMethod, "CallSite method % expects CallSite as receiver") \
|
||||||
T(CannotConvertToPrimitive, "Cannot convert object to primitive value") \
|
T(CannotConvertToPrimitive, "Cannot convert object to primitive value") \
|
||||||
T(CannotPreventExt, "Cannot prevent extensions") \
|
T(CannotPreventExt, "Cannot prevent extensions") \
|
||||||
|
T(CannotFreeze, "Cannot freeze") \
|
||||||
T(CannotFreezeArrayBufferView, \
|
T(CannotFreezeArrayBufferView, \
|
||||||
"Cannot freeze array buffer views with elements") \
|
"Cannot freeze array buffer views with elements") \
|
||||||
|
T(CannotSeal, "Cannot seal") \
|
||||||
T(CircularStructure, "Converting circular structure to JSON") \
|
T(CircularStructure, "Converting circular structure to JSON") \
|
||||||
T(ConstructAbstractClass, "Abstract class % not directly constructable") \
|
T(ConstructAbstractClass, "Abstract class % not directly constructable") \
|
||||||
T(ConstAssign, "Assignment to constant variable.") \
|
T(ConstAssign, "Assignment to constant variable.") \
|
||||||
|
@ -7541,6 +7541,12 @@ Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
|
|||||||
should_throw);
|
should_throw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (object->map()->has_named_interceptor() ||
|
||||||
|
object->map()->has_indexed_interceptor()) {
|
||||||
|
RETURN_FAILURE(isolate, should_throw,
|
||||||
|
NewTypeError(MessageTemplate::kCannotPreventExt));
|
||||||
|
}
|
||||||
|
|
||||||
if (!object->HasFixedTypedArrayElements()) {
|
if (!object->HasFixedTypedArrayElements()) {
|
||||||
// If there are fast elements we normalize.
|
// If there are fast elements we normalize.
|
||||||
Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
|
Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
|
||||||
@ -7701,6 +7707,25 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
|
|||||||
PrototypeIterator::GetCurrent<JSObject>(iter), should_throw);
|
PrototypeIterator::GetCurrent<JSObject>(iter), should_throw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (object->map()->has_named_interceptor() ||
|
||||||
|
object->map()->has_indexed_interceptor()) {
|
||||||
|
MessageTemplate::Template message = MessageTemplate::kNone;
|
||||||
|
switch (attrs) {
|
||||||
|
case NONE:
|
||||||
|
message = MessageTemplate::kCannotPreventExt;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SEALED:
|
||||||
|
message = MessageTemplate::kCannotSeal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FROZEN:
|
||||||
|
message = MessageTemplate::kCannotFreeze;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
RETURN_FAILURE(isolate, should_throw, NewTypeError(message));
|
||||||
|
}
|
||||||
|
|
||||||
Handle<SeededNumberDictionary> new_element_dictionary;
|
Handle<SeededNumberDictionary> new_element_dictionary;
|
||||||
if (!object->HasFixedTypedArrayElements() &&
|
if (!object->HasFixedTypedArrayElements() &&
|
||||||
!object->HasDictionaryElements() &&
|
!object->HasDictionaryElements() &&
|
||||||
|
@ -217,7 +217,7 @@ bytecodes: [
|
|||||||
B(TestTypeOf), U8(5),
|
B(TestTypeOf), U8(5),
|
||||||
B(JumpIfFalse), U8(4),
|
B(JumpIfFalse), U8(4),
|
||||||
B(Jump), U8(18),
|
B(Jump), U8(18),
|
||||||
B(Wide), B(LdaSmi), I16(130),
|
B(Wide), B(LdaSmi), I16(132),
|
||||||
B(Star), R(12),
|
B(Star), R(12),
|
||||||
B(LdaConstant), U8(11),
|
B(LdaConstant), U8(11),
|
||||||
B(Star), R(13),
|
B(Star), R(13),
|
||||||
@ -701,7 +701,7 @@ bytecodes: [
|
|||||||
B(TestTypeOf), U8(5),
|
B(TestTypeOf), U8(5),
|
||||||
B(JumpIfFalse), U8(4),
|
B(JumpIfFalse), U8(4),
|
||||||
B(Jump), U8(18),
|
B(Jump), U8(18),
|
||||||
B(Wide), B(LdaSmi), I16(130),
|
B(Wide), B(LdaSmi), I16(132),
|
||||||
B(Star), R(12),
|
B(Star), R(12),
|
||||||
B(LdaConstant), U8(11),
|
B(LdaConstant), U8(11),
|
||||||
B(Star), R(13),
|
B(Star), R(13),
|
||||||
@ -1219,7 +1219,7 @@ bytecodes: [
|
|||||||
B(TestTypeOf), U8(5),
|
B(TestTypeOf), U8(5),
|
||||||
B(JumpIfFalse), U8(4),
|
B(JumpIfFalse), U8(4),
|
||||||
B(Jump), U8(18),
|
B(Jump), U8(18),
|
||||||
B(Wide), B(LdaSmi), I16(130),
|
B(Wide), B(LdaSmi), I16(132),
|
||||||
B(Star), R(12),
|
B(Star), R(12),
|
||||||
B(LdaConstant), U8(11),
|
B(LdaConstant), U8(11),
|
||||||
B(Star), R(13),
|
B(Star), R(13),
|
||||||
@ -1627,7 +1627,7 @@ bytecodes: [
|
|||||||
B(TestTypeOf), U8(5),
|
B(TestTypeOf), U8(5),
|
||||||
B(JumpIfFalse), U8(4),
|
B(JumpIfFalse), U8(4),
|
||||||
B(Jump), U8(18),
|
B(Jump), U8(18),
|
||||||
B(Wide), B(LdaSmi), I16(130),
|
B(Wide), B(LdaSmi), I16(132),
|
||||||
B(Star), R(11),
|
B(Star), R(11),
|
||||||
B(LdaConstant), U8(10),
|
B(LdaConstant), U8(10),
|
||||||
B(Star), R(12),
|
B(Star), R(12),
|
||||||
|
@ -85,7 +85,7 @@ bytecodes: [
|
|||||||
B(TestTypeOf), U8(5),
|
B(TestTypeOf), U8(5),
|
||||||
B(JumpIfFalse), U8(4),
|
B(JumpIfFalse), U8(4),
|
||||||
B(Jump), U8(18),
|
B(Jump), U8(18),
|
||||||
B(Wide), B(LdaSmi), I16(130),
|
B(Wide), B(LdaSmi), I16(132),
|
||||||
B(Star), R(12),
|
B(Star), R(12),
|
||||||
B(LdaConstant), U8(8),
|
B(LdaConstant), U8(8),
|
||||||
B(Star), R(13),
|
B(Star), R(13),
|
||||||
@ -226,7 +226,7 @@ bytecodes: [
|
|||||||
B(TestTypeOf), U8(5),
|
B(TestTypeOf), U8(5),
|
||||||
B(JumpIfFalse), U8(4),
|
B(JumpIfFalse), U8(4),
|
||||||
B(Jump), U8(18),
|
B(Jump), U8(18),
|
||||||
B(Wide), B(LdaSmi), I16(130),
|
B(Wide), B(LdaSmi), I16(132),
|
||||||
B(Star), R(13),
|
B(Star), R(13),
|
||||||
B(LdaConstant), U8(8),
|
B(LdaConstant), U8(8),
|
||||||
B(Star), R(14),
|
B(Star), R(14),
|
||||||
@ -380,7 +380,7 @@ bytecodes: [
|
|||||||
B(TestTypeOf), U8(5),
|
B(TestTypeOf), U8(5),
|
||||||
B(JumpIfFalse), U8(4),
|
B(JumpIfFalse), U8(4),
|
||||||
B(Jump), U8(18),
|
B(Jump), U8(18),
|
||||||
B(Wide), B(LdaSmi), I16(130),
|
B(Wide), B(LdaSmi), I16(132),
|
||||||
B(Star), R(12),
|
B(Star), R(12),
|
||||||
B(LdaConstant), U8(8),
|
B(LdaConstant), U8(8),
|
||||||
B(Star), R(13),
|
B(Star), R(13),
|
||||||
@ -524,7 +524,7 @@ bytecodes: [
|
|||||||
B(TestTypeOf), U8(5),
|
B(TestTypeOf), U8(5),
|
||||||
B(JumpIfFalse), U8(4),
|
B(JumpIfFalse), U8(4),
|
||||||
B(Jump), U8(18),
|
B(Jump), U8(18),
|
||||||
B(Wide), B(LdaSmi), I16(130),
|
B(Wide), B(LdaSmi), I16(132),
|
||||||
B(Star), R(11),
|
B(Star), R(11),
|
||||||
B(LdaConstant), U8(10),
|
B(LdaConstant), U8(10),
|
||||||
B(Star), R(12),
|
B(Star), R(12),
|
||||||
|
@ -493,7 +493,7 @@ bytecodes: [
|
|||||||
B(TestTypeOf), U8(5),
|
B(TestTypeOf), U8(5),
|
||||||
B(JumpIfFalse), U8(4),
|
B(JumpIfFalse), U8(4),
|
||||||
B(Jump), U8(18),
|
B(Jump), U8(18),
|
||||||
B(Wide), B(LdaSmi), I16(130),
|
B(Wide), B(LdaSmi), I16(132),
|
||||||
B(Star), R(11),
|
B(Star), R(11),
|
||||||
B(LdaConstant), U8(10),
|
B(LdaConstant), U8(10),
|
||||||
B(Star), R(12),
|
B(Star), R(12),
|
||||||
|
@ -12,6 +12,7 @@ v8_executable("unittests") {
|
|||||||
"../../testing/gtest-support.h",
|
"../../testing/gtest-support.h",
|
||||||
"api/access-check-unittest.cc",
|
"api/access-check-unittest.cc",
|
||||||
"api/exception-unittest.cc",
|
"api/exception-unittest.cc",
|
||||||
|
"api/interceptor-unittest.cc",
|
||||||
"api/isolate-unittest.cc",
|
"api/isolate-unittest.cc",
|
||||||
"api/remote-object-unittest.cc",
|
"api/remote-object-unittest.cc",
|
||||||
"api/v8-object-unittest.cc",
|
"api/v8-object-unittest.cc",
|
||||||
|
32
test/unittests/api/interceptor-unittest.cc
Normal file
32
test/unittests/api/interceptor-unittest.cc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2017 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.
|
||||||
|
|
||||||
|
#include "include/v8.h"
|
||||||
|
#include "test/unittests/test-utils.h"
|
||||||
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace v8 {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using InterceptorTest = TestWithContext;
|
||||||
|
|
||||||
|
void NamedGetter(Local<Name> property,
|
||||||
|
const PropertyCallbackInfo<Value>& info) {}
|
||||||
|
|
||||||
|
TEST_F(InterceptorTest, FreezeApiObjectWithInterceptor) {
|
||||||
|
TryCatch try_catch(isolate());
|
||||||
|
|
||||||
|
Local<FunctionTemplate> tmpl = FunctionTemplate::New(isolate());
|
||||||
|
tmpl->InstanceTemplate()->SetHandler(
|
||||||
|
NamedPropertyHandlerConfiguration(NamedGetter));
|
||||||
|
|
||||||
|
Local<Function> ctor = tmpl->GetFunction(context()).ToLocalChecked();
|
||||||
|
Local<Object> obj = ctor->NewInstance(context()).ToLocalChecked();
|
||||||
|
ASSERT_TRUE(
|
||||||
|
obj->SetIntegrityLevel(context(), IntegrityLevel::kFrozen).IsNothing());
|
||||||
|
ASSERT_TRUE(try_catch.HasCaught());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace v8
|
@ -10,6 +10,7 @@
|
|||||||
'unittests_sources': [ ### gcmole(all) ###
|
'unittests_sources': [ ### gcmole(all) ###
|
||||||
'api/access-check-unittest.cc',
|
'api/access-check-unittest.cc',
|
||||||
'api/exception-unittest.cc',
|
'api/exception-unittest.cc',
|
||||||
|
'api/interceptor-unittest.cc',
|
||||||
'api/isolate-unittest.cc',
|
'api/isolate-unittest.cc',
|
||||||
'api/remote-object-unittest.cc',
|
'api/remote-object-unittest.cc',
|
||||||
'api/v8-object-unittest.cc',
|
'api/v8-object-unittest.cc',
|
||||||
|
Loading…
Reference in New Issue
Block a user