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.
windowSetTimeoutImpl(const v8::FunctionCallbackInfo<v8::Value> & info,bool singleShot,ExceptionState & exceptionState)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
eventAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value> & info)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
eventAttributeSetterCustom(v8::Local<v8::Value> value,const v8::PropertyCallbackInfo<void> & info)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
frameElementAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value> & info)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
openerAttributeSetterCustom(v8::Local<v8::Value> value,const v8::PropertyCallbackInfo<void> & info)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
isLegacyTargetOriginDesignation(v8::Handle<v8::Value> value)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
postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value> & info)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.
toStringMethodCustom(const v8::FunctionCallbackInfo<v8::Value> & info)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:
DialogHandler(v8::Handle<v8::Value> dialogArguments,ScriptState * scriptState)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
dialogCreated(LocalDOMWindow * dialogFrame)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
returnValue() const333 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
setUpDialog(LocalDOMWindow * dialog,void * handler)348 static void setUpDialog(LocalDOMWindow* dialog, void* handler)
349 {
350 static_cast<DialogHandler*>(handler)->dialogCreated(dialog);
351 }
352
showModalDialogMethodCustom(const v8::FunctionCallbackInfo<v8::Value> & info)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
openMethodCustom(const v8::FunctionCallbackInfo<v8::Value> & info)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
namedPropertyGetterCustom(v8::Local<v8::String> name,const v8::PropertyCallbackInfo<v8::Value> & info)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
setTimeoutMethodCustom(const v8::FunctionCallbackInfo<v8::Value> & info)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
setIntervalMethodCustom(const v8::FunctionCallbackInfo<v8::Value> & info)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
namedSecurityCheckCustom(v8::Local<v8::Object> host,v8::Local<v8::Value> key,v8::AccessType type,v8::Local<v8::Value>)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
indexedSecurityCheckCustom(v8::Local<v8::Object> host,uint32_t index,v8::AccessType type,v8::Local<v8::Value>)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
toV8(LocalDOMWindow * window,v8::Handle<v8::Object> creationContext,v8::Isolate * isolate)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