Fix HasOwnProperty stub for interceptors

When internalization of the key fails because the string does not
exist in the StringTable yet, then no regular object can possibly
have a property with that name, so just returning "false" is safe.
However, for objects with interceptors this is not true, as there
may well be intercepted properties whose keys have not been
internalized. So "special API objects" must take the slow path to
query any interceptors.

Bug: chromium:735990
Change-Id: Ibe6c4f8b14fef65738115f12167d3602bec3d9b7
Reviewed-on: https://chromium-review.googlesource.com/552550
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46323}
This commit is contained in:
Jakob Kummerow 2017-06-29 16:15:56 +02:00 committed by Commit Bot
parent 580777977a
commit 347e6215c5
2 changed files with 27 additions and 4 deletions

View File

@ -90,10 +90,18 @@ TF_BUILTIN(ObjectHasOwnProperty, ObjectBuiltinsAssembler) {
BIND(&if_notunique_name);
{
// If the string was not found in the string table, then no object can
// have a property with that name, so return |false|.
Label not_in_string_table(this);
TryInternalizeString(key, &if_index, &var_index, &if_unique_name,
&var_unique, &return_false, &call_runtime);
&var_unique, &not_in_string_table, &call_runtime);
BIND(&not_in_string_table);
{
// If the string was not found in the string table, then no regular
// object can have a property with that name, so return |false|.
// "Special API objects" with interceptors must take the slow path.
Branch(IsSpecialReceiverInstanceType(instance_type), &call_runtime,
&return_false);
}
}
}
BIND(&to_primitive);

View File

@ -20944,13 +20944,16 @@ void HasOwnPropertyNamedPropertyQuery2(
}
}
void HasOwnPropertyAccessorGetter(
Local<String> property,
const v8::PropertyCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(v8_str("yes"));
}
void HasOwnPropertyAccessorNameGetter(
Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(v8_str("yes"));
}
TEST(HasOwnProperty) {
LocalContext env;
@ -21032,6 +21035,18 @@ TEST(HasOwnProperty) {
CHECK(!instance->HasOwnProperty(env.local(), v8_str("foo")).FromJust());
CHECK(instance->HasOwnProperty(env.local(), v8_str("bar")).FromJust());
}
{ // Check that non-internalized keys are handled correctly.
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
HasOwnPropertyAccessorNameGetter));
Local<Object> instance = templ->NewInstance(env.local()).ToLocalChecked();
env->Global()->Set(env.local(), v8_str("obj"), instance).FromJust();
const char* src =
"var dyn_string = 'this string ';"
"dyn_string += 'does not exist elsewhere';"
"({}).hasOwnProperty.call(obj, dyn_string)";
CHECK(CompileRun(src)->BooleanValue(env.local()).FromJust());
}
}