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

Commit 9dd0fe3

Browse files
gkalpakNarretz
authored andcommitted
fix(filterFilter): fix matching against null/undefined
Included fixes: * Do not convert `null`/`undefined` to strings for substring matching in non-strict comparison mode. Prevents `null`/`undefined` from being matched against e.g. 'u'. * Let `null` (as a top-level filter expression) match "deeply" (as do booleans, numbers and strings). E.g. let `filterFilter(arr, null)` match an item like `{someProp: null}`. Fixes #11573 Closes #11617
1 parent 7560a8d commit 9dd0fe3

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/ng/filter/filter.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,16 @@ function filterFilter() {
126126
return function(array, expression, comparator) {
127127
if (!isArray(array)) return array;
128128

129+
var expressionType = (expression !== null) ? typeof expression : 'null';
129130
var predicateFn;
130131
var matchAgainstAnyProp;
131132

132-
switch (typeof expression) {
133+
switch (expressionType) {
133134
case 'function':
134135
predicateFn = expression;
135136
break;
136137
case 'boolean':
138+
case 'null':
137139
case 'number':
138140
case 'string':
139141
matchAgainstAnyProp = true;
@@ -159,6 +161,14 @@ function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
159161
comparator = equals;
160162
} else if (!isFunction(comparator)) {
161163
comparator = function(actual, expected) {
164+
if (isUndefined(actual)) {
165+
// No substring matching against `undefined`
166+
return false;
167+
}
168+
if ((actual === null) || (expected === null)) {
169+
// No substring matching against `null`; only match against `null`
170+
return actual === expected;
171+
}
162172
if (isObject(actual) || isObject(expected)) {
163173
// Prevent an object to be considered equal to a string like `'[object'`
164174
return false;

test/ng/filter/filterSpec.js

+51
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,59 @@ describe('Filter: filter', function() {
435435
});
436436

437437

438+
it('should match `null` against `null` only', function() {
439+
var items = [
440+
{value: null},
441+
{value: undefined},
442+
{value: true},
443+
{value: false},
444+
{value: NaN},
445+
{value: 42},
446+
{value: 'null'},
447+
{value: 'test'},
448+
{value: {}},
449+
{value: new Date()}
450+
];
451+
var flt;
452+
453+
flt = null;
454+
expect(filter(items, flt).length).toBe(1);
455+
expect(filter(items, flt)[0]).toBe(items[0]);
456+
457+
flt = {value: null};
458+
expect(filter(items, flt).length).toBe(1);
459+
expect(filter(items, flt)[0]).toBe(items[0]);
460+
461+
flt = {value: undefined};
462+
expect(filter(items, flt).length).toBe(items.length);
463+
464+
flt = {value: NaN};
465+
expect(includes(filter(items, flt), items[0])).toBeFalsy();
466+
467+
flt = {value: false};
468+
expect(includes(filter(items, flt), items[0])).toBeFalsy();
469+
470+
flt = '';
471+
expect(includes(filter(items, flt), items[0])).toBeFalsy();
472+
473+
flt = {value: 'null'};
474+
expect(includes(filter(items, flt), items[0])).toBeFalsy();
475+
});
476+
477+
438478
describe('should support comparator', function() {
439479

480+
it('not convert `null` or `undefined` to string in non-strict comparison', function() {
481+
var items = [
482+
{value: null},
483+
{value: undefined}
484+
];
485+
var flt = {value: 'u'};
486+
487+
expect(filter(items, flt).length).toBe(0);
488+
});
489+
490+
440491
it('not consider `object === "[object Object]"` in non-strict comparison', function() {
441492
var items = [{test: {}}];
442493
var expr = '[object';

0 commit comments

Comments
 (0)