Home | History | Annotate | Download | only in custom
      1 /*
      2  * Copyright (C) 2009, 2011 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "bindings/core/v8/V8Window.h"
     33 
     34 #include "bindings/core/v8/BindingSecurity.h"
     35 #include "bindings/core/v8/ExceptionMessages.h"
     36 #include "bindings/core/v8/ExceptionState.h"
     37 #include "bindings/core/v8/ScheduledAction.h"
     38 #include "bindings/core/v8/ScriptController.h"
     39 #include "bindings/core/v8/ScriptSourceCode.h"
     40 #include "bindings/core/v8/SerializedScriptValue.h"
     41 #include "bindings/core/v8/V8Binding.h"
     42 #include "bindings/core/v8/V8EventListener.h"
     43 #include "bindings/core/v8/V8EventListenerList.h"
     44 #include "bindings/core/v8/V8GCForContextDispose.h"
     45 #include "bindings/core/v8/V8HTMLCollection.h"
     46 #include "bindings/core/v8/V8HiddenValue.h"
     47 #include "bindings/core/v8/V8Node.h"
     48 #include "core/dom/ExceptionCode.h"
     49 #include "core/dom/MessagePort.h"
     50 #include "core/frame/DOMTimer.h"
     51 #include "core/frame/DOMWindowTimers.h"
     52 #include "core/frame/FrameView.h"
     53 #include "core/frame/LocalDOMWindow.h"
     54 #include "core/frame/LocalFrame.h"
     55 #include "core/frame/Settings.h"
     56 #include "core/frame/csp/ContentSecurityPolicy.h"
     57 #include "core/html/HTMLCollection.h"
     58 #include "core/html/HTMLDocument.h"
     59 #include "core/inspector/ScriptCallStack.h"
     60 #include "core/loader/FrameLoadRequest.h"
     61 #include "core/loader/FrameLoader.h"
     62 #include "core/storage/Storage.h"
     63 #include "platform/PlatformScreen.h"
     64 #include "platform/graphics/media/MediaPlayer.h"
     65 #include "wtf/ArrayBuffer.h"
     66 #include "wtf/Assertions.h"
     67 #include "wtf/OwnPtr.h"
     68 
     69 namespace blink {
     70 
     71 // FIXME: There is a lot of duplication with SetTimeoutOrInterval() in V8WorkerGlobalScopeCustom.cpp.
     72 // We should refactor this.
     73 static void windowSetTimeoutImpl(const v8::FunctionCallbackInfo<v8::Value>& info, bool singleShot, ExceptionState& exceptionState)
     74 {
     75     int argumentCount = info.Length();
     76 
     77     if (argumentCount < 1)
     78         return;
     79 
     80     LocalDOMWindow* impl = V8Window::toImpl(info.Holder());
     81     if (!impl->frame() || !impl->document()) {
     82         exceptionState.throwDOMException(InvalidAccessError, "No script context is available in which to execute the script.");
     83         return;
     84     }
     85     ScriptState* scriptState = ScriptState::current(info.GetIsolate());
     86     v8::Handle<v8::Value> function = info[0];
     87     String functionString;
     88     if (!function->IsFunction()) {
     89         if (function->IsString()) {
     90             functionString = toCoreString(function.As<v8::String>());
     91         } else {
     92             v8::Handle<v8::String> v8String = function->ToString();
     93 
     94             // Bail out if string conversion failed.
     95             if (v8String.IsEmpty())
     96                 return;
     97 
     98             functionString = toCoreString(v8String);
     99         }
    100 
    101         // Don't allow setting timeouts to run empty functions!
    102         // (Bug 1009597)
    103         if (!functionString.length())
    104             return;
    105     }
    106 
    107     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState))
    108         return;
    109 
    110     OwnPtr<ScheduledAction> action;
    111     if (function->IsFunction()) {
    112         int paramCount = argumentCount >= 2 ? argumentCount - 2 : 0;
    113         OwnPtr<v8::Local<v8::Value>[]> params;
    114         if (paramCount > 0) {
    115             params = adoptArrayPtr(new v8::Local<v8::Value>[paramCount]);
    116             for (int i = 0; i < paramCount; i++) {
    117                 // parameters must be globalized
    118                 params[i] = info[i+2];
    119             }
    120         }
    121 
    122         // params is passed to action, and released in action's destructor
    123         ASSERT(impl->frame());
    124         action = adoptPtr(new ScheduledAction(scriptState, v8::Handle<v8::Function>::Cast(function), paramCount, params.get(), info.GetIsolate()));
    125     } else {
    126         if (impl->document() && !impl->document()->contentSecurityPolicy()->allowEval()) {
    127             v8SetReturnValue(info, 0);
    128             return;
    129         }
    130         ASSERT(impl->frame());
    131         action = adoptPtr(new ScheduledAction(scriptState, functionString, KURL(), info.GetIsolate()));
    132     }
    133 
    134     int32_t timeout = argumentCount >= 2 ? info[1]->Int32Value() : 0;
    135     int timerId;
    136     if (singleShot)
    137         timerId = DOMWindowTimers::setTimeout(*impl, action.release(), timeout);
    138     else
    139         timerId = DOMWindowTimers::setInterval(*impl, action.release(), timeout);
    140 
    141     // Try to do the idle notification before the timeout expires to get better
    142     // use of any idle time. Aim for the middle of the interval for simplicity.
    143     if (timeout >= 0) {
    144         double maximumFireInterval = static_cast<double>(timeout) / 1000 / 2;
    145         V8GCForContextDispose::instanceTemplate().notifyIdleSooner(maximumFireInterval);
    146     }
    147 
    148     v8SetReturnValue(info, timerId);
    149 }
    150 
    151 void V8Window::eventAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
    152 {
    153     LocalFrame* frame = V8Window::toImpl(info.Holder())->frame();
    154     ExceptionState exceptionState(ExceptionState::GetterContext, "event", "Window", info.Holder(), info.GetIsolate());
    155     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), frame, exceptionState)) {
    156         exceptionState.throwIfNeeded();
    157         return;
    158     }
    159 
    160     ASSERT(frame);
    161     // This is a fast path to retrieve info.Holder()->CreationContext().
    162     v8::Local<v8::Context> context = toV8Context(frame, DOMWrapperWorld::current(info.GetIsolate()));
    163     if (context.IsEmpty())
    164         return;
    165 
    166     v8::Handle<v8::Value> jsEvent = V8HiddenValue::getHiddenValue(info.GetIsolate(), context->Global(), V8HiddenValue::event(info.GetIsolate()));
    167     if (jsEvent.IsEmpty())
    168         return;
    169     v8SetReturnValue(info, jsEvent);
    170 }
    171 
    172 void V8Window::eventAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
    173 {
    174     LocalFrame* frame = V8Window::toImpl(info.Holder())->frame();
    175     ExceptionState exceptionState(ExceptionState::SetterContext, "event", "Window", info.Holder(), info.GetIsolate());
    176     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), frame, exceptionState)) {
    177         exceptionState.throwIfNeeded();
    178         return;
    179     }
    180 
    181     ASSERT(frame);
    182     // This is a fast path to retrieve info.Holder()->CreationContext().
    183     v8::Local<v8::Context> context = toV8Context(frame, DOMWrapperWorld::current(info.GetIsolate()));
    184     if (context.IsEmpty())
    185         return;
    186 
    187     V8HiddenValue::setHiddenValue(info.GetIsolate(), context->Global(), V8HiddenValue::event(info.GetIsolate()), value);
    188 }
    189 
    190 void V8Window::frameElementAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
    191 {
    192     LocalDOMWindow* impl = V8Window::toImpl(info.Holder());
    193     ExceptionState exceptionState(ExceptionState::GetterContext, "frame", "Window", info.Holder(), info.GetIsolate());
    194     if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), impl->frameElement(), exceptionState)) {
    195         v8SetReturnValueNull(info);
    196         exceptionState.throwIfNeeded();
    197         return;
    198     }
    199 
    200     // The wrapper for an <iframe> should get its prototype from the context of the frame it's in, rather than its own frame.
    201     // So, use its containing document as the creation context when wrapping.
    202     v8::Handle<v8::Value> creationContext = toV8(&impl->frameElement()->document(), info.Holder(), info.GetIsolate());
    203     RELEASE_ASSERT(!creationContext.IsEmpty());
    204     v8::Handle<v8::Value> wrapper = toV8(impl->frameElement(), v8::Handle<v8::Object>::Cast(creationContext), info.GetIsolate());
    205     v8SetReturnValue(info, wrapper);
    206 }
    207 
    208 void V8Window::openerAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
    209 {
    210     LocalDOMWindow* impl = V8Window::toImpl(info.Holder());
    211     ExceptionState exceptionState(ExceptionState::SetterContext, "opener", "Window", info.Holder(), info.GetIsolate());
    212     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
    213         exceptionState.throwIfNeeded();
    214         return;
    215     }
    216 
    217     // Opener can be shadowed if it is in the same domain.
    218     // Have a special handling of null value to behave
    219     // like Firefox. See bug http://b/1224887 & http://b/791706.
    220     if (value->IsNull()) {
    221         // impl->frame() cannot be null,
    222         // otherwise, SameOrigin check would have failed.
    223         ASSERT(impl->frame());
    224         impl->frame()->loader().setOpener(0);
    225     }
    226 
    227     // Delete the accessor from this object.
    228     info.Holder()->Delete(v8AtomicString(info.GetIsolate(), "opener"));
    229 
    230     // Put property on the front (this) object.
    231     if (info.This()->IsObject())
    232         v8::Handle<v8::Object>::Cast(info.This())->Set(v8AtomicString(info.GetIsolate(), "opener"), value);
    233 }
    234 
    235 static bool isLegacyTargetOriginDesignation(v8::Handle<v8::Value> value)
    236 {
    237     if (value->IsString() || value->IsStringObject())
    238         return true;
    239     return false;
    240 }
    241 
    242 
    243 void V8Window::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    244 {
    245     // None of these need to be RefPtr because info and context are guaranteed
    246     // to hold on to them.
    247     LocalDOMWindow* window = V8Window::toImpl(info.Holder());
    248     LocalDOMWindow* source = callingDOMWindow(info.GetIsolate());
    249 
    250     ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", "Window", info.Holder(), info.GetIsolate());
    251 
    252     // If called directly by WebCore we don't have a calling context.
    253     if (!source) {
    254         exceptionState.throwTypeError("No active calling context exists.");
    255         exceptionState.throwIfNeeded();
    256         return;
    257     }
    258 
    259     // This function has variable arguments and can be:
    260     // Per current spec:
    261     //   postMessage(message, targetOrigin)
    262     //   postMessage(message, targetOrigin, {sequence of transferrables})
    263     // Legacy non-standard implementations in webkit allowed:
    264     //   postMessage(message, {sequence of transferrables}, targetOrigin);
    265     MessagePortArray portArray;
    266     ArrayBufferArray arrayBufferArray;
    267     int targetOriginArgIndex = 1;
    268     if (info.Length() > 2) {
    269         int transferablesArgIndex = 2;
    270         if (isLegacyTargetOriginDesignation(info[2])) {
    271             targetOriginArgIndex = 2;
    272             transferablesArgIndex = 1;
    273         }
    274         if (!SerializedScriptValue::extractTransferables(info[transferablesArgIndex], transferablesArgIndex, portArray, arrayBufferArray, exceptionState, info.GetIsolate())) {
    275             exceptionState.throwIfNeeded();
    276             return;
    277         }
    278     }
    279     TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, targetOrigin, info[targetOriginArgIndex]);
    280 
    281     RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &portArray, &arrayBufferArray, exceptionState, info.GetIsolate());
    282     if (exceptionState.throwIfNeeded())
    283         return;
    284 
    285     window->postMessage(message.release(), &portArray, targetOrigin, source, exceptionState);
    286     exceptionState.throwIfNeeded();
    287 }
    288 
    289 // FIXME(fqian): returning string is cheating, and we should
    290 // fix this by calling toString function on the receiver.
    291 // However, V8 implements toString in JavaScript, which requires
    292 // switching context of receiver. I consider it is dangerous.
    293 void V8Window::toStringMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    294 {
    295     v8::Handle<v8::Object> domWrapper = V8Window::findInstanceInPrototypeChain(info.This(), info.GetIsolate());
    296     if (domWrapper.IsEmpty()) {
    297         v8SetReturnValue(info, info.This()->ObjectProtoToString());
    298         return;
    299     }
    300     v8SetReturnValue(info, domWrapper->ObjectProtoToString());
    301 }
    302 
    303 class DialogHandler {
    304 public:
    305     explicit DialogHandler(v8::Handle<v8::Value> dialogArguments, ScriptState* scriptState)
    306         : m_scriptState(scriptState)
    307         , m_dialogArguments(dialogArguments)
    308     {
    309     }
    310 
    311     void dialogCreated(LocalDOMWindow*);
    312     v8::Handle<v8::Value> returnValue() const;
    313 
    314 private:
    315     RefPtr<ScriptState> m_scriptState;
    316     RefPtr<ScriptState> m_scriptStateForDialogFrame;
    317     v8::Handle<v8::Value> m_dialogArguments;
    318 };
    319 
    320 void DialogHandler::dialogCreated(LocalDOMWindow* dialogFrame)
    321 {
    322     if (m_dialogArguments.IsEmpty())
    323         return;
    324     v8::Handle<v8::Context> context = toV8Context(dialogFrame->frame(), m_scriptState->world());
    325     if (context.IsEmpty())
    326         return;
    327     m_scriptStateForDialogFrame = ScriptState::from(context);
    328 
    329     ScriptState::Scope scope(m_scriptStateForDialogFrame.get());
    330     m_scriptStateForDialogFrame->context()->Global()->Set(v8AtomicString(m_scriptState->isolate(), "dialogArguments"), m_dialogArguments);
    331 }
    332 
    333 v8::Handle<v8::Value> DialogHandler::returnValue() const
    334 {
    335     if (!m_scriptStateForDialogFrame)
    336         return v8Undefined();
    337     ASSERT(!m_scriptStateForDialogFrame->contextIsValid());
    338 
    339     v8::Isolate* isolate = m_scriptStateForDialogFrame->isolate();
    340     v8::EscapableHandleScope handleScope(isolate);
    341     ScriptState::Scope scope(m_scriptStateForDialogFrame.get());
    342     v8::Local<v8::Value> returnValue = m_scriptStateForDialogFrame->context()->Global()->Get(v8AtomicString(isolate, "returnValue"));
    343     if (returnValue.IsEmpty())
    344         return v8Undefined();
    345     return handleScope.Escape(returnValue);
    346 }
    347 
    348 static void setUpDialog(LocalDOMWindow* dialog, void* handler)
    349 {
    350     static_cast<DialogHandler*>(handler)->dialogCreated(dialog);
    351 }
    352 
    353 void V8Window::showModalDialogMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    354 {
    355     LocalDOMWindow* impl = V8Window::toImpl(info.Holder());
    356     ExceptionState exceptionState(ExceptionState::ExecutionContext, "showModalDialog", "Window", info.Holder(), info.GetIsolate());
    357     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
    358         exceptionState.throwIfNeeded();
    359         return;
    360     }
    361 
    362     TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, urlString, info[0]);
    363     DialogHandler handler(info[1], ScriptState::current(info.GetIsolate()));
    364     TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, dialogFeaturesString, info[2]);
    365 
    366     impl->showModalDialog(urlString, dialogFeaturesString, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate()), setUpDialog, &handler);
    367 
    368     v8SetReturnValue(info, handler.returnValue());
    369 }
    370 
    371 void V8Window::openMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    372 {
    373     LocalDOMWindow* impl = V8Window::toImpl(info.Holder());
    374     ExceptionState exceptionState(ExceptionState::ExecutionContext, "open", "Window", info.Holder(), info.GetIsolate());
    375     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
    376         exceptionState.throwIfNeeded();
    377         return;
    378     }
    379 
    380     TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, urlString, info[0]);
    381     AtomicString frameName;
    382     if (info[1]->IsUndefined() || info[1]->IsNull()) {
    383         frameName = "_blank";
    384     } else {
    385         TOSTRING_VOID(V8StringResource<>, frameNameResource, info[1]);
    386         frameName = frameNameResource;
    387     }
    388     TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, windowFeaturesString, info[2]);
    389 
    390     RefPtrWillBeRawPtr<LocalDOMWindow> openedWindow = impl->open(urlString, frameName, windowFeaturesString, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate()));
    391     if (!openedWindow)
    392         return;
    393 
    394     v8SetReturnValueFast(info, openedWindow.release(), impl);
    395 }
    396 
    397 void V8Window::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
    398 {
    399 
    400     LocalDOMWindow* window = V8Window::toImpl(info.Holder());
    401     if (!window)
    402         return;
    403 
    404     LocalFrame* frame = window->frame();
    405     // window is detached from a frame.
    406     if (!frame)
    407         return;
    408 
    409     // Search sub-frames.
    410     AtomicString propName = toCoreAtomicString(name);
    411     Frame* child = frame->tree().scopedChild(propName);
    412     if (child) {
    413         v8SetReturnValueFast(info, child->domWindow(), window);
    414         return;
    415     }
    416 
    417     // Search IDL functions defined in the prototype
    418     if (!info.Holder()->GetRealNamedProperty(name).IsEmpty())
    419         return;
    420 
    421     // Search named items in the document.
    422     Document* doc = frame->document();
    423 
    424     if (doc && doc->isHTMLDocument()) {
    425         if (toHTMLDocument(doc)->hasNamedItem(propName) || doc->hasElementWithId(propName)) {
    426             RefPtrWillBeRawPtr<HTMLCollection> items = doc->windowNamedItems(propName);
    427             if (!items->isEmpty()) {
    428                 if (items->hasExactlyOneItem()) {
    429                     v8SetReturnValueFast(info, items->item(0), window);
    430                     return;
    431                 }
    432                 v8SetReturnValueFast(info, items.release(), window);
    433                 return;
    434             }
    435         }
    436     }
    437 }
    438 
    439 
    440 void V8Window::setTimeoutMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    441 {
    442     ExceptionState exceptionState(ExceptionState::ExecutionContext, "setTimeout", "Window", info.Holder(), info.GetIsolate());
    443     windowSetTimeoutImpl(info, true, exceptionState);
    444     exceptionState.throwIfNeeded();
    445 }
    446 
    447 
    448 void V8Window::setIntervalMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    449 {
    450     ExceptionState exceptionState(ExceptionState::ExecutionContext, "setInterval", "Window", info.Holder(), info.GetIsolate());
    451     windowSetTimeoutImpl(info, false, exceptionState);
    452     exceptionState.throwIfNeeded();
    453 }
    454 
    455 bool V8Window::namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
    456 {
    457     v8::Isolate* isolate = v8::Isolate::GetCurrent();
    458     v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host, isolate);
    459     if (window.IsEmpty())
    460         return false; // the frame is gone.
    461 
    462     LocalDOMWindow* targetWindow = V8Window::toImpl(window);
    463 
    464     ASSERT(targetWindow);
    465 
    466     LocalFrame* target = targetWindow->frame();
    467     if (!target)
    468         return false;
    469 
    470     // Notify the loader's client if the initial document has been accessed.
    471     if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument())
    472         target->loader().didAccessInitialDocument();
    473 
    474     if (key->IsString()) {
    475         DEFINE_STATIC_LOCAL(const AtomicString, nameOfProtoProperty, ("__proto__", AtomicString::ConstructFromLiteral));
    476 
    477         AtomicString name = toCoreAtomicString(key.As<v8::String>());
    478         Frame* childFrame = target->tree().scopedChild(name);
    479         // Notice that we can't call HasRealNamedProperty for ACCESS_HAS
    480         // because that would generate infinite recursion.
    481         if (type == v8::ACCESS_HAS && childFrame)
    482             return true;
    483         // We need to explicitly compare against nameOfProtoProperty because
    484         // V8's JSObject::LocalLookup finds __proto__ before
    485         // interceptors and even when __proto__ isn't a "real named property".
    486         v8::Handle<v8::String> keyString = key.As<v8::String>();
    487         if (type == v8::ACCESS_GET
    488             && childFrame
    489             && !host->HasRealNamedProperty(keyString)
    490             && !window->HasRealNamedProperty(keyString)
    491             && name != nameOfProtoProperty)
    492             return true;
    493     }
    494 
    495     return BindingSecurity::shouldAllowAccessToFrame(isolate, target, DoNotReportSecurityError);
    496 }
    497 
    498 bool V8Window::indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
    499 {
    500     v8::Isolate* isolate = v8::Isolate::GetCurrent();
    501     v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host, isolate);
    502     if (window.IsEmpty())
    503         return false;
    504 
    505     LocalDOMWindow* targetWindow = V8Window::toImpl(window);
    506 
    507     ASSERT(targetWindow);
    508 
    509     LocalFrame* target = targetWindow->frame();
    510     if (!target)
    511         return false;
    512 
    513     // Notify the loader's client if the initial document has been accessed.
    514     if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument())
    515         target->loader().didAccessInitialDocument();
    516 
    517     Frame* childFrame = target->tree().scopedChild(index);
    518 
    519     // Notice that we can't call HasRealNamedProperty for ACCESS_HAS
    520     // because that would generate infinite recursion.
    521     if (type == v8::ACCESS_HAS && childFrame)
    522         return true;
    523     if (type == v8::ACCESS_GET
    524         && childFrame
    525         && !host->HasRealIndexedProperty(index)
    526         && !window->HasRealIndexedProperty(index))
    527         return true;
    528 
    529     return BindingSecurity::shouldAllowAccessToFrame(isolate, target, DoNotReportSecurityError);
    530 }
    531 
    532 v8::Handle<v8::Value> toV8(LocalDOMWindow* window, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
    533 {
    534     // Notice that we explicitly ignore creationContext because the LocalDOMWindow is its own creationContext.
    535 
    536     if (!window)
    537         return v8::Null(isolate);
    538     // Initializes environment of a frame, and return the global object
    539     // of the frame.
    540     LocalFrame* frame = window->frame();
    541     if (!frame)
    542         return v8Undefined();
    543 
    544     v8::Handle<v8::Context> context = toV8Context(frame, DOMWrapperWorld::current(isolate));
    545     if (context.IsEmpty())
    546         return v8Undefined();
    547 
    548     v8::Handle<v8::Object> global = context->Global();
    549     ASSERT(!global.IsEmpty());
    550     return global;
    551 }
    552 
    553 } // namespace blink
    554