OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009, 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2009, 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 return; | 343 return; |
344 | 344 |
345 // Frame could have been detached in call to GetRealNamedProperty. | 345 // Frame could have been detached in call to GetRealNamedProperty. |
346 frame = window->frame(); | 346 frame = window->frame(); |
347 // window is detached. | 347 // window is detached. |
348 if (!frame) | 348 if (!frame) |
349 return; | 349 return; |
350 | 350 |
351 // Search named items in the document. | 351 // Search named items in the document. |
352 Document* doc = frame->document(); | 352 Document* doc = frame->document(); |
| 353 if (!doc || !doc->isHTMLDocument()) |
| 354 return; |
353 | 355 |
354 if (doc && doc->isHTMLDocument()) { | 356 // This is an AllCanRead interceptor. Check that the caller has access to t
he named results. |
355 if (toHTMLDocument(doc)->hasNamedItem(propName) || doc->hasElementWithId
(propName)) { | 357 if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), frame, DoN
otReportSecurityError)) |
356 RefPtrWillBeRawPtr<HTMLCollection> items = doc->windowNamedItems(pro
pName); | 358 return; |
357 if (!items->isEmpty()) { | 359 |
358 if (items->hasExactlyOneItem()) { | 360 if (toHTMLDocument(doc)->hasNamedItem(propName) || doc->hasElementWithId(pro
pName)) { |
359 v8SetReturnValueFast(info, items->item(0), window); | 361 RefPtrWillBeRawPtr<HTMLCollection> items = doc->windowNamedItems(propNam
e); |
360 return; | 362 if (!items->isEmpty()) { |
361 } | 363 if (items->hasExactlyOneItem()) { |
362 v8SetReturnValueFast(info, items.release(), window); | 364 v8SetReturnValueFast(info, items->item(0), window); |
363 return; | 365 return; |
364 } | 366 } |
| 367 v8SetReturnValueFast(info, items.release(), window); |
| 368 return; |
365 } | 369 } |
366 } | 370 } |
367 } | 371 } |
368 | 372 |
369 bool V8Window::namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8
::Value> key, v8::AccessType type, v8::Local<v8::Value>) | 373 static bool securityCheck(v8::Local<v8::Object> host) |
370 { | 374 { |
371 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 375 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
372 v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host,
isolate); | 376 v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host,
isolate); |
373 if (window.IsEmpty()) | 377 if (window.IsEmpty()) |
374 return false; // the frame is gone. | 378 return false; // the frame is gone. |
375 | 379 |
376 DOMWindow* targetWindow = V8Window::toImpl(window); | 380 DOMWindow* targetWindow = V8Window::toImpl(window); |
377 ASSERT(targetWindow); | 381 ASSERT(targetWindow); |
378 if (!targetWindow->isLocalDOMWindow()) | 382 if (!targetWindow->isLocalDOMWindow()) |
379 return false; | 383 return false; |
380 | 384 |
381 LocalFrame* target = toLocalDOMWindow(targetWindow)->frame(); | 385 LocalFrame* target = toLocalDOMWindow(targetWindow)->frame(); |
382 if (!target) | 386 if (!target) |
383 return false; | 387 return false; |
384 | 388 |
385 // Notify the loader's client if the initial document has been accessed. | 389 // Notify the loader's client if the initial document has been accessed. |
386 if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument()) | 390 if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument()) |
387 target->loader().didAccessInitialDocument(); | 391 target->loader().didAccessInitialDocument(); |
388 | 392 |
389 if (key->IsString()) { | |
390 DEFINE_STATIC_LOCAL(const AtomicString, nameOfProtoProperty, ("__proto__
", AtomicString::ConstructFromLiteral)); | |
391 | |
392 AtomicString name = toCoreAtomicString(key.As<v8::String>()); | |
393 Frame* childFrame = target->tree().scopedChild(name); | |
394 // Notice that we can't call HasRealNamedProperty for ACCESS_HAS | |
395 // because that would generate infinite recursion. | |
396 if (type == v8::ACCESS_HAS && childFrame) | |
397 return true; | |
398 // We need to explicitly compare against nameOfProtoProperty because | |
399 // V8's JSObject::LocalLookup finds __proto__ before | |
400 // interceptors and even when __proto__ isn't a "real named property". | |
401 v8::Handle<v8::String> keyString = key.As<v8::String>(); | |
402 if (type == v8::ACCESS_GET | |
403 && childFrame | |
404 && !host->HasRealNamedProperty(keyString) | |
405 && !window->HasRealNamedProperty(keyString) | |
406 && name != nameOfProtoProperty) | |
407 return true; | |
408 } | |
409 | |
410 return BindingSecurity::shouldAllowAccessToFrame(isolate, target, DoNotRepor
tSecurityError); | 393 return BindingSecurity::shouldAllowAccessToFrame(isolate, target, DoNotRepor
tSecurityError); |
411 } | 394 } |
412 | 395 |
| 396 bool V8Window::namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8
::Value> key, v8::AccessType type, v8::Local<v8::Value>) |
| 397 { |
| 398 return securityCheck(host); |
| 399 } |
| 400 |
413 bool V8Window::indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t i
ndex, v8::AccessType type, v8::Local<v8::Value>) | 401 bool V8Window::indexedSecurityCheckCustom(v8::Local<v8::Object> host, uint32_t i
ndex, v8::AccessType type, v8::Local<v8::Value>) |
414 { | 402 { |
415 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 403 return securityCheck(host); |
416 v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host,
isolate); | |
417 if (window.IsEmpty()) | |
418 return false; | |
419 | |
420 DOMWindow* targetWindow = V8Window::toImpl(window); | |
421 ASSERT(targetWindow); | |
422 if (!targetWindow->isLocalDOMWindow()) | |
423 return false; | |
424 | |
425 LocalFrame* target = toLocalDOMWindow(targetWindow)->frame(); | |
426 if (!target) | |
427 return false; | |
428 | |
429 // Notify the loader's client if the initial document has been accessed. | |
430 if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument()) | |
431 target->loader().didAccessInitialDocument(); | |
432 | |
433 Frame* childFrame = target->tree().scopedChild(index); | |
434 | |
435 // Notice that we can't call HasRealNamedProperty for ACCESS_HAS | |
436 // because that would generate infinite recursion. | |
437 if (type == v8::ACCESS_HAS && childFrame) | |
438 return true; | |
439 if (type == v8::ACCESS_GET | |
440 && childFrame | |
441 && !host->HasRealIndexedProperty(index) | |
442 && !window->HasRealIndexedProperty(index)) | |
443 return true; | |
444 | |
445 return BindingSecurity::shouldAllowAccessToFrame(isolate, target, DoNotRepor
tSecurityError); | |
446 } | 404 } |
447 | 405 |
448 v8::Handle<v8::Value> toV8(DOMWindow* window, v8::Handle<v8::Object> creationCon
text, v8::Isolate* isolate) | 406 v8::Handle<v8::Value> toV8(DOMWindow* window, v8::Handle<v8::Object> creationCon
text, v8::Isolate* isolate) |
449 { | 407 { |
450 // Notice that we explicitly ignore creationContext because the LocalDOMWind
ow is its own creationContext. | 408 // Notice that we explicitly ignore creationContext because the LocalDOMWind
ow is its own creationContext. |
451 | 409 |
452 if (!window) | 410 if (!window) |
453 return v8::Null(isolate); | 411 return v8::Null(isolate); |
454 // Initializes environment of a frame, and return the global object | 412 // Initializes environment of a frame, and return the global object |
455 // of the frame. | 413 // of the frame. |
456 Frame * frame = window->frame(); | 414 Frame * frame = window->frame(); |
457 if (!frame) | 415 if (!frame) |
458 return v8Undefined(); | 416 return v8Undefined(); |
459 | 417 |
460 v8::Handle<v8::Context> context = toV8Context(frame, DOMWrapperWorld::curren
t(isolate)); | 418 v8::Handle<v8::Context> context = toV8Context(frame, DOMWrapperWorld::curren
t(isolate)); |
461 if (context.IsEmpty()) | 419 if (context.IsEmpty()) |
462 return v8Undefined(); | 420 return v8Undefined(); |
463 | 421 |
464 v8::Handle<v8::Object> global = context->Global(); | 422 v8::Handle<v8::Object> global = context->Global(); |
465 ASSERT(!global.IsEmpty()); | 423 ASSERT(!global.IsEmpty()); |
466 return global; | 424 return global; |
467 } | 425 } |
468 | 426 |
469 } // namespace blink | 427 } // namespace blink |
OLD | NEW |