Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ldapjs/filter

Package Overview
Dependencies
Maintainers
4
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ldapjs/filter - npm Package Compare versions

Comparing version 2.0.0-rc.2 to 2.0.0-rc.3

lib/ber-parsing/_fixtures/evolution-filter.js

87

lib/ber-parsing/index.js
'use strict'
const protocol = require('@ldapjs/protocol')
const { search } = require('@ldapjs/protocol')
const AndFilter = require('../filters/and')
const ApproximateFilter = require('../filters/approximate')
const EqualityFilter = require('../filters/equality')
const ExtensibleFilter = require('../filters/extensible')
const GreaterThanEqualsFilter = require('../filters/greater-than-equals')
const LessThanEqualsFilter = require('../filters/less-than-equals')
const NotFilter = require('../filters/not')
const OrFilter = require('../filters/or')
const PresenceFilter = require('../filters/presence')
const SubstringFilter = require('../filters/substring')
const FILTERS = {
[search.FILTER_AND]: require('../filters/and'),
[search.FILTER_APPROX]: require('../filters/approximate'),
[search.FILTER_EQUALITY]: require('../filters/equality'),
[search.FILTER_EXT]: require('../filters/extensible'),
[search.FILTER_GE]: require('../filters/greater-than-equals'),
[search.FILTER_LE]: require('../filters/less-than-equals'),
[search.FILTER_NOT]: require('../filters/not'),
[search.FILTER_OR]: require('../filters/or'),
[search.FILTER_PRESENT]: require('../filters/presence'),
[search.FILTER_SUBSTRINGS]: require('../filters/substring')
}

