Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
fix(linky): throw error if input is not a string
Browse files Browse the repository at this point in the history
BREAKING CHANGE:

Before this change, the filter assumed that the input (if not undefined/null) was of type 'string'
and that certain methods (such as `.match()`) would be available on it. Passing a non-string value
would most likely result in a not-very-useful error being thrown (trying to call a method that does
not exist) or in unexpected behavior (if the input happened to have the assumed methods).

After this change, a proper (informative) error will be thrown. If you want to pass non-string
values through `linky`, you need to explicitly convert them to strings first.
Since input values could be initialized asynchronously, `undefined` or `null` will still be
returned unchanged (without throwing an error).

Closes #13547

Closes #13693
  • Loading branch information
gkalpak committed Jan 8, 2016
1 parent 06aa52e commit 98c2db7
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
16 changes: 16 additions & 0 deletions 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
<div ng-bind-html="42 | linky"></div>
```

`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.
7 changes: 6 additions & 1 deletion src/ngSanitize/filter/linky.js
Expand Up @@ -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 = [];
Expand Down
31 changes: 31 additions & 0 deletions test/ngSanitize/filter/linkySpec.js
Expand Up @@ -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('<a href="http://WWW.example.com">WWW.example.com</a>');
expect(linky('WWW.EXAMPLE.COM')).toEqual('<a href="http://WWW.EXAMPLE.COM">WWW.EXAMPLE.COM</a>');
Expand Down

0 comments on commit 98c2db7

Please sign in to comment.