diff --git a/lib/net/ldap/filter.rb b/lib/net/ldap/filter.rb index f77c5e26..b38b13e9 100644 --- a/lib/net/ldap/filter.rb +++ b/lib/net/ldap/filter.rb @@ -291,11 +291,11 @@ def parse_ber(ber) case b.ber_identifier when 0x80 # context-specific primitive 0, SubstringFilter "initial" raise Net::LDAP::LdapError, "Unrecognized substring filter; bad initial value." if str.length > 0 - str += b + str += escape(b) when 0x81 # context-specific primitive 0, SubstringFilter "any" - str += "*#{b}" + str += "*#{escape(b)}" when 0x82 # context-specific primitive 0, SubstringFilter "final" - str += "*#{b}" + str += "*#{escape(b)}" final = true end } @@ -509,17 +509,17 @@ def to_ber first = nil ary.shift else - first = ary.shift.to_ber_contextspecific(0) + first = unescape(ary.shift).to_ber_contextspecific(0) end if ary.last.empty? last = nil ary.pop else - last = ary.pop.to_ber_contextspecific(2) + last = unescape(ary.pop).to_ber_contextspecific(2) end - seq = ary.map { |e| e.to_ber_contextspecific(1) } + seq = ary.map { |e| unescape(e).to_ber_contextspecific(1) } seq.unshift first if first seq.push last if last diff --git a/spec/unit/ldap/filter_spec.rb b/spec/unit/ldap/filter_spec.rb index 416be31c..5e4cb8a8 100644 --- a/spec/unit/ldap/filter_spec.rb +++ b/spec/unit/ldap/filter_spec.rb @@ -81,4 +81,35 @@ def eq(attribute, value) Net::LDAP::Filter.escape("\0*()\\").should == "\\00\\2A\\28\\29\\5C" end end + + context 'with a well-known BER string' do + ber = "\xa4\x2d" \ + "\x04\x0b" "objectclass" \ + "\x30\x1e" \ + "\x80\x08" "foo" "*\\" "bar" \ + "\x81\x08" "foo" "*\\" "bar" \ + "\x82\x08" "foo" "*\\" "bar" + + describe "<- .to_ber" do + [ + "foo" "\\2A\\5C" "bar", + "foo" "\\2a\\5c" "bar", + "foo" "\\2A\\5c" "bar", + "foo" "\\2a\\5C" "bar" + ].each do |escaped| + it 'unescapes escaped characters' do + filter = Net::LDAP::Filter.eq("objectclass", "#{escaped}*#{escaped}*#{escaped}") + filter.to_ber.should == ber + end + end + end + + describe '<- .parse_ber' do + it 'escapes characters' do + escaped = Net::LDAP::Filter.escape("foo" "*\\" "bar") + filter = Net::LDAP::Filter.parse_ber(ber.read_ber(Net::LDAP::AsnSyntax)) + filter.to_s.should == "(objectclass=#{escaped}*#{escaped}*#{escaped})" + end + end + end end