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

Commit 7ee3586

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 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
1 parent 8955cfb commit 7ee3586

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
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

+6-1
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,13 @@ 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+
var isString = angular.isString;
139+
137140
return function(text, target, attributes) {
138-
if (!text) return text;
141+
if (text == null) return text;
142+
if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text);
143+
139144
var match;
140145
var raw = text;
141146
var html = [];

test/ngSanitize/filter/linkySpec.js

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

23+
it('should return `undefined`/`null`/`""` values unchanged', function() {
24+
expect(linky(undefined)).toBe(undefined);
25+
expect(linky(null)).toBe(null);
26+
expect(linky('')).toBe('');
27+
});
28+
29+
it('should throw an error when used with a non-string value (other than `undefined`/`null`)',
30+
function() {
31+
expect(function() { linky(false); }).
32+
toThrowMinErr('linky', 'notstring', 'Expected string but received: false');
33+
34+
expect(function() { linky(true); }).
35+
toThrowMinErr('linky', 'notstring', 'Expected string but received: true');
36+
37+
expect(function() { linky(0); }).
38+
toThrowMinErr('linky', 'notstring', 'Expected string but received: 0');
39+
40+
expect(function() { linky(42); }).
41+
toThrowMinErr('linky', 'notstring', 'Expected string but received: 42');
42+
43+
expect(function() { linky({}); }).
44+
toThrowMinErr('linky', 'notstring', 'Expected string but received: {}');
45+
46+
expect(function() { linky([]); }).
47+
toThrowMinErr('linky', 'notstring', 'Expected string but received: []');
48+
49+
expect(function() { linky(noop); }).
50+
toThrowMinErr('linky', 'notstring', 'Expected string but received: function noop()');
51+
}
52+
);
53+
2354
it('should be case-insensitive', function() {
2455
expect(linky('WWW.example.com')).toEqual('<a href="http://WWW.example.com">WWW.example.com</a>');
2556
expect(linky('WWW.EXAMPLE.COM')).toEqual('<a href="http://WWW.EXAMPLE.COM">WWW.EXAMPLE.COM</a>');

0 commit comments

Comments
 (0)