Skip to content

Commit 9af6e91

Browse files
committed
fix(linky): throw error if input is not a string
BREAKING CHANGE: Before this change, the filter assumed that the input (if not falsy) was of type 'string' and that certain methods (such as `.match()`) would be available on it. This would most likely result in an 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. Closes angular#13547
1 parent 8955cfb commit 9af6e91

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
@ngdoc error
2+
@name linky:notstring
3+
@fullName Not a string
4+
@description
5+
6+
This error occurs when {@link ngSanitize.linky linky} is used with a non-empty, non-string value:
7+
```html
8+
<div ng-bind-html="42 | linky"></div>
9+
```
10+
11+
`linky` is supposed to be used with string values only, and therefore assumes that several methods
12+
(such as `.match()`) are available on the passed in value.
13+
The value can be initialized asynchronously and therefore null or undefined won't throw this error.
14+
15+
If you want to pass non-string values to `linky` (e.g. Objects whose `.toString()` should be
16+
utilized), you need to manually convert them to strings.

src/ngSanitize/filter/linky.js

+4
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,12 @@ angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
134134
/((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,
135135
MAILTO_REGEXP = /^mailto:/i;
136136

137+
var linkyMinErr = angular.$$minErr('linky');
138+
137139
return function(text, target, attributes) {
138140
if (!text) return text;
141+
if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text);
142+
139143
var match;
140144
var raw = text;
141145
var html = [];

test/ngSanitize/filter/linkySpec.js

+22
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,28 @@ describe('linky', function() {
2020
expect(linky(undefined)).not.toBeDefined();
2121
});
2222

23+
they('should return falsy values (such as $prop) unchanged', {
24+
'undefined': undefined,
25+
'null': null,
26+
'false': false,
27+
'0': 0,
28+
'\'\'': ''
29+
}, function(value) {
30+
expect(value).toBeFalsy();
31+
expect(linky(value)).toBe(value);
32+
});
33+
34+
they('should throw an error when used with a non-empty, non-string value (such as $prop)', {
35+
'true': true,
36+
'42': 42,
37+
'{}': {},
38+
'[]': [],
39+
'noop()': noop
40+
}, function(value) {
41+
expect(function() { linky(value); }).
42+
toThrowMinErr('linky', 'notstring', 'Expected string but received: ' + toDebugString(value));
43+
});
44+
2345
it('should be case-insensitive', function() {
2446
expect(linky('WWW.example.com')).toEqual('<a href="http://WWW.example.com">WWW.example.com</a>');
2547
expect(linky('WWW.EXAMPLE.COM')).toEqual('<a href="http://WWW.EXAMPLE.COM">WWW.EXAMPLE.COM</a>');

0 commit comments

Comments
 (0)