Subject: | BUG in Net::LDAP::FilterMatch affecting substrings matches. |
This is a one line fix for Net::LDAP::FilterMatch.
Using the SYNOPSIS code from Net::LDAP::FilterMatch, the results for the
ldap entry:
dn: cn=dummy entry
cn: dummy entry
street: 1 some road
street: nowhere
Are :
(cn=dummy*) : no match
(ou=*) : no match
(&(cn=dummy*)(street=*road)) : no match
(&(cn=dummy*)(!(street=nowhere))) : no match
They should be:
(cn=dummy*) : match
(ou=*) : no match
(&(cn=dummy*)(street=*road)) : match
(&(cn=dummy*)(!(street=nowhere))) : no match
I tracked this down to Net::LDAP::FilterMatch::_cis_substrings. This
line:
return grep(/\Q$regex\E/i, @_) ? 1 : 0;
Should be:
return grep(/$regex/i, @_) ? 1 : 0;
The reason the quoting isn't needed, is because it's already done in
_filterMatch() on the line:
$assertion = join('.*', map { "\Q$_\E" } map { values %$_ }
@{$args->{'substrings'}});
If that is then escaped with \Q\E again, then the ".*" will get regex
escaped, and breaks.
This change may affect the following lines:
*_caseIgnoreIA5SubstringsMatch = \&_cis_substrings;
*_caseIgnoreSubstringsMatch = \&_cis_substrings;
I'm didn't dig into those, but they may need a separate subroutine doing
what the old one did.
Attached is a slightly more thorough example script.
I also noticed there is no test script for this module in the
distribution. If one would be accepted, please let me know and I'll put
one together.
Subject: | test_ldap_filtermatch.pl |
#!/usr/bin/perl
use strict;
use IO::Scalar;
use Net::LDAP::LDIF;
use Net::LDAP::Entry;
use Net::LDAP::Filter;
use Net::LDAP::FilterMatch;
my $entry = new Net::LDAP::Entry;
$entry->dn("cn=dummy entry");
$entry->add (
'cn' => 'dummy entry',
'street' => [ '1 some road','nowhere' ] );
print "ENTRY:\n";
$entry->dump();
print "".("-"x72)."\n";
print "MATCHES:\n";
my @filters = (qw/(cn=dummy*)
(cn=*)
(cn=dummy)
(cn=d*)
(ou=*)
(&(cn=dummy)(street=nowhere))
(|(cn=wrong)(street=nowhere))
(|(cn=dummy)(street=wrong))
(&(cn=dummy*)(street=*road))
(&(cn=dummy*)(!(street=nowhere)))/);
# XML::Sax::Writer ??
for (@filters) {
my $filter = Net::LDAP::Filter->new($_);
print $_,' : ', $filter->match($entry) ? 'match' : 'no match' ,"\n";
}