Bugfix in html_dart2js: Detect window objects in a way compatible with cross domain iframes

The "setTimeout" member in window object can only be accessed if the window
object is from the same origin. Cross origin windows will throw a security error
exception.

This is fixed by checking for "postMessage" in the window object (which
can be accessed even in cross-origin windows).

BUG=http://dartbug.com/20166
R=blois@google.com

Review URL: https://codereview.chromium.org//406143004

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@38517 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
kustermann@google.com 2014-07-23 20:16:31 +00:00
parent 01d0779b85
commit 13c0d42313
4 changed files with 47 additions and 4 deletions

View file

@ -35436,10 +35436,10 @@ EventTarget _convertNativeToDart_EventTarget(e) {
if (e == null) {
return null;
}
// Assume it's a Window if it contains the setInterval property. It may be
// Assume it's a Window if it contains the postMessage property. It may be
// from a different frame - without a patched prototype - so we cannot
// rely on Dart type checking.
if (JS('bool', r'"setInterval" in #', e)) {
if (JS('bool', r'"postMessage" in #', e)) {
var window = _DOMWindowCrossFrame._createSafe(e);
// If it's a native window.
if (window is EventTarget) {

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>cross_domain_iframe_script</title>
</head>
<body>
<script type="application/javascript">
window.parent.postMessage('foobar', '*');
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:html';
import 'package:unittest/unittest.dart';
main() {
test('cross_domain_iframe', () {
var uri = Uri.parse(window.location.href);
var crossOriginPort = int.parse(uri.queryParameters['crossOriginPort']);
var crossOrigin = '${uri.scheme}://${uri.host}:$crossOriginPort';
var crossOriginUrl =
'$crossOrigin/root_dart/tests/html/cross_domain_iframe_script.html';
var iframe = new IFrameElement();
iframe.src = crossOriginUrl;
document.body.append(iframe);
window.onMessage.where((MessageEvent event) {
return event.origin == crossOrigin;
}).first.then(expectAsync((MessageEvent event) {
expect(event.data, equals('foobar'));
expect(event.source, isNotNull);
}));
});
}

View file

@ -20,10 +20,10 @@ EventTarget _convertNativeToDart_EventTarget(e) {
if (e == null) {
return null;
}
// Assume it's a Window if it contains the setInterval property. It may be
// Assume it's a Window if it contains the postMessage property. It may be
// from a different frame - without a patched prototype - so we cannot
// rely on Dart type checking.
if (JS('bool', r'"setInterval" in #', e)) {
if (JS('bool', r'"postMessage" in #', e)) {
var window = _DOMWindowCrossFrame._createSafe(e);
// If it's a native window.
if (window is EventTarget) {