Skip to content

Commit 4c24cf2

Browse files
author
Rory OConnell
committed
Import fixes from kschiess
1 parent d37c3b3 commit 4c24cf2

File tree

6 files changed

+246
-245
lines changed

6 files changed

+246
-245
lines changed

Rakefile

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@ require 'hoe'
77
$LOAD_PATH.unshift( "#{File.dirname(__FILE__)}/lib" )
88

99
# Pull in local 'net/ldap' as opposed to an installed version.
10-
require 'net/ldap'
10+
require 'net'
1111

12-
Hoe.new('net-ldap', Net::LDAP::VERSION) do |p|
13-
p.rubyforge_name = 'net-ldap'
14-
p.developer('Francis Cianfrocca', 'garbagecat10@gmail.com')
15-
p.developer('Emiel van de Laar', 'gemiel@gmail.com')
12+
Hoe.spec "net-ldap" do
13+
developer 'Francis Cianfrocca', 'garbagecat10@gmail.com'
14+
developer 'Emiel van de Laar', 'gemiel@gmail.com'
15+
developer "Rory O'Connell", 'rory.ocon@gmail.com'
1616
end
1717

18+
# Hoe.new('net-ldap', Net::LDAP::VERSION) do |p|
19+
# p.rubyforge_name = 'net-ldap'
20+
# p.developer('Francis Cianfrocca', 'garbagecat10@gmail.com')
21+
# p.developer('Emiel van de Laar', 'gemiel@gmail.com')
22+
# end
23+
1824
# vim: syntax=Ruby

lib/net/ber/ber_parser.rb

Lines changed: 139 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -40,100 +40,97 @@ module BERParser
4040
# of this one.
4141
#
4242
def read_ber syntax=nil
43-
# don't bother with this line, since IO#getc by definition returns nil on eof.
44-
#return nil if eof?
43+
# don't bother with this line, since IO#getc by definition returns nil on eof.
44+
#return nil if eof?
4545

46-
# here we'll create two different procs, one for 1.8 and one for 1.9
47-
# the reason being getc doesn't return a byte value in 1.9, so we need to
48-
# get the byte code out of the 1.9 encoded string
46+
# here we'll create two different procs, one for 1.8 and one for 1.9
47+
# the reason being getc doesn't return a byte value in 1.9, so we need to
48+
# get the byte code out of the 1.9 encoded string
4949

50-
if RUBY_VERSION =~ /^1\.9/
51-
fetch_byte = Proc.new { getc.bytes.first }
50+
if RUBY_VERSION =~ /^1\.9/
51+
fetch_byte = Proc.new { getc.bytes.first }
5252
elsif RUBY_VERSION =~ /^1\.8/
53-
fetch_byte = Proc.new { getc }
54-
end
55-
56-
id = fetch_byte.call or return nil # don't trash this value, we'll use it later
57-
#tag = id & 31
58-
#tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" )
59-
#tagclass = TagClasses[ id >> 6 ]
60-
#encoding = (id & 0x20 != 0) ? :constructed : :primitive
61-
62-
n = fetch_byte.call
63-
lengthlength,contentlength = if n <= 127
64-
[1,n]
65-
else
66-
# Replaced the inject because it profiles hot.
67-
#j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc}
68-
j = 0
69-
read( n & 127 ).each_byte {|n1| j = (j << 8) + n1}
70-
[1 + (n & 127), j]
71-
end
72-
73-
newobj = read contentlength
53+
fetch_byte = Proc.new { getc }
54+
end
7455

75-
# This exceptionally clever and clear bit of code is verrrry slow.
76-
objtype = (syntax && syntax[id]) || BuiltinSyntax[id]
56+
id = fetch_byte.call or return nil # don't trash this value, we'll use it later
57+
#tag = id & 31
58+
#tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" )
59+
#tagclass = TagClasses[ id >> 6 ]
60+
#encoding = (id & 0x20 != 0) ? :constructed : :primitive
7761

62+
n = fetch_byte.call
63+
lengthlength,contentlength = if n <= 127
64+
[1,n]
65+
else
66+
# Replaced the inject because it profiles hot.
67+
#j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc}
68+
j = 0
69+
read( n & 127 ).each_byte {|n1| j = (j << 8) + n1}
70+
[1 + (n & 127), j]
71+
end
7872

