| Index: src/runtime.cc
|
| ===================================================================
|
| --- src/runtime.cc (revision 7030)
|
| +++ src/runtime.cc (working copy)
|
| @@ -675,6 +675,78 @@
|
| }
|
|
|
|
|
| +static bool CheckAccessException(LookupResult* result,
|
| + v8::AccessType access_type) {
|
| + if (result->type() == CALLBACKS) {
|
| + Object* callback = result->GetCallbackObject();
|
| + if (callback->IsAccessorInfo()) {
|
| + AccessorInfo* info = AccessorInfo::cast(callback);
|
| + bool can_access =
|
| + (access_type == v8::ACCESS_HAS &&
|
| + (info->all_can_read() || info->all_can_write())) ||
|
| + (access_type == v8::ACCESS_GET && info->all_can_read()) ||
|
| + (access_type == v8::ACCESS_SET && info->all_can_write());
|
| + return can_access;
|
| + }
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| +
|
| +static bool CheckAccess(Isolate* isolate,
|
| + JSObject* obj,
|
| + String* name,
|
| + LookupResult* result,
|
| + v8::AccessType access_type) {
|
| + ASSERT(result->IsProperty());
|
| +
|
| + JSObject* holder = result->holder();
|
| + JSObject* current = obj;
|
| + while (true) {
|
| + if (current->IsAccessCheckNeeded() &&
|
| + !isolate->MayNamedAccess(current, name, access_type)) {
|
| + // Access check callback denied the access, but some properties
|
| + // can have a special permissions which override callbacks descision
|
| + // (currently see v8::AccessControl).
|
| + break;
|
| + }
|
| +
|
| + if (current == holder) {
|
| + return true;
|
| + }
|
| +
|
| + current = JSObject::cast(current->GetPrototype());
|
| + }
|
| +
|
| + // API callbacks can have per callback access exceptions.
|
| + switch (result->type()) {
|
| + case CALLBACKS: {
|
| + if (CheckAccessException(result, access_type)) {
|
| + return true;
|
| + }
|
| + break;
|
| + }
|
| + case INTERCEPTOR: {
|
| + // If the object has an interceptor, try real named properties.
|
| + // Overwrite the result to fetch the correct property later.
|
| + holder->LookupRealNamedProperty(name, result);
|
| + if (result->IsProperty()) {
|
| + if (CheckAccessException(result, access_type)) {
|
| + return true;
|
| + }
|
| + }
|
| + break;
|
| + }
|
| + default:
|
| + break;
|
| + }
|
| +
|
| + isolate->ReportFailedAccessCheck(current, access_type);
|
| + return false;
|
| +}
|
| +
|
| +
|
| // Enumerator used as indices into the array returned from GetOwnProperty
|
| enum PropertyDescriptorIndices {
|
| IS_ACCESSOR_INDEX,
|
| @@ -778,35 +850,41 @@
|
| if (!result.IsProperty()) {
|
| return heap->undefined_value();
|
| }
|
| - if (result.type() == CALLBACKS) {
|
| - Object* structure = result.GetCallbackObject();
|
| - if (structure->IsProxy() || structure->IsAccessorInfo()) {
|
| - // Property that is internally implemented as a callback or
|
| - // an API defined callback.
|
| - Object* value;
|
| - { MaybeObject* maybe_value = obj->GetPropertyWithCallback(
|
| - *obj, structure, *name, result.holder());
|
| - if (!maybe_value->ToObject(&value)) return maybe_value;
|
| - }
|
| - elms->set(IS_ACCESSOR_INDEX, heap->false_value());
|
| - elms->set(VALUE_INDEX, value);
|
| - elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly()));
|
| - } else if (structure->IsFixedArray()) {
|
| - // __defineGetter__/__defineSetter__ callback.
|
| - elms->set(IS_ACCESSOR_INDEX, heap->true_value());
|
| - elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0));
|
| - elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1));
|
| - } else {
|
| - return heap->undefined_value();
|
| +
|
| + if (!CheckAccess(isolate, *obj, *name, &result, v8::ACCESS_HAS)) {
|
| + return heap->undefined_value();
|
| + }
|
| +
|
| + elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum()));
|
| + elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete()));
|
| +
|
| + bool is_js_accessor = (result.type() == CALLBACKS) &&
|
| + (result.GetCallbackObject()->IsFixedArray());
|
| +
|
| + if (is_js_accessor) {
|
| + // __defineGetter__/__defineSetter__ callback.
|
| + elms->set(IS_ACCESSOR_INDEX, heap->true_value());
|
| +
|
| + FixedArray* structure = FixedArray::cast(result.GetCallbackObject());
|
| + if (CheckAccess(isolate, *obj, *name, &result, v8::ACCESS_GET)) {
|
| + elms->set(GETTER_INDEX, structure->get(0));
|
| }
|
| + if (CheckAccess(isolate, *obj, *name, &result, v8::ACCESS_SET)) {
|
| + elms->set(SETTER_INDEX, structure->get(1));
|
| + }
|
| } else {
|
| elms->set(IS_ACCESSOR_INDEX, heap->false_value());
|
| - elms->set(VALUE_INDEX, result.GetLazyValue());
|
| elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly()));
|
| +
|
| + PropertyAttributes attrs;
|
| + Object* value;
|
| + // GetProperty will check access and report any violations.
|
| + { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs);
|
| + if (!maybe_value->ToObject(&value)) return maybe_value;
|
| + }
|
| + elms->set(VALUE_INDEX, value);
|
| }
|
|
|
| - elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum()));
|
| - elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete()));
|
| return *desc;
|
| }
|
|
|
| @@ -11233,6 +11311,53 @@
|
| return *value;
|
| }
|
|
|
| +
|
| +static MaybeObject* Runtime_NewMessageObject(RUNTIME_CALLING_CONVENTION) {
|
| + RUNTIME_GET_ISOLATE;
|
| + HandleScope scope;
|
| + CONVERT_ARG_CHECKED(String, type, 0);
|
| + CONVERT_ARG_CHECKED(JSArray, arguments, 1);
|
| + Factory* factory = isolate->factory();
|
| + Handle<Object> undefined = factory->undefined_value();
|
| + return *factory->NewJSMessageObject(type,
|
| + arguments,
|
| + 0,
|
| + 0,
|
| + undefined,
|
| + undefined,
|
| + undefined);
|
| +}
|
| +
|
| +
|
| +static MaybeObject* Runtime_MessageGetType(RUNTIME_CALLING_CONVENTION) {
|
| + RUNTIME_GET_ISOLATE;
|
| + CONVERT_CHECKED(JSMessageObject, message, args[0]);
|
| + return message->type();
|
| +}
|
| +
|
| +
|
| +static MaybeObject* Runtime_MessageGetArguments(RUNTIME_CALLING_CONVENTION) {
|
| + RUNTIME_GET_ISOLATE;
|
| + CONVERT_CHECKED(JSMessageObject, message, args[0]);
|
| + return message->arguments();
|
| +}
|
| +
|
| +
|
| +static MaybeObject* Runtime_MessageGetStartPosition(
|
| + RUNTIME_CALLING_CONVENTION) {
|
| + RUNTIME_GET_ISOLATE;
|
| + CONVERT_CHECKED(JSMessageObject, message, args[0]);
|
| + return Smi::FromInt(message->start_position());
|
| +}
|
| +
|
| +
|
| +static MaybeObject* Runtime_MessageGetScript(RUNTIME_CALLING_CONVENTION) {
|
| + RUNTIME_GET_ISOLATE;
|
| + CONVERT_CHECKED(JSMessageObject, message, args[0]);
|
| + return message->script();
|
| +}
|
| +
|
| +
|
| #ifdef DEBUG
|
| // ListNatives is ONLY used by the fuzz-natives.js in debug mode
|
| // Exclude the code in release mode.
|
|
|