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);
|
||||
i::JSReceiver::IntegrityLevel i_level =
|
||||
level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
|
||||
Maybe<bool> result =
|
||||
i::JSReceiver::SetIntegrityLevel(self, i_level, i::Object::DONT_THROW);
|
||||
Maybe<bool> result = i::JSReceiver::SetIntegrityLevel(
|
||||
self, i_level, i::Object::THROW_ON_ERROR);
|
||||
has_pending_exception = result.IsNothing();
|
||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
||||
return result;
|
||||
|
@ -280,8 +280,10 @@ class ErrorUtils : public AllStatic {
|
||||
T(CallSiteMethod, "CallSite method % expects CallSite as receiver") \
|
||||
T(CannotConvertToPrimitive, "Cannot convert object to primitive value") \
|
||||
T(CannotPreventExt, "Cannot prevent extensions") \
|
||||
T(CannotFreeze, "Cannot freeze") \
|
||||
T(CannotFreezeArrayBufferView, \
|
||||
"Cannot freeze array buffer views with elements") \
|
||||
T(CannotSeal, "Cannot seal") \
|
||||
T(CircularStructure, "Converting circular structure to JSON") \
|
||||
T(ConstructAbstractClass, "Abstract class % not directly constructable") \
|
||||
T(ConstAssign, "Assignment to constant variable.") \
|
||||
|
@ -7541,6 +7541,12 @@ Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
|
||||
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 there are fast elements we normalize.
|
||||
Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
|
||||
@ -7701,6 +7707,25 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
|
||||
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;
|
||||
if (!object->HasFixedTypedArrayElements() &&
|
||||
!object->HasDictionaryElements() &&
|
||||
|
@ -217,7 +217,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(5),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(130),
|
||||
B(Wide), B(LdaSmi), I16(132),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(11),
|
||||
B(Star), R(13),
|
||||
@ -701,7 +701,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(5),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(130),
|
||||
B(Wide), B(LdaSmi), I16(132),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(11),
|
||||
B(Star), R(13),
|
||||
@ -1219,7 +1219,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(5),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(130),
|
||||
B(Wide), B(LdaSmi), I16(132),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(11),
|
||||
B(Star), R(13),
|
||||
@ -1627,7 +1627,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(5),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(130),
|
||||
B(Wide), B(LdaSmi), I16(132),
|
||||
B(Star), R(11),
|
||||
B(LdaConstant), U8(10),
|
||||
B(Star), R(12),
|
||||
|
@ -85,7 +85,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(5),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(130),
|
||||
B(Wide), B(LdaSmi), I16(132),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(8),
|
||||
B(Star), R(13),
|
||||
@ -226,7 +226,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(5),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(130),
|
||||
B(Wide), B(LdaSmi), I16(132),
|
||||
B(Star), R(13),
|
||||
B(LdaConstant), U8(8),
|
||||
B(Star), R(14),
|
||||
@ -380,7 +380,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(5),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(130),
|
||||
B(Wide), B(LdaSmi), I16(132),
|
||||
B(Star), R(12),
|
||||
B(LdaConstant), U8(8),
|
||||
B(Star), R(13),
|
||||
@ -524,7 +524,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(5),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(130),
|
||||
B(Wide), B(LdaSmi), I16(132),
|
||||
B(Star), R(11),
|
||||
B(LdaConstant), U8(10),
|
||||
B(Star), R(12),
|
||||
|
@ -493,7 +493,7 @@ bytecodes: [
|
||||
B(TestTypeOf), U8(5),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(18),
|
||||
B(Wide), B(LdaSmi), I16(130),
|
||||
B(Wide), B(LdaSmi), I16(132),
|
||||
B(Star), R(11),
|
||||
B(LdaConstant), U8(10),
|
||||
B(Star), R(12),
|
||||
|
@ -12,6 +12,7 @@ v8_executable("unittests") {
|
||||
"../../testing/gtest-support.h",
|
||||
"api/access-check-unittest.cc",
|
||||
"api/exception-unittest.cc",
|
||||
"api/interceptor-unittest.cc",
|
||||
"api/isolate-unittest.cc",
|
||||
"api/remote-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) ###
|
||||
'api/access-check-unittest.cc',
|
||||
'api/exception-unittest.cc',
|
||||
'api/interceptor-unittest.cc',
|
||||
'api/isolate-unittest.cc',
|
||||
'api/remote-object-unittest.cc',
|
||||
'api/v8-object-unittest.cc',
|
||||
|
Loading…
Reference in New Issue
Block a user