diff --git a/docs/content/error/linky/notstring.ngdoc b/docs/content/error/linky/notstring.ngdoc new file mode 100644 index 000000000000..159ac42de123 --- /dev/null +++ b/docs/content/error/linky/notstring.ngdoc @@ -0,0 +1,16 @@ +@ngdoc error +@name linky:notstring +@fullName Not a string +@description + +This error occurs when {@link ngSanitize.linky linky} is used with a non-empty, non-string value: +```html +
+``` + +`linky` is supposed to be used with string values only, and therefore assumes that several methods +(such as `.match()`) are available on the passed in value. +The value can be initialized asynchronously and therefore null or undefined won't throw this error. + +If you want to pass non-string values to `linky` (e.g. Objects whose `.toString()` should be +utilized), you need to manually convert them to strings. diff --git a/src/ngSanitize/filter/linky.js b/src/ngSanitize/filter/linky.js index 2780d74c0b33..495dd80af7ab 100644 --- a/src/ngSanitize/filter/linky.js +++ b/src/ngSanitize/filter/linky.js @@ -134,8 +134,13 @@ angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) { /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i, MAILTO_REGEXP = /^mailto:/i; + var linkyMinErr = angular.$$minErr('linky'); + var isString = angular.isString; + return function(text, target, attributes) { - if (!text) return text; + if (text == null || text === '') return text; + if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text); + var match; var raw = text; var html = []; diff --git a/test/ngSanitize/filter/linkySpec.js b/test/ngSanitize/filter/linkySpec.js index a3dafb18ddce..5077ae9bf406 100644 --- a/test/ngSanitize/filter/linkySpec.js +++ b/test/ngSanitize/filter/linkySpec.js @@ -20,6 +20,37 @@ describe('linky', function() { expect(linky(undefined)).not.toBeDefined(); }); + it('should return `undefined`/`null`/`""` values unchanged', function() { + expect(linky(undefined)).toBe(undefined); + expect(linky(null)).toBe(null); + expect(linky('')).toBe(''); + }); + + it('should throw an error when used with a non-string value (other than `undefined`/`null`)', + function() { + expect(function() { linky(false); }). + toThrowMinErr('linky', 'notstring', 'Expected string but received: false'); + + expect(function() { linky(true); }). + toThrowMinErr('linky', 'notstring', 'Expected string but received: true'); + + expect(function() { linky(0); }). + toThrowMinErr('linky', 'notstring', 'Expected string but received: 0'); + + expect(function() { linky(42); }). + toThrowMinErr('linky', 'notstring', 'Expected string but received: 42'); + + expect(function() { linky({}); }). + toThrowMinErr('linky', 'notstring', 'Expected string but received: {}'); + + expect(function() { linky([]); }). + toThrowMinErr('linky', 'notstring', 'Expected string but received: []'); + + expect(function() { linky(noop); }). + toThrowMinErr('linky', 'notstring', 'Expected string but received: function noop()'); + } + ); + it('should be case-insensitive', function() { expect(linky('WWW.example.com')).toEqual('WWW.example.com'); expect(linky('WWW.EXAMPLE.COM')).toEqual('WWW.EXAMPLE.COM');