Skip to content

Commit d52352a

Browse files
rjametnetman92
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 angular#12219 Closes angular#12220 Closes angular#12240
1 parent 66e4c85 commit d52352a

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
@@ -2205,7 +2205,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
22052205

22062206
$compileNode.empty();
22072207

2208-
$templateRequest($sce.getTrustedResourceUrl(templateUrl))
2208+
$templateRequest(templateUrl)
22092209
.then(function(content) {
22102210
var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;
22112211

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} a promise for the HTTP response data of the given URL.
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
@@ -1296,14 +1296,24 @@ describe('$compile', function() {
12961296
));
12971297

12981298
it('should not load cross domain templates by default', inject(
1299-
function($compile, $rootScope, $templateCache, $sce) {
1299+
function($compile, $httpBackend, $rootScope, $sce) {
13001300
expect(function() {
1301-
$templateCache.put('http://example.com/should-not-load.html', 'Should not load even if in cache.');
13021301
$compile('<div class="crossDomainTemplate"></div>')($rootScope);
13031302
}).toThrowMinErr('$sce', 'insecurl', 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example.com/should-not-load.html');
13041303
}
13051304
));
13061305

1306+
it('should trust what is already in the template cache', inject(
1307+
function($compile, $httpBackend, $rootScope, $templateCache, $sce) {
1308+
$httpBackend.expect('GET', 'http://example.com/should-not-load.html').respond('<span>example.com/remote-version</span>');
1309+
$templateCache.put('http://example.com/should-not-load.html', '<span>example.com/cached-version</span>');
1310+
element = $compile('<div class="crossDomainTemplate"></div>')($rootScope);
1311+
expect(sortedHtml(element)).toEqual('<div class="crossDomainTemplate"></div>');
1312+
$rootScope.$digest();
1313+
expect(sortedHtml(element)).toEqual('<div class="crossDomainTemplate"><span>example.com/cached-version</span></div>');
1314+
}
1315+
));
1316+
13071317
it('should load cross domain templates when trusted', inject(
13081318
function($compile, $httpBackend, $rootScope, $sce) {
13091319
$httpBackend.expect('GET', 'http://example.com/trusted-template.html').respond('<span>example.com/trusted_template_contents</span>');

0 commit comments

Comments
 (0)