Skip to content

Commit 367da58

Browse files
Parent5446petebacondarwin
authored andcommitted
fix($sniffer): don't use history.pushState in sandboxed Chrome Packaged Apps
While sandboxed Chrome Packaged Apps (CPAs) have the same restrictions wrt accessing `history.pushState` as "normal" CPAs, they can't be detected in the same way, as they do not have access to the same APIs. Previously, due to their differences from normal CPAs, `$sniffer` would fail to detect sandboxed CPAs and incorrectly assume `history.pushState` is available (which resulted in an error being thrown). This commit fixes the detection of sandboxed CPAs in `$sniffer`. See angular#11932 and angular#13945 for previous work. Closes angular#15021
1 parent 68fb70e commit 367da58

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/ng/sniffer.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@
2020
function $SnifferProvider() {
2121
this.$get = ['$window', '$document', function($window, $document) {
2222
var eventSupport = {},
23-
// Chrome Packaged Apps are not allowed to access `history.pushState`. They can be detected by
24-
// the presence of `chrome.app.runtime` (see https://developer.chrome.com/apps/api_index)
25-
isChromePackagedApp = $window.chrome && $window.chrome.app && $window.chrome.app.runtime,
23+
// Chrome Packaged Apps are not allowed to access `history.pushState`.
24+
// If not sandboxed, they can be detected by the presence of `chrome.app.runtime`
25+
// (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by
26+
// the presence of an extension runtime ID and the absence of other Chrome runtime APIs
27+
// (see https://developer.chrome.com/apps/manifest/sandbox).
28+
isChromePackagedApp =
29+
$window.chrome &&
30+
($window.chrome.app && $window.chrome.app.runtime ||
31+
!$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id),
2632
hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState,
2733
android =
2834
toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),

test/ng/snifferSpec.js

+22
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,28 @@ describe('$sniffer', function() {
9090

9191
expect(pushStateAccessCount).toBe(0);
9292
});
93+
94+
it('should not try to access `history.pushState` in sandboxed Chrome Packaged Apps',
95+
function() {
96+
var pushStateAccessCount = 0;
97+
98+
var mockHistory = Object.create(Object.prototype, {
99+
pushState: {get: function() { pushStateAccessCount++; return noop; }}
100+
});
101+
var mockWindow = {
102+
chrome: {
103+
runtime: {
104+
id: 'x'
105+
}
106+
},
107+
history: mockHistory
108+
};
109+
110+
sniffer(mockWindow);
111+
112+
expect(pushStateAccessCount).toBe(0);
113+
}
114+
);
93115
});
94116

95117

0 commit comments

Comments
 (0)