Skip to content

Commit 8e2f254

Browse files
committed
fix integrity cases
1 parent 7b1db53 commit 8e2f254

File tree

2 files changed

+62
-12
lines changed

2 files changed

+62
-12
lines changed

lib/global-eval.js

+54-11
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,68 @@ var __exec;
5151
// System clobbering protection (mostly for Traceur)
5252
var curSystem;
5353
var callCounter = 0;
54+
function preExec(loader, load) {
55+
if (callCounter++ == 0)
56+
curSystem = __global.System;
57+
__global.System = __global.SystemJS = loader;
58+
}
59+
function postExec() {
60+
if (--callCounter == 0)
61+
__global.System = __global.SystemJS = curSystem;
62+
curLoad = undefined;
63+
}
64+
5465
__exec = function(load) {
55-
if (load.metadata.integrity)
56-
throw new TypeError('Subresource integrity checking is only supported on modules with scriptLoad:true metadata or through the SystemCSP build.');
66+
if ((load.metadata.integrity || load.metadata.nonce) && supportsScriptExec)
67+
return scriptExec.call(this, load);
5768
try {
58-
if (callCounter++ == 0)
59-
curSystem = __global.System;
60-
__global.System = __global.SystemJS = this;
69+
preExec(this, load);
6170
curLoad = load;
6271
(0, eval)(getSource(load));
63-
if (--callCounter == 0)
64-
__global.System = __global.SystemJS = curSystem;
65-
curLoad = undefined;
72+
postExec();
6673
}
6774
catch(e) {
68-
if (--callCounter == 0)
69-
__global.System = __global.SystemJS = curSystem;
70-
curLoad = undefined;
75+
postExec();
7176
throw addToError(e, 'Evaluating ' + load.address);
7277
}
7378
};
7479

80+
var supportsScriptExec = false;
81+
if (isBrowser && typeof document != 'undefined' && document.getElementsByTagName) {
82+
var scripts = document.getElementsByTagName('script');
83+
$__curScript = scripts[scripts.length - 1];
84+
85+
if (!(window.chrome && window.chrome.extension || navigator.userAgent.match(/^Node\.js/)))
86+
supportsScriptExec = true;
87+
}
88+
89+
// script execution via injecting a script tag into the page
90+
// this allows CSP integrity and nonce to be set for CSP environments
91+
var head;
92+
function scriptExec(load) {
93+
if (!head)
94+
head = document.head || document.body || document.documentElement;
95+
96+
var script = document.createElement('script');
97+
script.text = getSource(load, false);
98+
var onerror = window.onerror;
99+
var e;
100+
window.onerror = function(_e) {
101+
e = addToError(_e, 'Evaluating ' + load.address);
102+
}
103+
preExec(this, load);
104+
105+
if (load.metadata.integrity)
106+
script.setAttribute('integrity', load.metadata.integrity);
107+
if (load.metadata.nonce)
108+
script.setAttribute('nonce', load.metadata.nonce);
109+
110+
head.appendChild(script);
111+
head.removeChild(script);
112+
postExec();
113+
window.onerror = onerror;
114+
if (e)
115+
throw e;
116+
}
117+
75118
})();

test/test-csp-inline.html

+8-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,14 @@ <h2 id="qunit-userAgent"></h2>
4343
});
4444
});
4545

46-
asyncTest('Importing a script without a nonce', function() {
46+
asyncTest('Importing a script with a bad nonce', function() {
47+
System.config({
48+
meta: {
49+
'tests/csp/nonce2.js': {
50+
nonce: 'asdf'
51+
}
52+
}
53+
});
4754
System['import']('tests/csp/nonce2.js').then(function(m) {
4855
ok(m.nonce !== 'ab');
4956
start();

0 commit comments

Comments
 (0)