Use Buffer storage for EqualityFilter value
Store the value portion of EqualityFilter objects in raw attribute. Certain binary-only comparisons (such as GUIDs or objectSIDs) are difficult, if not impossible, to handle without direct binary access.
This commit is contained in:
parent
b7dab1ba50
commit
87117ecdec
|
@ -3,6 +3,8 @@
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
|
||||||
|
var ASN1 = require('asn1').Ber;
|
||||||
|
|
||||||
var escape = require('./escape').escape;
|
var escape = require('./escape').escape;
|
||||||
|
|
||||||
var Filter = require('./filter');
|
var Filter = require('./filter');
|
||||||
|
@ -17,17 +19,29 @@ function EqualityFilter(options) {
|
||||||
if (typeof (options) === 'object') {
|
if (typeof (options) === 'object') {
|
||||||
if (!options.attribute || typeof (options.attribute) !== 'string')
|
if (!options.attribute || typeof (options.attribute) !== 'string')
|
||||||
throw new TypeError('options.attribute (string) required');
|
throw new TypeError('options.attribute (string) required');
|
||||||
if (!options.value || typeof (options.value) !== 'string')
|
if (!options.value)
|
||||||
throw new TypeError('options.value (string) required');
|
throw new TypeError('options.value required');
|
||||||
this.attribute = options.attribute;
|
|
||||||
this.value = options.value;
|
|
||||||
} else {
|
} else {
|
||||||
|
this.raw = new Buffer(0);
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
options.type = Protocol.FILTER_EQUALITY;
|
options.type = Protocol.FILTER_EQUALITY;
|
||||||
Filter.call(this, options);
|
Filter.call(this, options);
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
this.__defineGetter__('value', function () {
|
||||||
|
return self.raw.toString();
|
||||||
|
});
|
||||||
|
this.__defineSetter__('value', function (data) {
|
||||||
|
if (typeof (data) === 'string') {
|
||||||
|
self.raw = new Buffer(data);
|
||||||
|
} else if (Buffer.isBuffer(data)) {
|
||||||
|
self.raw = new Buffer(data.length);
|
||||||
|
data.copy(self.raw);
|
||||||
|
} else {
|
||||||
|
throw new TypeError('value (string|buffer) required');
|
||||||
|
}
|
||||||
|
});
|
||||||
this.__defineGetter__('json', function () {
|
this.__defineGetter__('json', function () {
|
||||||
return {
|
return {
|
||||||
type: 'EqualityMatch',
|
type: 'EqualityMatch',
|
||||||
|
@ -35,6 +49,10 @@ function EqualityFilter(options) {
|
||||||
value: self.value || undefined
|
value: self.value || undefined
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
if (options.attribute !== undefined && options.value !== undefined) {
|
||||||
|
this.attribute = options.attribute;
|
||||||
|
this.value = options.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
util.inherits(EqualityFilter, Filter);
|
util.inherits(EqualityFilter, Filter);
|
||||||
module.exports = EqualityFilter;
|
module.exports = EqualityFilter;
|
||||||
|
@ -71,7 +89,7 @@ EqualityFilter.prototype.parse = function (ber) {
|
||||||
assert.ok(ber);
|
assert.ok(ber);
|
||||||
|
|
||||||
this.attribute = ber.readString().toLowerCase();
|
this.attribute = ber.readString().toLowerCase();
|
||||||
this.value = ber.readString();
|
this.value = ber.readString(ASN1.OctetString, true);
|
||||||
|
|
||||||
if (this.attribute === 'objectclass')
|
if (this.attribute === 'objectclass')
|
||||||
this.value = this.value.toLowerCase();
|
this.value = this.value.toLowerCase();
|
||||||
|
@ -84,7 +102,7 @@ EqualityFilter.prototype._toBer = function (ber) {
|
||||||
assert.ok(ber);
|
assert.ok(ber);
|
||||||
|
|
||||||
ber.writeString(this.attribute);
|
ber.writeString(this.attribute);
|
||||||
ber.writeString(this.value);
|
ber.writeBuffer(this.raw, ASN1.OctetString);
|
||||||
|
|
||||||
return ber;
|
return ber;
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,9 +101,12 @@ test('parse ok', function (t) {
|
||||||
t.ok(f);
|
t.ok(f);
|
||||||
t.ok(f.parse(new BerReader(writer.buffer)));
|
t.ok(f.parse(new BerReader(writer.buffer)));
|
||||||
t.ok(f.matches({ foo: 'bar' }));
|
t.ok(f.matches({ foo: 'bar' }));
|
||||||
|
t.equal(f.attribute, 'foo');
|
||||||
|
t.equal(f.value, 'bar');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('escape EqualityFilter inputs', function (t) {
|
test('escape EqualityFilter inputs', function (t) {
|
||||||
var f = new EqualityFilter({
|
var f = new EqualityFilter({
|
||||||
attribute: '(|(foo',
|
attribute: '(|(foo',
|
||||||
|
@ -154,3 +157,28 @@ test('GH-109 = to ber uses plain values', function (t) {
|
||||||
t.equal(f.value, 'ba(r)');
|
t.equal(f.value, 'ba(r)');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('handle values passed via buffer', function (t) {
|
||||||
|
var b = new Buffer([32, 64, 128, 254]);
|
||||||
|
var f = new EqualityFilter({
|
||||||
|
attribute: 'foo',
|
||||||
|
value: b
|
||||||
|
});
|
||||||
|
t.ok(f);
|
||||||
|
|
||||||
|
var writer = new BerWriter();
|
||||||
|
f.toBer(writer);
|
||||||
|
var reader = new BerReader(writer.buffer);
|
||||||
|
reader.readSequence();
|
||||||
|
|
||||||
|
var f2 = new EqualityFilter();
|
||||||
|
t.ok(f2.parse(reader));
|
||||||
|
|
||||||
|
t.equal(f2.value, b.toString());
|
||||||
|
t.equal(f2.raw.length, b.length);
|
||||||
|
for (var i = 0; i < b.length; i++) {
|
||||||
|
t.equal(f2.raw[i], b[i]);
|
||||||
|
}
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue