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:
Patrick Mooney 2014-06-01 19:46:11 -05:00
parent b7dab1ba50
commit 87117ecdec
2 changed files with 52 additions and 6 deletions

View File

@ -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;
}; };

View File

@ -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();
});