Support escaping * in filter values

This commit is contained in:
Mark Cavage 2012-01-19 15:12:19 -08:00
parent 512541bfbd
commit 11b3a6655d
3 changed files with 122 additions and 27 deletions

View File

@ -138,40 +138,67 @@ function _buildFilterTree(expr) {
tree.name = expr;
} else {
// pull out lhs and rhs of equality operator
var clean = false;
var splitAry = expr.split(operatorStr);
tree.name = splitAry.shift();
tree.value = splitAry.join(operatorStr);
// substrings and extensible matching fall into the equality bin in the
// substrings fall into the equality bin in the
// switch above so we need more processing here
if (tree.tag === 'equalityMatch') {
if (tree.value.indexOf('*') !== -1) {
tree.tag = 'substrings';
split = tree.value.split('*');
// if the value string doesn't start with a * then theres no initial
// value else split will have an empty string in its first array
// index...
// we need to remove that empty string
if (tree.value.indexOf('*') !== 0) {
tree.initial = split.shift();
} else {
split.shift();
}
//if the value string doesn't end with a * then theres no final value
//also same split stuff as the initial stuff above
if (tree.value.lastIndexOf('*') !== tree.value.length - 1) {
tree['final'] = split.pop();
} else {
split.pop();
}
tree.any = split;
} else if (tree.value.length === 0) {
if (tree.value.length === 0) {
tree.tag = 'present';
} else {
var substrNdx = 0;
var substr = false;
var esc = false;
// Effectively a hand-rolled .shift() to support \* sequences
clean = true;
split = [];
substrNdx = 0;
split[substrNdx] = '';
for (var i = 0; i < tree.value.length; i++) {
var c = tree.value[i];
if (esc) {
split[substrNdx] += c;
esc = false;
} else if (c === '*') {
split[++substrNdx] = '';
} else if (c === '\\') {
esc = true;
} else {
split[substrNdx] += c;
}
}
if (split.length > 1) {
tree.tag = 'substrings';
clean = true;
// if the value string doesn't start with a * then theres no initial
// value else split will have an empty string in its first array
// index...
// we need to remove that empty string
if (tree.value.indexOf('*') !== 0) {
tree.initial = split.shift();
} else {
split.shift();
}
// if the value string doesn't end with a * then theres no final
// value also same split stuff as the initial stuff above
if (tree.value.lastIndexOf('*') !== tree.value.length - 1) {
tree['final'] = split.pop();
} else {
split.pop();
}
tree.any = split;
} else {
tree.value = split[0]; // pick up the cleaned version
}
}
} else if (tree.tag == 'extensibleMatch') {
split = tree.name.split(':');
tree.extensible = {
@ -197,6 +224,24 @@ function _buildFilterTree(expr) {
}
}
}
// Cleanup any escape sequences
if (!clean) {
var val = '';
var esc = false;
for (var i = 0; i < tree.value.length; i++) {
var c = tree.value[i];
if (esc) {
val += c;
esc = false;
} else if (c === '\\') {
esc = true;
} else {
val += c;
}
}
tree.value = val;
}
}
return tree;

View File

@ -29,3 +29,53 @@ test('GH-50 = in filter', function(t) {
'uuid=930896af-bf8c-48d4-885c-6573a94b1853, ou=users, o=smartdc');
t.end();
});
test('( in filter', function(t) {
var str = '(foo=bar\\()';
var f = parse(str);
t.ok(f);
t.equal(f.attribute, 'foo');
t.equal(f.value, 'bar(');
t.end();
});
test(') in filter', function(t) {
var str = '(foo=bar\\))';
var f = parse(str);
t.ok(f);
t.equal(f.attribute, 'foo');
t.equal(f.value, 'bar)');
t.end();
});
test('\\ in filter', function(t) {
var str = '(foo=bar\\\\)';
var f = parse(str);
t.ok(f);
t.equal(f.attribute, 'foo');
t.equal(f.value, 'bar\\');
t.end();
});
test('* in equality filter', function(t) {
var str = '(foo=bar\\*)';
var f = parse(str);
t.ok(f);
t.equal(f.attribute, 'foo');
t.equal(f.value, 'bar*');
t.end();
});
test('* substr filter (prefix)', function(t) {
var str = '(foo=bar*)';
var f = parse(str);
t.ok(f);
t.equal(f.attribute, 'foo');
t.equal(f.initial, 'bar');
t.end();
});

View File

@ -44,7 +44,7 @@ test('Evolution search filter (GH-3)', function(t) {
};
server.search(suffix, function(req, res, next) {
console.log(req.filter.toString());
console.log(req.filter.filters[0].type);
if (req.filter.matches(entry.attributes))
res.send(entry);
res.end();