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) {