From deea0fc037f7f1f0f1301c08dd8f2286ffb3a84b Mon Sep 17 00:00:00 2001 From: Raphael Jamet Date: Fri, 22 Apr 2016 14:11:30 +0200 Subject: [PATCH 1/2] fix($templateRequest): Handle empty templates in cache correctly. Fixes #14479, where $templateRequest looks for truthiness of $templateCache.get, while it should look for definedness instead. --- src/ng/templateRequest.js | 8 +++++++- test/ng/templateRequestSpec.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/ng/templateRequest.js b/src/ng/templateRequest.js index 3b34c146c147..68c8a2c966e5 100644 --- a/src/ng/templateRequest.js +++ b/src/ng/templateRequest.js @@ -68,8 +68,14 @@ function $TemplateRequestProvider() { // are included in there. This also makes Angular accept any script // directive, no matter its name. However, we still need to unwrap trusted // types. - if (!isString(tpl) || !$templateCache.get(tpl)) { + if (!isString(tpl)) { // Safe types need unwrapping. tpl = $sce.getTrustedResourceUrl(tpl); + } else { // Strings can be tested against the cache. + var cacheAnswer = $templateCache.get(tpl); + if (typeof cacheAnswer === 'undefined') { + // It is not in the cache, hence we don't trust it and it has to go through the $sce. + tpl = $sce.getTrustedResourceUrl(tpl); + } // Anything else means the cache has a record of it, so no need to check. } var transformResponse = $http.defaults && $http.defaults.transformResponse; diff --git a/test/ng/templateRequestSpec.js b/test/ng/templateRequestSpec.js index fd84027c4ca9..766d833a2e24 100644 --- a/test/ng/templateRequestSpec.js +++ b/test/ng/templateRequestSpec.js @@ -158,6 +158,37 @@ describe('$templateRequest', function() { }).not.toThrow(); })); + it('should accept empty templates and refuse null or undefined templates in cache', + inject(function($rootScope, $templateRequest, $templateCache, $sce) { + + // Will throw on any template not in cache. + spyOn($sce, 'getTrustedResourceUrl').and.returnValue(false); + + expect(function() { + $templateRequest('tpl.html'); // should go through $sce + $rootScope.$digest(); + }).toThrow(); + + $templateCache.put('tpl.html'); // is a no-op, so $sce check as well. + expect(function() { + $templateRequest('tpl.html'); + $rootScope.$digest(); + }).toThrow(); + + $templateCache.put('tpl.html', null); // makes no sense, but it's been added, so trust it. + expect(function() { + $templateRequest('tpl.html'); + $rootScope.$digest(); + }).not.toThrow(); + + $templateCache.put('tpl.html', ''); // should work (empty template) + expect(function() { + $templateRequest('tpl.html'); + $rootScope.$digest(); + }).not.toThrow(); + + })); + it('should keep track of how many requests are going on', inject(function($rootScope, $templateRequest, $httpBackend) { From b0038a3ea47318b2a736ad7c2a0c3c16e17147a6 Mon Sep 17 00:00:00 2001 From: Raphael Jamet Date: Fri, 22 Apr 2016 15:14:30 +0200 Subject: [PATCH 2/2] fix($templateRequest): Make the test more reliable, and simplify the check. Following gkalpak's comments on the PR. --- src/ng/templateRequest.js | 8 +------- test/ng/templateRequestSpec.js | 4 +++- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/ng/templateRequest.js b/src/ng/templateRequest.js index 68c8a2c966e5..f5bce1b83349 100644 --- a/src/ng/templateRequest.js +++ b/src/ng/templateRequest.js @@ -68,14 +68,8 @@ function $TemplateRequestProvider() { // are included in there. This also makes Angular accept any script // directive, no matter its name. However, we still need to unwrap trusted // types. - if (!isString(tpl)) { // Safe types need unwrapping. + if (!isString(tpl) || isUndefined($templateCache.get(tpl))) { tpl = $sce.getTrustedResourceUrl(tpl); - } else { // Strings can be tested against the cache. - var cacheAnswer = $templateCache.get(tpl); - if (typeof cacheAnswer === 'undefined') { - // It is not in the cache, hence we don't trust it and it has to go through the $sce. - tpl = $sce.getTrustedResourceUrl(tpl); - } // Anything else means the cache has a record of it, so no need to check. } var transformResponse = $http.defaults && $http.defaults.transformResponse; diff --git a/test/ng/templateRequestSpec.js b/test/ng/templateRequestSpec.js index 766d833a2e24..dc78e21f3bc8 100644 --- a/test/ng/templateRequestSpec.js +++ b/test/ng/templateRequestSpec.js @@ -174,19 +174,21 @@ describe('$templateRequest', function() { $templateRequest('tpl.html'); $rootScope.$digest(); }).toThrow(); + $templateCache.removeAll(); $templateCache.put('tpl.html', null); // makes no sense, but it's been added, so trust it. expect(function() { $templateRequest('tpl.html'); $rootScope.$digest(); }).not.toThrow(); + $templateCache.removeAll(); $templateCache.put('tpl.html', ''); // should work (empty template) expect(function() { $templateRequest('tpl.html'); $rootScope.$digest(); }).not.toThrow(); - + $templateCache.removeAll(); })); it('should keep track of how many requests are going on',