From dd90e4f1cc4375b83aaa5299ae079a1bd2c7aa89 Mon Sep 17 00:00:00 2001 From: Georgios Kalpakas Date: Tue, 3 Jan 2017 16:55:38 +0200 Subject: [PATCH] fix(angularInit): allow auto-bootstraping from inline script Some browsers (e.g. Safari 9.x, PhantomJS) do not set `link.origin/protocol` correctly, when setting `link.href` to `null`, which prevented auto-bootstraping Angular from scripts without a `src` attribute (i.e. inline scripts). Inline scripts are on the same origin as the loading page, so auto-bootstraping should be allowed. Fixes #15567 --- src/Angular.js | 8 ++++++-- test/AngularSpec.js | 25 +++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Angular.js b/src/Angular.js index c4e0eef237ac..d4088ad35227 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -1479,12 +1479,16 @@ function getNgAttribute(element, ngAttr) { } function allowAutoBootstrap(document) { - if (!document.currentScript) { + var script = document.currentScript; + var src = script && script.getAttribute('src'); + + if (!src) { return true; } - var src = document.currentScript.getAttribute('src'); + var link = document.createElement('a'); link.href = src; + if (document.location.origin === link.origin) { // Same-origin resources are always allowed, even for non-whitelisted schemes. return true; diff --git a/test/AngularSpec.js b/test/AngularSpec.js index 10540ecc36e5..9e9bbfea6a98 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -1684,7 +1684,8 @@ describe('angular', function() { }); it('should bootstrap from an extension into an extension document for same-origin documents only', function() { - if (msie) return; // IE does not support document.currentScript (nor extensions with protocol), so skip test. + // IE does not support `document.currentScript` (nor extensions with protocol), so skip test. + if (msie) return; // Extension URLs are browser-specific, so we must choose a scheme that is supported by the browser to make // sure that the URL is properly parsed. @@ -1715,8 +1716,28 @@ describe('angular', function() { expect(allowAutoBootstrap(fakeDoc)).toBe(false); }); + it('should bootstrap from a script with an empty or missing `src` attribute', function() { + // IE does not support `document.currentScript` (nor extensions with protocol), so skip test. + if (msie) return; + + // Fake a minimal document object (the actual document.currentScript is readonly). + var src; + var fakeDoc = { + createElement: document.createElement.bind(document), + currentScript: {getAttribute: function() { return src; }}, + location: {origin: 'some-value', protocol: 'http:'} + }; + + src = null; + expect(allowAutoBootstrap(fakeDoc)).toBe(true); + + src = ''; + expect(allowAutoBootstrap(fakeDoc)).toBe(true); + }); + it('should not bootstrap from an extension into a non-extension document', function() { - if (msie) return; // IE does not support document.currentScript (nor extensions with protocol), so skip test. + // IE does not support `document.currentScript` (nor extensions with protocol), so skip test. + if (msie) return; var src = 'resource://something'; // Fake a minimal document object (the actual document.currentScript is readonly).