79-
# == is expensive so sort this if/else so the common cases are at the top.
80-
obj = if objtype == :string
81-
#(newobj || "").dup
82-
s = BerIdentifiedString.new( newobj || "" )
83-
s.ber_identifier = id
84-
s
85-
elsif objtype == :integer
86-
j = 0
87-
newobj.each_byte {|b| j = (j << 8) + b}
88-
j
89-
elsif objtype == :oid
90-
# cf X.690 pgh 8.19 for an explanation of this algorithm.
91-
# Potentially not good enough. We may need a BerIdentifiedOid
92-
# as a subclass of BerIdentifiedArray, to get the ber identifier
93-
# and also a to_s method that produces the familiar dotted notation.
94-
oid = newobj.unpack("w*")
95-
f = oid.shift
96-
g = if f < 40
73+
newobj = read contentlength
74+
75+
# This exceptionally clever and clear bit of code is verrrry slow.
76+
objtype = (syntax && syntax[id]) || BuiltinSyntax[id]
77+
78+
# == is expensive so sort this if/else so the common cases are at the top.
79+
obj = if objtype == :string
80+
#(newobj || "").dup
81+
s = BerIdentifiedString.new( newobj || "" )
82+
s.ber_identifier = id
83+
s
84+
elsif objtype == :integer
85+
j = 0
86+
newobj.each_byte {|b| j = (j << 8) + b}
87+
j
88+
elsif objtype == :oid
89+
# cf X.690 pgh 8.19 for an explanation of this algorithm.
90+
# Potentially not good enough. We may need a BerIdentifiedOid
91+
# as a subclass of BerIdentifiedArray, to get the ber identifier
92+
# and also a to_s method that produces the familiar dotted notation.
93+
oid = newobj.unpack("w*")
94+
f = oid.shift
95+
g = if f < 40
9796
[0, f]
98-
elsif f < 80
97+
elsif f < 80
9998
[1, f-40]
100-
else
99+
else
101100
[2, f-80] # f-80 can easily be > 80. What a weird optimization.
101+
end
102+
oid.unshift g.last
103+
oid.unshift g.first
104+
oid
105+
elsif objtype == :array
106+
#seq = []
107+
seq = BerIdentifiedArray.new
108+
seq.ber_identifier = id
109+
sio = StringIO.new( newobj || "" )
110+
# Interpret the subobject, but note how the loop
111+
# is built: nil ends the loop, but false (a valid
112+
# BER value) does not!
113+
while (e = sio.read_ber(syntax)) != nil
114+
seq << e
115+
end
116+
seq
117+
elsif objtype == :boolean
118+
newobj != "\000"
119+
elsif objtype == :null
120+
n = BerIdentifiedNull.new
121+
n.ber_identifier = id
122+
n
123+
else
124+
#raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
125+
raise BerError.new( "unsupported object type: id=#{id}" )
102126
end
103-
oid.unshift g.last
104-
oid.unshift g.first
105-
oid
106-
elsif objtype == :array
107-
#seq = []
108-
seq = BerIdentifiedArray.new
109-
seq.ber_identifier = id
110-
sio = StringIO.new( newobj || "" )
111-
# Interpret the subobject, but note how the loop
112-
# is built: nil ends the loop, but false (a valid
113-
# BER value) does not!
114-
while (e = sio.read_ber(syntax)) != nil
115-
seq << e
116-
end
117-
seq
118-
elsif objtype == :boolean
119-
newobj != "\000"
120-
elsif objtype == :null
121-
n = BerIdentifiedNull.new
122-
n.ber_identifier = id
123-
n
124-
else
125-
#raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
126-
raise BerError.new( "unsupported object type: id=#{id}" )
127-
end
128-
129-
# Add the identifier bits into the object if it's a String or an Array.
130-
# We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway.
131-
# Replaced this mechanism with subclasses because the instance_eval profiled too hot.
132-
#obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end"
133-
#obj.ber_identifier = id if obj.respond_to?(:ber_identifier)
134-
obj
135-
136-
end
127+
# Add the identifier bits into the object if it's a String or an Array.
128+
# We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway.
129+
# Replaced this mechanism with subclasses because the instance_eval profiled too hot.
130+
#obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end"
131+
#obj.ber_identifier = id if obj.respond_to?(:ber_identifier)
132+
obj
133+
end
137134

