Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 74ecea9

Browse files
rjametIgorMinar
authored andcommitted
refactor($templateRequest): move $sce checks and trust the cache
Move all the calls to $sce.getTrustedUrl inside $templateRequest, and also trust the contents of the cache. This allows prefetching templates and to bypass the checks on things where they make no sense, like templates specified in script tags. Closes #12219 Closes #12220 Closes #12240
1 parent 8d5c08c commit 74ecea9

File tree

5 files changed

+28
-10
lines changed

5 files changed

+28
-10
lines changed

src/ng/compile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2193,7 +2193,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
21932193

21942194
$compileNode.empty();
21952195

2196-
$templateRequest($sce.getTrustedResourceUrl(templateUrl))
2196+
$templateRequest(templateUrl)
21972197
.then(function(content) {
21982198
var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;
21992199

src/ng/directive/ngInclude.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@
178178
* @param {Object} angularEvent Synthetic event object.
179179
* @param {String} src URL of content to load.
180180
*/
181-
var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate', '$sce',
182-
function($templateRequest, $anchorScroll, $animate, $sce) {
181+
var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate',
182+
function($templateRequest, $anchorScroll, $animate) {
183183
return {
184184
restrict: 'ECA',
185185
priority: 400,
@@ -215,7 +215,7 @@ var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate', '$sce
215215
}
216216
};
217217

218-
scope.$watch($sce.parseAsResourceUrl(srcExp), function ngIncludeWatchAction(src) {
218+
scope.$watch(srcExp, function ngIncludeWatchAction(src) {
219219
var afterAnimation = function() {
220220
if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
221221
$anchorScroll();

src/ng/templateRequest.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,27 @@ var $compileMinErr = minErr('$compile');
1212
* of the HTTP request is empty, a `$compile` error will be thrown (the exception can be thwarted
1313
* by setting the 2nd parameter of the function to true).
1414
*
15-
* @param {string} tpl The HTTP request template URL
15+
* @param {string|TrustedResourceUrl} tpl The HTTP request template URL
1616
* @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty
1717
*
1818
* @return {Promise} the HTTP Promise for the given.
1919
*
2020
* @property {number} totalPendingRequests total amount of pending template requests being downloaded.
2121
*/
2222
function $TemplateRequestProvider() {
23-
this.$get = ['$templateCache', '$http', '$q', function($templateCache, $http, $q) {
23+
this.$get = ['$templateCache', '$http', '$q', '$sce', function($templateCache, $http, $q, $sce) {
2424
function handleRequestFn(tpl, ignoreRequestError) {
2525
handleRequestFn.totalPendingRequests++;
2626

27+
// We consider the template cache holds only trusted templates, so
28+
// there's no need to go through whitelisting again for keys that already
29+
// are included in there. This also makes Angular accept any script
30+
// directive, no matter its name. However, we still need to unwrap trusted
31+
// types.
32+
if (!isString(tpl) || !$templateCache.get(tpl)) {
33+
tpl = $sce.getTrustedResourceUrl(tpl);
34+
}
35+
2736
var transformResponse = $http.defaults && $http.defaults.transformResponse;
2837

2938
if (isArray(transformResponse)) {

src/ngRoute/route.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -591,9 +591,8 @@ function $RouteProvider() {
591591
if (angular.isFunction(templateUrl)) {
592592
templateUrl = templateUrl(nextRoute.params);
593593
}
594-
templateUrl = $sce.getTrustedResourceUrl(templateUrl);
595594
if (angular.isDefined(templateUrl)) {
596-
nextRoute.loadedTemplateUrl = templateUrl;
595+
nextRoute.loadedTemplateUrl = $sce.valueOf(templateUrl);
597596
template = $templateRequest(templateUrl);
598597
}
599598
}

test/ng/compileSpec.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,14 +1281,24 @@ describe('$compile', function() {
12811281
));
12821282

12831283
it('should not load cross domain templates by default', inject(
1284-
function($compile, $rootScope, $templateCache, $sce) {
1284+
function($compile, $httpBackend, $rootScope, $sce) {
12851285
expect(function() {
1286-
$templateCache.put('http://example.com/should-not-load.html', 'Should not load even if in cache.');
12871286
$compile('<div class="crossDomainTemplate"></div>')($rootScope);
12881287
}).toThrowMinErr('$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example.com/should-not-load.html');
12891288
}
12901289
));
12911290

1291+
it('should trust what is already in the template cache', inject(
1292+
function($compile, $httpBackend, $rootScope, $templateCache, $sce) {
1293+
$httpBackend.expect('GET', 'http://example.com/should-not-load.html').respond('<span>example.com/remote-version</span>');
1294+
$templateCache.put('http://example.com/should-not-load.html', '<span>example.com/cached-version</span>');
1295+
element = $compile('<div class="crossDomainTemplate"></div>')($rootScope);
1296+
expect(sortedHtml(element)).toEqual('<div class="crossDomainTemplate"></div>');
1297+
$rootScope.$digest();
1298+
expect(sortedHtml(element)).toEqual('<div class="crossDomainTemplate"><span>example.com/cached-version</span></div>');
1299+
}
1300+
));
1301+
12921302
it('should load cross domain templates when trusted', inject(
12931303
function($compile, $httpBackend, $rootScope, $sce) {
12941304
$httpBackend.expect('GET', 'http://example.com/trusted-template.html').respond('<span>example.com/trusted_template_contents</span>');

0 commit comments

Comments
 (0)