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

Commit e12ec04

Browse files
committed
Fix filter for non-ascii chars
1 parent 7876f8d commit e12ec04

File tree

6 files changed

+86
-45
lines changed

6 files changed

+86
-45
lines changed

lib/filter-string.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const { BerReader, BerWriter } = require('@ldapjs/asn1')
44

55
/**
66
* Baseline LDAP filter object. This exists solely to define the interface
7-
* and basline properties and methods for actual LDAP filters.
7+
* and baseline properties and methods for actual LDAP filters.
88
*/
99
class FilterString {
1010
/**
@@ -22,7 +22,7 @@ class FilterString {
2222
type = 'FilterString'
2323

2424
/**
25-
* String value denoting which LDAP attribute the filter tagets. For example,
25+
* String value denoting which LDAP attribute the filter targets. For example,
2626
* in the filter `(&(cn=Foo Bar))`, the value would be "cn".
2727
*/
2828
attribute = ''
@@ -39,7 +39,7 @@ class FilterString {
3939
*/
4040

4141
/**
42-
* Creates a new filter object and sets the `attrbitute`.
42+
* Creates a new filter object and sets the `attribute`.
4343
*
4444
* @param {FilterStringParams} input
4545
*

lib/filters/equality.test.js

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,30 @@ tap.test('escape EqualityFilter inputs', async t => {
159159
t.equal(f.toString(), '(\\28|\\28foo=\\c3\\b1)')
160160
})
161161

162-
tap.test('encodes to BER correctly', async t => {
163-
const expected = Buffer.from([
164-
0xa3, 0x0a,
165-
0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo"
166-
0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar"
167-
])
168-
const f = new EqualityFilter({ attribute: 'foo', value: 'bar' })
169-
const ber = f.toBer()
170-
t.equal(expected.compare(ber.buffer), 0)
162+
tap.test('encodes to BER correctly', t => {
163+
t.test('basic ascii values', async t => {
164+
const expected = Buffer.from([
165+
0xa3, 0x0a,
166+
0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo"
167+
0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar"
168+
])
169+
const f = new EqualityFilter({ attribute: 'foo', value: 'bar' })
170+
const ber = f.toBer()
171+
t.equal(expected.compare(ber.buffer), 0)
172+
})
173+
174+
t.test('values with non-ascii', async t => {
175+
const expected = Buffer.from([
176+
0xa3, 0x0b,
177+
0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo"
178+
0x04, 0x04, 0xc3, 0xad, 0xc3, 0xb8 // OctetString "íø"
179+
])
180+
const f = new EqualityFilter({ attribute: 'foo', value: 'íø' })
181+
const ber = f.toBer()
182+
t.equal(expected.compare(ber.buffer), 0)
183+
})
184+
185+
t.end()
171186
})
172187

173188
tap.test('#parse', t => {

lib/string-parsing/parse-expression.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const LessThanEqualsFilter = require('../filters/less-than-equals')
77
const PresenceFilter = require('../filters/presence')
88
const SubstringFilter = require('../filters/substring')
99
const escapeSubstring = require('./escape-substring')
10-
const escapeFilterValue = require('../utils/escape-filter-value')
1110
const parseExtensibleFilterString = require('./parse-extensible-filter-string')
1211

1312
const attrRegex = /^[-_a-zA-Z0-9]+/
@@ -52,23 +51,23 @@ module.exports = function parseExpr (inputString) {
5251
} else {
5352
return new EqualityFilter({
5453
attribute,
55-
value: escapeFilterValue(remainder)
54+
value: remainder
5655
})
5756
}
5857
} else if (remainder[0] === '>' && remainder[1] === '=') {
5958
return new GreaterThanEqualsFilter({
6059
attribute,
61-
value: escapeFilterValue(remainder.substring(2))
60+
value: remainder.substring(2)
6261
})
6362
} else if (remainder[0] === '<' && remainder[1] === '=') {
6463
return new LessThanEqualsFilter({
6564
attribute,
66-
value: escapeFilterValue(remainder.substring(2))
65+
value: remainder.substring(2)
6766
})
6867
} else if (remainder[0] === '~' && remainder[1] === '=') {
6968
return new ApproximateFilter({
7069
attribute,
71-
value: escapeFilterValue(remainder.substring(2))
70+
value: remainder.substring(2)
7271
})
7372
}
7473

lib/string-parsing/parse-expression.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,21 @@ tap.test('ExtensibleFilter', t => {
8686

8787
t.end()
8888
})
89+
90+
tap.test('parses filter with non-ascii characters', t => {
91+
t.test('í', async t => {
92+
const result = parse('cn=í')
93+
t.type(result, EqualityFilter)
94+
t.equal(result.value, 'í')
95+
t.equal(result.toString(), '(cn=\\c3\\ad)')
96+
})
97+
98+
t.test('ø', async t => {
99+
const result = parse('cn=ø')
100+
t.type(result, EqualityFilter)
101+
t.equal(result.value, 'ø')
102+
t.equal(result.toString(), '(cn=\\c3\\b8)')
103+
})
104+
105+
t.end()
106+
})

lib/string-parsing/parse-string.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ module.exports = function parseString (inputString) {
2222

2323
let normalizedString = inputString
2424
if (normalizedString.charAt(0) !== '(') {
25-
// Wrap the filter in parantheticals since it is not already wrapped.
25+
// Wrap the filter in parentheses since it is not already wrapped.
2626
normalizedString = `(${normalizedString})`
2727
}
2828

lib/string-parsing/parse-string.test.js

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,27 @@ tap.test(') in filter', async t => {
8383

8484
tap.test('newlines in filter', async t => {
8585
const v1 = '\\0a'
86+
const v1Literal = '\n'
8687
const v2 = 'bar\\0a'
88+
const v2Literal = 'bar\n'
8789
const v3 = '\\0abar'
90+
const v3Literal = '\nbar'
8891
checkFilters(t, [
89-
{ str: '(foo=\n)', type: 'EqualityFilter', val: v1, output: '(foo=\\0a)' },
90-
{ str: '(foo<=\n)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=\\0a)' },
91-
{ str: '(foo>=\n)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=\\0a)' },
92+
{ str: '(foo=\n)', type: 'EqualityFilter', val: v1Literal, output: '(foo=\\0a)' },
93+
{ str: '(foo<=\n)', type: 'LessThanEqualsFilter', val: v1Literal, output: '(foo<=\\0a)' },
94+
{ str: '(foo>=\n)', type: 'GreaterThanEqualsFilter', val: v1Literal, output: '(foo>=\\0a)' },
9295
{ str: '(foo=\\0a)', type: 'EqualityFilter', val: v1, output: '(foo=\\0a)' },
9396
{ str: '(foo<=\\0a)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=\\0a)' },
9497
{ str: '(foo>=\\0a)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=\\0a)' },
95-
{ str: '(foo=bar\n)', type: 'EqualityFilter', val: v2, output: '(foo=bar\\0a)' },
96-
{ str: '(foo<=bar\n)', type: 'LessThanEqualsFilter', val: v2, output: '(foo<=bar\\0a)' },
97-
{ str: '(foo>=bar\n)', type: 'GreaterThanEqualsFilter', val: v2, output: '(foo>=bar\\0a)' },
98+
{ str: '(foo=bar\n)', type: 'EqualityFilter', val: v2Literal, output: '(foo=bar\\0a)' },
99+
{ str: '(foo<=bar\n)', type: 'LessThanEqualsFilter', val: v2Literal, output: '(foo<=bar\\0a)' },
100+
{ str: '(foo>=bar\n)', type: 'GreaterThanEqualsFilter', val: v2Literal, output: '(foo>=bar\\0a)' },
98101
{ str: '(foo=bar\\0a)', type: 'EqualityFilter', val: v2, output: '(foo=bar\\0a)' },
99102
{ str: '(foo<=bar\\0a)', type: 'LessThanEqualsFilter', val: v2, output: '(foo<=bar\\0a)' },
100103
{ str: '(foo>=bar\\0a)', type: 'GreaterThanEqualsFilter', val: v2, output: '(foo>=bar\\0a)' },
101-
{ str: '(foo=\nbar)', type: 'EqualityFilter', val: v3, output: '(foo=\\0abar)' },
102-
{ str: '(foo<=\nbar)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\0abar)' },
103-
{ str: '(foo>=\nbar)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\0abar)' },
104+
{ str: '(foo=\nbar)', type: 'EqualityFilter', val: v3Literal, output: '(foo=\\0abar)' },
105+
{ str: '(foo<=\nbar)', type: 'LessThanEqualsFilter', val: v3Literal, output: '(foo<=\\0abar)' },
106+
{ str: '(foo>=\nbar)', type: 'GreaterThanEqualsFilter', val: v3Literal, output: '(foo>=\\0abar)' },
104107
{ str: '(foo=\\0abar)', type: 'EqualityFilter', val: v3, output: '(foo=\\0abar)' },
105108
{ str: '(foo<=\\0abar)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\0abar)' },
106109
{ str: '(foo>=\\0abar)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\0abar)' }
@@ -109,24 +112,27 @@ tap.test('newlines in filter', async t => {
109112

110113
tap.test('carriage returns in filter', async t => {
111114
const v1 = '\\0d'
115+
const v1Literal = '\r'
112116
const v2 = 'bar\\0d'
117+
const v2Literal = 'bar\r'
113118
const v3 = '\\0dbar'
119+
const v3Literal = '\rbar'
114120
checkFilters(t, [
115-
{ str: '(foo=\r)', type: 'EqualityFilter', val: v1, output: '(foo=\\0d)' },
116-
{ str: '(foo<=\r)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=\\0d)' },
117-
{ str: '(foo>=\r)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=\\0d)' },
121+
{ str: '(foo=\r)', type: 'EqualityFilter', val: v1Literal, output: '(foo=\\0d)' },
122+
{ str: '(foo<=\r)', type: 'LessThanEqualsFilter', val: v1Literal, output: '(foo<=\\0d)' },
123+
{ str: '(foo>=\r)', type: 'GreaterThanEqualsFilter', val: v1Literal, output: '(foo>=\\0d)' },
118124
{ str: '(foo=\\0d)', type: 'EqualityFilter', val: v1, output: '(foo=\\0d)' },
119125
{ str: '(foo<=\\0d)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=\\0d)' },
120126
{ str: '(foo>=\\0d)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=\\0d)' },
121-
{ str: '(foo=bar\r)', type: 'EqualityFilter', val: v2, output: '(foo=bar\\0d)' },
122-
{ str: '(foo<=bar\r)', type: 'LessThanEqualsFilter', val: v2, output: '(foo<=bar\\0d)' },
123-
{ str: '(foo>=bar\r)', type: 'GreaterThanEqualsFilter', val: v2, output: '(foo>=bar\\0d)' },
127+
{ str: '(foo=bar\r)', type: 'EqualityFilter', val: v2Literal, output: '(foo=bar\\0d)' },
128+
{ str: '(foo<=bar\r)', type: 'LessThanEqualsFilter', val: v2Literal, output: '(foo<=bar\\0d)' },
129+
{ str: '(foo>=bar\r)', type: 'GreaterThanEqualsFilter', val: v2Literal, output: '(foo>=bar\\0d)' },
124130
{ str: '(foo=bar\\0d)', type: 'EqualityFilter', val: v2, output: '(foo=bar\\0d)' },
125131
{ str: '(foo<=bar\\0d)', type: 'LessThanEqualsFilter', val: v2, output: '(foo<=bar\\0d)' },
126132
{ str: '(foo>=bar\\0d)', type: 'GreaterThanEqualsFilter', val: v2, output: '(foo>=bar\\0d)' },
127-
{ str: '(foo=\rbar)', type: 'EqualityFilter', val: v3, output: '(foo=\\0dbar)' },
128-
{ str: '(foo<=\rbar)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\0dbar)' },
129-
{ str: '(foo>=\rbar)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\0dbar)' },
133+
{ str: '(foo=\rbar)', type: 'EqualityFilter', val: v3Literal, output: '(foo=\\0dbar)' },
134+
{ str: '(foo<=\rbar)', type: 'LessThanEqualsFilter', val: v3Literal, output: '(foo<=\\0dbar)' },
135+
{ str: '(foo>=\rbar)', type: 'GreaterThanEqualsFilter', val: v3Literal, output: '(foo>=\\0dbar)' },
130136
{ str: '(foo=\\0dbar)', type: 'EqualityFilter', val: v3, output: '(foo=\\0dbar)' },
131137
{ str: '(foo<=\\0dbar)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\0dbar)' },
132138
{ str: '(foo>=\\0dbar)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\0dbar)' }
@@ -135,24 +141,27 @@ tap.test('carriage returns in filter', async t => {
135141

136142
tap.test('tabs in filter', async t => {
137143
const v1 = '\\09'
144+
const v1Literal = '\t'
138145
const v2 = 'bar\\09'
146+
const v2Literal = 'bar\t'
139147
const v3 = '\\09bar'
148+
const v3Literal = '\tbar'
140149
checkFilters(t, [
141-
{ str: '(foo=\t)', type: 'EqualityFilter', val: v1, output: '(foo=\\09)' },
142-
{ str: '(foo<=\t)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=\\09)' },
143-
{ str: '(foo>=\t)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=\\09)' },
150+
{ str: '(foo=\t)', type: 'EqualityFilter', val: v1Literal, output: '(foo=\\09)' },
151+
{ str: '(foo<=\t)', type: 'LessThanEqualsFilter', val: v1Literal, output: '(foo<=\\09)' },
152+
{ str: '(foo>=\t)', type: 'GreaterThanEqualsFilter', val: v1Literal, output: '(foo>=\\09)' },
144153
{ str: '(foo=\\09)', type: 'EqualityFilter', val: v1, output: '(foo=\\09)' },
145154
{ str: '(foo<=\\09)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=\\09)' },
146155
{ str: '(foo>=\\09)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=\\09)' },
147-
{ str: '(foo=bar\t)', type: 'EqualityFilter', val: v2, output: '(foo=bar\\09)' },
148-
{ str: '(foo<=bar\t)', type: 'LessThanEqualsFilter', val: v2, output: '(foo<=bar\\09)' },
149-
{ str: '(foo>=bar\t)', type: 'GreaterThanEqualsFilter', val: v2, output: '(foo>=bar\\09)' },
156+
{ str: '(foo=bar\t)', type: 'EqualityFilter', val: v2Literal, output: '(foo=bar\\09)' },
157+
{ str: '(foo<=bar\t)', type: 'LessThanEqualsFilter', val: v2Literal, output: '(foo<=bar\\09)' },
158+
{ str: '(foo>=bar\t)', type: 'GreaterThanEqualsFilter', val: v2Literal, output: '(foo>=bar\\09)' },
150159
{ str: '(foo=bar\\09)', type: 'EqualityFilter', val: v2, output: '(foo=bar\\09)' },
151160
{ str: '(foo<=bar\\09)', type: 'LessThanEqualsFilter', val: v2, output: '(foo<=bar\\09)' },
152161
{ str: '(foo>=bar\\09)', type: 'GreaterThanEqualsFilter', val: v2, output: '(foo>=bar\\09)' },
153-
{ str: '(foo=\tbar)', type: 'EqualityFilter', val: v3, output: '(foo=\\09bar)' },
154-
{ str: '(foo<=\tbar)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\09bar)' },
155-
{ str: '(foo>=\tbar)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\09bar)' },
162+
{ str: '(foo=\tbar)', type: 'EqualityFilter', val: v3Literal, output: '(foo=\\09bar)' },
163+
{ str: '(foo<=\tbar)', type: 'LessThanEqualsFilter', val: v3Literal, output: '(foo<=\\09bar)' },
164+
{ str: '(foo>=\tbar)', type: 'GreaterThanEqualsFilter', val: v3Literal, output: '(foo>=\\09bar)' },
156165
{ str: '(foo=\\09bar)', type: 'EqualityFilter', val: v3, output: '(foo=\\09bar)' },
157166
{ str: '(foo<=\\09bar)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\09bar)' },
158167
{ str: '(foo>=\\09bar)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\09bar)' }

0 commit comments

Comments
 (0)