138135
#--
139136
# Violates DRY! This replicates the functionality of #read_ber.
@@ -145,77 +142,77 @@ def read_ber syntax=nil
145142
#
146143
# Observe that weirdly we recursively call the original #read_ber in here.
147144
# That needs to be fixed if we ever obsolete the original method in favor of this one.
148-
def read_ber_from_string str, syntax=nil
149-
id = str[0] or return nil
150-
n = str[1] or return nil
151-
n_consumed = 2
152-
lengthlength,contentlength = if n <= 127
153-
[1,n]
154-
else
155-
n1 = n & 127
156-
return nil unless str.length >= (n_consumed + n1)
157-
j = 0
158-
n1.times {
159-
j = (j << 8) + str[n_consumed]
160-
n_consumed += 1
161-
}
162-
[1 + (n1), j]
163-
end
164-
165-
return nil unless str.length >= (n_consumed + contentlength)
145+
def read_ber_from_string str, syntax=nil
146+
id = str[0].ord or return nil
147+
n = str[1].ord or return nil
148+
n_consumed = 2
149+
lengthlength,contentlength = if n <= 127
150+
[1,n]
151+
else
152+
n1 = n & 127
153+
return nil unless str.length >= (n_consumed + n1)
154+
j = 0
155+
n1.times {
156+
j = (j << 8) + str[n_consumed]
157+
n_consumed += 1
158+
}
159+
[1 + (n1), j]
160+
end
161+
162+
return nil unless str.length >= (n_consumed + contentlength)
166163
newobj = str[n_consumed...(n_consumed + contentlength)]
167164
n_consumed += contentlength
168165

169166
objtype = (syntax && syntax[id]) || BuiltinSyntax[id]
170167

171168
# == is expensive so sort this if/else so the common cases are at the top.
172169
obj = if objtype == :array
173-
seq = BerIdentifiedArray.new
174-
seq.ber_identifier = id
175-
sio = StringIO.new( newobj || "" )
176-
# Interpret the subobject, but note how the loop
177-
# is built: nil ends the loop, but false (a valid
178-
# BER value) does not!
179-
# Also, we can use the standard read_ber method because
180-
# we know for sure we have enough data. (Although this
181-
# might be faster than the standard method.)
182-
while (e = sio.read_ber(syntax)) != nil
183-
seq << e
184-
end
185-
seq
170+
seq = BerIdentifiedArray.new
171+
seq.ber_identifier = id
172+
sio = StringIO.new( newobj || "" )
173+
# Interpret the subobject, but note how the loop
174+
# is built: nil ends the loop, but false (a valid
175+
# BER value) does not!
176+
# Also, we can use the standard read_ber method because
177+
# we know for sure we have enough data. (Although this
178+
# might be faster than the standard method.)
179+
while (e = sio.read_ber(syntax)) != nil
180+
seq << e
181+
end
182+
seq
186183
elsif objtype == :string
187-
s = BerIdentifiedString.new( newobj || "" )
188-
s.ber_identifier = id
189-
s
184+
s = BerIdentifiedString.new( newobj || "" )
185+
s.ber_identifier = id
186+
s
190187
elsif objtype == :integer
191-
j = 0
192-
newobj.each_byte {|b| j = (j << 8) + b}
193-
j
188+
j = 0
189+
newobj.each_byte {|b| j = (j << 8) + b}
190+
j
194191
elsif objtype == :oid
195-
# cf X.690 pgh 8.19 for an explanation of this algorithm.
196-
# Potentially not good enough. We may need a BerIdentifiedOid
197-
# as a subclass of BerIdentifiedArray, to get the ber identifier
198-
# and also a to_s method that produces the familiar dotted notation.
199-
oid = newobj.unpack("w*")
200-
f = oid.shift
201-
g = if f < 40
202-
[0,f]
203-
elsif f < 80
204-
[1, f-40]
205-
else
206-
[2, f-80] # f-80 can easily be > 80. What a weird optimization.
207-
end
208-
oid.unshift g.last
209-
oid.unshift g.first
210-
oid
192+
# cf X.690 pgh 8.19 for an explanation of this algorithm.
193+
# Potentially not good enough. We may need a BerIdentifiedOid
194+
# as a subclass of BerIdentifiedArray, to get the ber identifier
195+
# and also a to_s method that produces the familiar dotted notation.
196+
oid = newobj.unpack("w*")
197+
f = oid.shift
198+
g = if f < 40
199+
[0,f]
200+
elsif f < 80
201+
[1, f-40]
202+
else
203+
[2, f-80] # f-80 can easily be > 80. What a weird optimization.
204+
end
205+
oid.unshift g.last
206+
oid.unshift g.first
207+
oid
211208
elsif objtype == :boolean
212-
newobj != "\000"
209+
newobj != "\000"
213210
elsif objtype == :null
214-
n = BerIdentifiedNull.new
215-
n.ber_identifier = id
216-
n
211+
n = BerIdentifiedNull.new
212+
n.ber_identifier = id
213+
n
217214
else
218-
raise BerError.new( "unsupported object type: id=#{id}" )
215+
raise BerError.new( "unsupported object type: id=#{id}" )
219216
end
220217

221218
[obj, n_consumed]

0 commit comments

Comments
 (0)