From 3a8b8a2e00f385e1283ef080dd476d4c6fee998d Mon Sep 17 00:00:00 2001 From: Daniel Abrahamsson Date: Fri, 9 Sep 2011 18:47:39 +0200 Subject: [PATCH] LDAP uses UTF-8 strings --- lib/net/ber.rb | 2 ++ lib/net/ber/core_ext/string.rb | 14 +++++++++++++- spec/unit/ber/ber_spec.rb | 17 ++++++++++++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/net/ber.rb b/lib/net/ber.rb index d65a354..b7608a4 100644 --- a/lib/net/ber.rb +++ b/lib/net/ber.rb @@ -295,6 +295,8 @@ class Net::BER::BerIdentifiedString < String attr_accessor :ber_identifier def initialize args super args + # LDAP uses UTF-8 encoded strings + force_encoding('UTF-8') if respond_to?(:encoding) end end diff --git a/lib/net/ber/core_ext/string.rb b/lib/net/ber/core_ext/string.rb index 3a1b415..28aeedd 100644 --- a/lib/net/ber/core_ext/string.rb +++ b/lib/net/ber/core_ext/string.rb @@ -12,9 +12,21 @@ module Net::BER::Extensions::String # User code should call either #to_ber_application_string or # #to_ber_contextspecific. def to_ber(code = 0x04) - [code].pack('C') + length.to_ber_length_encoding + self + raw_string = raw_utf8_encoded + [code].pack('C') + raw_string.length.to_ber_length_encoding + raw_string end + def raw_utf8_encoded + if self.respond_to?(:encode) + # Strings should be UTF-8 encoded according to LDAP. + # However, the BER code is not necessarily valid UTF-8 + self.encode('UTF-8').force_encoding('ASCII-8BIT') + else + self + end + end + private :raw_utf8_encoded + ## # Creates an application-specific BER string encoded value with the # provided syntax code value. diff --git a/spec/unit/ber/ber_spec.rb b/spec/unit/ber/ber_spec.rb index 33be2fd..86dc48a 100644 --- a/spec/unit/ber/ber_spec.rb +++ b/spec/unit/ber/ber_spec.rb @@ -75,6 +75,21 @@ describe "BER encoding of" do end end end + if "Ruby 1.9".respond_to?(:encoding) + context "strings" do + it "should properly encode UTF-8 strings" do + "\u00e5".force_encoding("UTF-8").to_ber.should == + "\x04\x02\xC3\xA5" + end + it "should properly encode strings encodable as UTF-8" do + "teststring".encode("US-ASCII").to_ber.should == "\x04\nteststring" + end + it "should fail on strings that can not be converted to UTF-8" do + error = Encoding::UndefinedConversionError + lambda {"\x81".to_ber }.should raise_exception(error) + end + end + end end describe "BER decoding of" do @@ -91,4 +106,4 @@ describe "BER decoding of" do [1, [3, "Administrator", "ad_is_bogus"]] end end -end \ No newline at end of file +end