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

Commit 8cc5da1

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 #13547
1 parent 8955cfb commit 8cc5da1

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-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

+5
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) {
138141
if (!text) 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

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

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

0 commit comments

Comments
 (0)