escape_dn_value Unicode behaviour #5

Open
wants to merge 9 commits into
from
View
@@ -12,7 +12,7 @@ license ('perl');
abstract ('LDAP client library');
resources homepage => 'http://ldap.perl.org/';
-resources repository => 'http://git.goingon.net/?p=perl-ldap.git;a=summary';
+resources repository => 'https://github.com/gbarr/perl-ldap';
resources MailingList => 'http://lists.cpan.org/showlist.cgi?name=perl-ldap';
resources ListArchive => 'http://perl.markmail.org/search/list:perl-ldap';
View
@@ -31,6 +31,8 @@ the L<Net::LDAP> modules.
=cut
+use Encode qw/ encode decode /;
+
use vars qw($VERSION);
require Exporter;
require Net::LDAP::Constant;
@@ -561,9 +563,11 @@ in scalar mode.
sub escape_dn_value(@)
{
my @values = @_;
-
- map { $_ =~ s/([\\",=+<>#;])/\\$1/og;
- $_ =~ s/([\x00-\x1F])/"\\".unpack("H2",$1)/oge;
+ # We conservatively encode all non-ASCII characters, beyond those explicitly
+ # required by RFC2253, but as performed in the examples in section 5.
+ map { $_=encode('utf-8', $_);
+ $_ =~ s/([\\",=+<>#;])/\\$1/og;
+ $_ =~ s/([^\x20-\x7f])/"\\".uc(unpack("H2",$1))/oge;
$_ =~ s/(^\s+|\s+$)/"\\20" x length($1)/oge; } @values;
return(wantarray ? @values : $values[0]);
@@ -591,7 +595,9 @@ my @values = @_;
map { $_ =~ s/\\([\\",=+<>#;]|[0-9a-fA-F]{2})
/(length($1)==1) ? $1 : pack("H2",$1)
- /ogex; } @values;
+ /ogex;
+ $_ = decode('utf-8', $_);
+ } @values;
return(wantarray ? @values : $values[0]);
}
View
@@ -0,0 +1,27 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More;
+use Net::LDAP::Util qw/ escape_dn_value unescape_dn_value /;
+
+is(escape_dn_value("foo"), "foo", "simple, passthrough test");
+is(unescape_dn_value(escape_dn_value("foo")), "foo", "simple, passthrough test, round trip");
+is(unescape_dn_value("foo"), "foo", "simple, passthrough test, decoding");
+
+is(escape_dn_value("foo,bar"), 'foo\,bar', "with a comma");
+is(unescape_dn_value(escape_dn_value("foo,bar")), 'foo,bar', "with a comma, round trip");
+is(unescape_dn_value('foo\,bar'), 'foo,bar', "with a comma, decoding");
+
+my $latin1 = "caf".chr(0xe9);
+is(escape_dn_value($latin1), 'caf\C3\A9', 'latin1');
+is(unescape_dn_value(escape_dn_value($latin1)), $latin1, 'latin1, round trip');
+is(unescape_dn_value('caf\C3\A9'), $latin1, 'latin1, decoding');
+
+my $bad_unicode = "mieow ".chr(0x1F638);
+is(escape_dn_value($bad_unicode), 'mieow \F0\9F\98\B8', 'bad unicode');
+is(unescape_dn_value(escape_dn_value($bad_unicode)), $bad_unicode, 'bad unicode, round trip');
+is(unescape_dn_value('mieow \F0\9F\98\B8'), $bad_unicode, 'bad unicode, decoding');
+
+done_testing();