diff --git a/src/ng/sce.js b/src/ng/sce.js index a5f618ef8fe4..45f90a8af951 100644 --- a/src/ng/sce.js +++ b/src/ng/sce.js @@ -440,7 +440,7 @@ function $SceDelegateProvider() { // If we get here, then we will either sanitize the value or throw an exception. if (type === SCE_CONTEXTS.MEDIA_URL || type === SCE_CONTEXTS.URL) { // we attempt to sanitize non-resource URLs - return $$sanitizeUri(maybeTrusted, type === SCE_CONTEXTS.MEDIA_URL); + return $$sanitizeUri(maybeTrusted.toString(), type === SCE_CONTEXTS.MEDIA_URL); } else if (type === SCE_CONTEXTS.RESOURCE_URL) { if (isResourceUrlAllowedByPolicy(maybeTrusted)) { return maybeTrusted; diff --git a/test/ng/directive/ngHrefSpec.js b/test/ng/directive/ngHrefSpec.js index 6d44ac8b5631..2c5e99c076b3 100644 --- a/test/ng/directive/ngHrefSpec.js +++ b/test/ng/directive/ngHrefSpec.js @@ -79,6 +79,42 @@ describe('ngHref', function() { })); } + + it('should bind numbers', inject(function($rootScope, $compile) { + element = $compile('')($rootScope); + $rootScope.$digest(); + expect(element.attr('href')).toEqual('1234'); + })); + + + it('should bind and sanitize the result of a (custom) toString() function', inject(function($rootScope, $compile) { + $rootScope.value = {}; + element = $compile('')($rootScope); + $rootScope.$digest(); + expect(element.attr('href')).toEqual('[object Object]'); + + function SafeClass() {} + + SafeClass.prototype.toString = function() { + return 'custom value'; + }; + + $rootScope.value = new SafeClass(); + $rootScope.$digest(); + expect(element.attr('href')).toEqual('custom value'); + + function UnsafeClass() {} + + UnsafeClass.prototype.toString = function() { + return 'javascript:alert(1);'; + }; + + $rootScope.value = new UnsafeClass(); + $rootScope.$digest(); + expect(element.attr('href')).toEqual('unsafe:javascript:alert(1);'); + })); + + if (isDefined(window.SVGElement)) { describe('SVGAElement', function() { it('should interpolate the expression and bind to xlink:href', inject(function($compile, $rootScope) {