@@ -37,6 +39,8 @@ /**

const filterStartOffset = ber.offset
const type = ber.readSequence()
switch (type) {
case protocol.search.FILTER_AND: {
f = new AndFilter()
case search.FILTER_AND:
case search.FILTER_OR: {
f = new FILTERS[type]()
parseSet(f)

@@ -46,49 +50,19 @@ break

case protocol.search.FILTER_APPROX: {
f = ApproximateFilter.parse(getBerBuffer(ber))
break
}
case protocol.search.FILTER_EQUALITY: {
f = EqualityFilter.parse(getBerBuffer(ber))
return f
}
case protocol.search.FILTER_EXT: {
f = ExtensibleFilter.parse(getBerBuffer(ber))
return f
}
case protocol.search.FILTER_GE: {
f = GreaterThanEqualsFilter.parse(getBerBuffer(ber))
return f
}
case protocol.search.FILTER_LE: {
f = LessThanEqualsFilter.parse(getBerBuffer(ber))
return f
}
case protocol.search.FILTER_NOT: {
case search.FILTER_NOT: {
const innerFilter = _parse(ber)
f = new NotFilter({ filter: innerFilter })
f = new FILTERS[type]({ filter: innerFilter })
break
}
case protocol.search.FILTER_OR: {
f = new OrFilter()
parseSet(f)
case search.FILTER_APPROX:
case search.FILTER_EQUALITY:
case search.FILTER_EXT:
case search.FILTER_GE:
case search.FILTER_LE:
case search.FILTER_PRESENT:
case search.FILTER_SUBSTRINGS: {
f = FILTERS[type].parse(getBerBuffer(ber))
break
}
case protocol.search.FILTER_PRESENT: {
f = PresenceFilter.parse(getBerBuffer(ber))
break
}
case protocol.search.FILTER_SUBSTRINGS: {
f = SubstringFilter.parse(getBerBuffer(ber))
break
}
default: {

@@ -105,3 +79,6 @@ throw Error(

const end = ber.offset + ber.length
while (ber.offset < end) { f.addClause(_parse(ber)) }
while (ber.offset < end) {
const parsed = _parse(ber)
f.addClause(parsed)
}
}

@@ -117,3 +94,3 @@

// construct a valid TLV buffer, we must rewind the offset by 2 bytes.
ber.setOffset(ber.offset - 2)
ber.setOffset(filterStartOffset)

@@ -120,0 +97,0 @@ // Next, we need the tag so that we can supply it to the raw buffer read

@@ -17,2 +17,3 @@ 'use strict'

const SubstringFilter = require('../filters/substring')
const parseString = require('../string-parsing/parse-string')

@@ -196,1 +197,12 @@ tap.test('throws if BerReader not supplied', async t => {

})
tap.test('parses evolution filter', async t => {
const evolutionFilterFixture = require('./_fixtures/evolution-filter')
const filter = parseString(evolutionFilterFixture.text)
const ber = filter.toBer()
t.equal(ber.buffer.compare(evolutionFilterFixture.bytes), 0)
const filterFromBer = parse(ber)
t.equal(filterFromBer.toString(), evolutionFilterFixture.text)
})
'use strict'
const FilterString = require('../filter-string')
const { BerReader } = require('@ldapjs/asn1')
const { search } = require('@ldapjs/protocol')

@@ -107,19 +106,8 @@

static parse (buffer) {
const reader = new BerReader(buffer)
const seq = reader.readSequence()
if (seq !== search.FILTER_AND) {
const expected = '0x' + search.FILTER_AND.toString(16).padStart(2, '0')
const found = '0x' + seq.toString(16).padStart(2, '0')
throw Error(`expected and filter sequence ${expected}, got ${found}`)
}
// TODO: in order to parse a AND filter, we need to read the lenght
// and the next tag. We must then parse the filter represented by
// that tag and pass sub-buffer (of the read length) to the associated
// filter's parse method. Which means we need to first finish all other
// filter implementations. ~ 2022-06-19
const filter = new FilterString()
return new AndFilter({ filters: [filter] })
const parseNestedFilter = require('./utils/parse-nested-filter')
return parseNestedFilter({
buffer,
constructor: AndFilter,
startTag: search.FILTER_AND
})
}

@@ -126,0 +114,0 @@ }

@@ -77,12 +77,16 @@ 'use strict'

t.test('parses buffer', async t => {
const input = Buffer.from([
0xa0, 0x0c, 0xa3, 0x0a, // and tag, length, eq tag, length
0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo"
0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar"
])
const f = AndFilter.parse(input)
const input = new AndFilter({
filters: [new EqualityFilter({ attribute: 'cn', value: 'foo' })]
})
const f = AndFilter.parse(input.toBer().buffer)
t.equal(f.clauses.length, 1)
t.equal(f.toString(), '(&())')
t.equal(f.toString(), '(&(cn=foo))')
})
t.test('parses simple all-match filter', async t => {
const input = Buffer.from([0xa0, 0x00])
const f = AndFilter.parse(input)
t.equal(f.toString(), '(&)')
})
t.test('throws for unexpected sequence', async t => {

@@ -96,3 +100,3 @@ const input = Buffer.from([

() => AndFilter.parse(input),
Error('expected and filter sequence 0xa0, got 0xa3')
Error('expected filter tag 0xa0, got 0xa3')
)

@@ -99,0 +103,0 @@ })

'use strict'
const FilterString = require('../filter-string')
const { BerReader } = require('@ldapjs/asn1')
const { search } = require('@ldapjs/protocol')

@@ -105,19 +104,8 @@

static parse (buffer) {
const reader = new BerReader(buffer)
const seq = reader.readSequence()
if (seq !== search.FILTER_NOT) {
const expected = '0x' + search.FILTER_NOT.toString(16).padStart(2, '0')
const found = '0x' + seq.toString(16).padStart(2, '0')
throw Error(`expected not filter sequence ${expected}, got ${found}`)
}
// TODO: in order to parse a NOT filter, we need to read the lenght
// and the next tag. We must then parse the filter represented by
// that tag and pass sub-buffer (of the read length) to the associated
// filter's parse method. Which means we need to first finish all other
// filter implementations. ~ 2022-06-19
const filter = new FilterString()
return new NotFilter({ filter })
const parseNestedFilter = require('./utils/parse-nested-filter')
return parseNestedFilter({
buffer,
constructor: NotFilter,
startTag: search.FILTER_NOT
})
}

@@ -124,0 +112,0 @@ }

'use strict'
const tap = require('tap')
const EqualityFilter = require('./equality')
const NotFilter = require('./not')
const EqualityFilter = require('./equality')
const FilterString = require('../filter-string')

@@ -86,10 +84,8 @@ tap.test('Construct args', async t => {

t.test('parses buffer', async t => {
const input = Buffer.from([
0xa2, 0x0c, 0xa3, 0x0a, // not tag, length, eq tag, length
0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo"
0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar"
])
const f = NotFilter.parse(input)
t.equal(f.filter instanceof FilterString, true)
t.equal(f.toString(), '(!())')
const input = new NotFilter({
filter: new EqualityFilter({ attribute: 'cn', value: 'foo' })
})
const f = NotFilter.parse(input.toBer().buffer)
t.equal(f.clauses.length, 1)
t.equal(f.toString(), '(!(cn=foo))')
})

@@ -105,3 +101,3 @@

() => NotFilter.parse(input),
Error('expected not filter sequence 0xa2, got 0xa3')
Error('expected filter tag 0xa2, got 0xa3')
)

@@ -108,0 +104,0 @@ })

'use strict'
const FilterString = require('../filter-string')
const { BerReader } = require('@ldapjs/asn1')
const { search } = require('@ldapjs/protocol')

@@ -107,19 +106,8 @@

static parse (buffer) {
const reader = new BerReader(buffer)
const seq = reader.readSequence()
if (seq !== search.FILTER_OR) {
const expected = '0x' + search.FILTER_OR.toString(16).padStart(2, '0')
const found = '0x' + seq.toString(16).padStart(2, '0')
throw Error(`expected or filter sequence ${expected}, got ${found}`)
}
// TODO: in order to parse a OR filter, we need to read the lenght
// and the next tag. We must then parse the filter represented by
// that tag and pass sub-buffer (of the read length) to the associated
// filter's parse method. Which means we need to first finish all other
// filter implementations. ~ 2022-06-19
const filter = new FilterString()
return new OrFilter({ filters: [filter] })
const parseNestedFilter = require('./utils/parse-nested-filter')
return parseNestedFilter({
buffer,
constructor: OrFilter,
startTag: search.FILTER_OR
})
}

@@ -126,0 +114,0 @@ }

@@ -5,2 +5,3 @@ 'use strict'

const EqualityFilter = require('./equality')
const SubstringFilter = require('./substring')
const OrFilter = require('./or')

@@ -64,12 +65,40 @@

tap.test('encodes to BER correctly', async t => {
const expected = Buffer.from([
0xa1, 0x0c, 0xa3, 0x0a, // or tag, length, eq tag, length
0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo"
0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar"
])
const eqFilter = new EqualityFilter({ attribute: 'foo', value: 'bar' })
const f = new OrFilter({ filters: [eqFilter] })
const ber = f.toBer()
t.equal(expected.compare(ber.buffer), 0)
tap.test('toBer', t => {
t.test('encodes to BER correctly', async t => {
const expected = Buffer.from([
0xa1, 0x0c, 0xa3, 0x0a, // or tag, length, eq tag, length
0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo"
0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar"
])
const eqFilter = new EqualityFilter({
attribute: 'foo',
value: 'bar'
})
const f = new OrFilter({ filters: [eqFilter] })
const ber = f.toBer()
t.equal(expected.compare(ber.buffer), 0)
})
t.test('encodes substring filters', async t => {
const expected = Buffer.from([
0xa1, 0x0d, // or tag, 13 bytes
0xa4, 0x0b, // sequence (substring tag), 11 bytes
0x04, 0x02, // string, 2 bytes
// "cn"
0x63, 0x6e,
0x30, 0x05, // sequence, 5 bytes
0x80, 0x03, // string (subinitial tag), 3 bytes
// "foo"
0x66, 0x6f, 0x6f
])
const subFilter = new SubstringFilter({
attribute: 'cn',
subInitial: 'foo'
})
const f = new OrFilter({ filters: [subFilter] })
const ber = f.toBer()
t.equal(expected.compare(ber.buffer), 0)
})
t.end()
})

@@ -86,3 +115,3 @@

t.equal(f.clauses.length, 1)
t.equal(f.toString(), '(|())')
t.equal(f.toString(), '(|(foo=bar))')
})

@@ -98,7 +127,33 @@

() => OrFilter.parse(input),
Error('expected or filter sequence 0xa1, got 0xa3')
Error('expected filter tag 0xa1, got 0xa3')
)
})
t.test('parses a set of substring filters', async t => {
const input = Buffer.from([
0xa1, 0x1a, // or tag, 26 bytes
0xa4, 0x0b, // sequence (substring tag), 11 bytes
0x04, 0x02, // string, 2 bytes
// "cn"
0x63, 0x6e,
0x30, 0x05, // sequence, 5 bytes
0x80, 0x03, // string (subinitial tag), 3 bytes
// "foo"
0x66, 0x6f, 0x6f,
0xa4, 0x0b, // sequence (substring tag), 11 bytes
0x04, 0x02, // string, 2 bytes
// "sn"
0x73, 0x6e,
0x30, 0x05, // sequence, 5 bytes
0x80, 0x03, // string (subinitial tag), 3 bytes
0x66, 0x6f, 0x6f
])
const filter = OrFilter.parse(input)
t.equal(filter.toString(), '(|(cn=foo*)(sn=foo*))')
})
t.end()
})

@@ -142,2 +142,4 @@ 'use strict'

_toBer (ber) {
// Tag sequence as already been started via FilterString.toBer, so
// start by writing the "type" field.
ber.writeString(this.attribute)

@@ -144,0 +146,0 @@ ber.startSequence()

@@ -45,9 +45,13 @@ 'use strict'

cur++
do {
res = parseFilter(inputString, cur)
children.push(res.filter)
cur = res.end + 1
} while (cur < len && inputString[cur] !== ')')
if (inputString[cur] === ')') {
output = new AndFilter({})
} else {
do {
res = parseFilter(inputString, cur)
children.push(res.filter)
cur = res.end + 1
} while (cur < len && inputString[cur] !== ')')
output = new AndFilter({ filters: children })
output = new AndFilter({ filters: children })
}
} else if (inputString[cur] === '|') {

@@ -54,0 +58,0 @@ cur++

@@ -26,2 +26,9 @@ 'use strict'

tap.test('AndFilter', t => {
t.test('match all', async t => {
const result = parse('(&)')
t.equal(result.end, 2)
t.type(result.filter, AndFilter)
t.equal(result.filter.toString(), '(&)')
})
t.test('simple', async t => {

@@ -28,0 +35,0 @@ const result = parse('(&(cn=foo))')

@@ -10,3 +10,3 @@ {

"description": "API for handling LDAP-style filters",
"version": "2.0.0-rc.2",
"version": "2.0.0-rc.3",
"license": "MIT",

@@ -22,3 +22,3 @@ "repository": {

"dependencies": {
"@ldapjs/asn1": "2.0.0-rc.2",
"@ldapjs/asn1": "2.0.0-rc.3",
"@ldapjs/protocol": "^1.2.1",

@@ -25,0 +25,0 @@ "process-warning": "^2.1.0"

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc