Merge pull request #65 from ozten/master

RFC 2254 filter escaping
This commit is contained in:
Mark Cavage 2012-03-14 08:54:29 -07:00
commit ac17609be8
9 changed files with 101 additions and 16 deletions

View File

@ -3,6 +3,8 @@
var assert = require('assert'); var assert = require('assert');
var util = require('util'); var util = require('util');
var escape = require('./escape').escape;
var Filter = require('./filter'); var Filter = require('./filter');
var Protocol = require('../protocol'); var Protocol = require('../protocol');
@ -17,8 +19,8 @@ function ApproximateFilter(options) {
throw new TypeError('options.attribute (string) required'); throw new TypeError('options.attribute (string) required');
if (!options.value || typeof (options.value) !== 'string') if (!options.value || typeof (options.value) !== 'string')
throw new TypeError('options.value (string) required'); throw new TypeError('options.value (string) required');
this.attribute = options.attribute; this.attribute = escape(options.attribute);
this.value = options.value; this.value = escape(options.value);
} else { } else {
options = {}; options = {};
} }

View File

@ -3,6 +3,8 @@
var assert = require('assert'); var assert = require('assert');
var util = require('util'); var util = require('util');
var escape = require('./escape').escape;
var Filter = require('./filter'); var Filter = require('./filter');
var Protocol = require('../protocol'); var Protocol = require('../protocol');
@ -17,8 +19,8 @@ function EqualityFilter(options) {
throw new TypeError('options.attribute (string) required'); throw new TypeError('options.attribute (string) required');
if (!options.value || typeof (options.value) !== 'string') if (!options.value || typeof (options.value) !== 'string')
throw new TypeError('options.value (string) required'); throw new TypeError('options.value (string) required');
this.attribute = options.attribute; this.attribute = escape(options.attribute);
this.value = options.value; this.value = escape(options.value);
} else { } else {
options = {}; options = {};
} }

43
lib/filters/escape.js Normal file
View File

@ -0,0 +1,43 @@
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
/**
* RFC 2254 Escaping of filter strings
*
* Raw Escaped
* (o=Parens (R Us)) (o=Parens \28R Us\29)
* (cn=star*) (cn=star\2A)
* (filename=C:\MyFile) (filename=C:\5cMyFile)
*
* Use substr_filter to avoid having * ecsaped.
*/
exports.escape = function (inp) {
if (typeof inp === 'string') {
var esc = "";
for (var i=0; i < inp.length; i++) {
switch (inp[i]) {
case '*':
esc += "\\2a";
break;
case '(':
esc += "\\28";
break;
case ')':
esc += "\\29";
break;
case '\\':
esc += "\\5c";
break;
case '\0':
esc += "\\00";
break;
default:
esc += inp[i];
break;
}
}
return esc;
} else {
return inp;
}
};

View File

@ -3,6 +3,8 @@
var assert = require('assert'); var assert = require('assert');
var util = require('util'); var util = require('util');
var escape = require('./escape').escape;
var Filter = require('./filter'); var Filter = require('./filter');
var Protocol = require('../protocol'); var Protocol = require('../protocol');
@ -17,8 +19,8 @@ function GreaterThanEqualsFilter(options) {
throw new TypeError('options.attribute (string) required'); throw new TypeError('options.attribute (string) required');
if (!options.value || typeof (options.value) !== 'string') if (!options.value || typeof (options.value) !== 'string')
throw new TypeError('options.value (string) required'); throw new TypeError('options.value (string) required');
this.attribute = options.attribute; this.attribute = escape(options.attribute);
this.value = options.value; this.value = escape(options.value);
} else { } else {
options = {}; options = {};
} }

View File

@ -3,6 +3,8 @@
var assert = require('assert'); var assert = require('assert');
var util = require('util'); var util = require('util');
var escape = require('./escape').escape;
var Filter = require('./filter'); var Filter = require('./filter');
var Protocol = require('../protocol'); var Protocol = require('../protocol');
@ -17,8 +19,8 @@ function LessThanEqualsFilter(options) {
throw new TypeError('options.attribute (string) required'); throw new TypeError('options.attribute (string) required');
if (!options.value || typeof (options.value) !== 'string') if (!options.value || typeof (options.value) !== 'string')
throw new TypeError('options.value (string) required'); throw new TypeError('options.value (string) required');
this.attribute = options.attribute; this.attribute = escape(options.attribute);
this.value = options.value; this.value = escape(options.value);
} else { } else {
options = {}; options = {};
} }

View File

@ -3,6 +3,8 @@
var assert = require('assert'); var assert = require('assert');
var util = require('util'); var util = require('util');
var escape = require('./escape').escape;
var Filter = require('./filter'); var Filter = require('./filter');
var Protocol = require('../protocol'); var Protocol = require('../protocol');
@ -14,7 +16,7 @@ function PresenceFilter(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');
this.attribute = options.attribute; this.attribute = escape(options.attribute);
} else { } else {
options = {}; options = {};
} }

View File

@ -3,6 +3,8 @@
var assert = require('assert'); var assert = require('assert');
var util = require('util'); var util = require('util');
var escape = require('./escape').escape;
var Filter = require('./filter'); var Filter = require('./filter');
var Protocol = require('../protocol'); var Protocol = require('../protocol');
@ -15,8 +17,8 @@ function SubstringFilter(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');
this.attribute = options.attribute; this.attribute = escape(options.attribute);
this.initial = options.initial || null; this.initial = options.initial ? escape(options.initial) : null;
this.any = options.any ? options.any.slice(0) : []; this.any = options.any ? options.any.slice(0) : [];
this['final'] = options['final'] || null; this['final'] = options['final'] || null;
} else { } else {

View File

@ -91,6 +91,17 @@ test('parse ok', function (t) {
t.end(); t.end();
}); });
test('escape EqualityFilter inputs', function (t) {
var f = new EqualityFilter({
attribute: '(|(foo',
value: 'bar))('
});
t.equal(f.attribute, '\\28|\\28foo');
t.equal(f.value, 'bar\\29\\29\\28');
t.end();
});
test('parse bad', function (t) { test('parse bad', function (t) {
var writer = new BerWriter(); var writer = new BerWriter();

View File

@ -36,17 +36,36 @@ test('( in filter', function (t) {
var f = parse(str); var f = parse(str);
t.ok(f); t.ok(f);
t.equal(f.attribute, 'foo'); t.equal(f.attribute, 'foo');
t.equal(f.value, 'bar('); t.equal(f.value, 'bar\\28');
t.end(); t.end();
}); });
test(') in filter', function (t) { test(') in filter', function (t) {
var str = '(foo=bar\\))'; var str = '(foo=bar\\))';
var f = parse(str); var f = parse(str);
t.ok(f); t.ok(f);
t.equal(f.attribute, 'foo'); t.equal(f.attribute, 'foo');
t.equal(f.value, 'bar)'); t.equal(f.value, 'bar\\29');
t.end();
});
test('( in filter', function (t) {
var str = 'foo(bar=baz\\()';
var f = parse(str);
t.ok(f);
t.equal(f.attribute, 'foo\\28bar');
t.equal(f.value, 'baz\\28\\29');
t.end();
});
test('( in filter', function (t) {
var str = 'foo)(&(bar=baz)(';
var f = parse(str);
t.ok(f);
t.equal(f.attribute, 'foo\\29\\28&\\28bar');
t.equal(f.value, 'baz\\29\\28');
t.end(); t.end();
}); });
@ -56,7 +75,7 @@ test('\\ in filter', function (t) {
var f = parse(str); var f = parse(str);
t.ok(f); t.ok(f);
t.equal(f.attribute, 'foo'); t.equal(f.attribute, 'foo');
t.equal(f.value, 'bar\\'); t.equal(f.value, 'bar\\5c');
t.end(); t.end();
}); });
@ -66,7 +85,7 @@ test('* in equality filter', function (t) {
var f = parse(str); var f = parse(str);
t.ok(f); t.ok(f);
t.equal(f.attribute, 'foo'); t.equal(f.attribute, 'foo');
t.equal(f.value, 'bar*'); t.equal(f.value, 'bar\\2a');
t.end(); t.end();
}); });