Skip to content

Commit 64b5181

Browse files
committed
undo unnessary changes
Signed-off-by: Tim Ramlot <[email protected]>
1 parent 2bc9b15 commit 64b5181

File tree

4 files changed

+68
-72
lines changed

4 files changed

+68
-72
lines changed

dn.go

+9-30
Original file line numberDiff line numberDiff line change
@@ -71,29 +71,12 @@ type RelativeDN struct {
7171
// String returns a normalized string representation of this relative DN which
7272
// is the a join of all attributes (sorted in increasing order) with a "+".
7373
func (r *RelativeDN) String() string {
74-
builder := strings.Builder{}
75-
sortedAttributes := make([]*AttributeTypeAndValue, len(r.Attributes))
76-
copy(sortedAttributes, r.Attributes)
77-
sortAttributes(sortedAttributes)
78-
for i, atv := range sortedAttributes {
79-
builder.WriteString(atv.String())
80-
if i < len(sortedAttributes)-1 {
81-
builder.WriteByte('+')
82-
}
74+
attrs := make([]string, len(r.Attributes))
75+
for i := range r.Attributes {
76+
attrs[i] = r.Attributes[i].String()
8377
}
84-
return builder.String()
85-
}
86-
87-
func sortAttributes(atvs []*AttributeTypeAndValue) {
88-
sort.Slice(atvs, func(i, j int) bool {
89-
ti := foldString(atvs[i].Type)
90-
tj := foldString(atvs[j].Type)
91-
if ti != tj {
92-
return ti < tj
93-
}
94-
95-
return atvs[i].Value < atvs[j].Value
96-
})
78+
sort.Strings(attrs)
79+
return strings.Join(attrs, "+")
9780
}
9881

9982
// DN represents a distinguishedName from https://tools.ietf.org/html/rfc4514
@@ -104,14 +87,11 @@ type DN struct {
10487
// String returns a normalized string representation of this DN which is the
10588
// join of all relative DNs with a ",".
10689
func (d *DN) String() string {
107-
builder := strings.Builder{}
108-
for i, rdn := range d.RDNs {
109-
builder.WriteString(rdn.String())
110-
if i < len(d.RDNs)-1 {
111-
builder.WriteByte(',')
112-
}
90+
rdns := make([]string, len(d.RDNs))
91+
for i := range d.RDNs {
92+
rdns[i] = d.RDNs[i].String()
11393
}
114-
return builder.String()
94+
return strings.Join(rdns, ",")
11595
}
11696

11797
func stripLeadingAndTrailingSpaces(inVal string) string {
@@ -285,7 +265,6 @@ func ParseDN(str string) (*DN, error) {
285265
rdn.Attributes = append(rdn.Attributes, attr)
286266
attr = &AttributeTypeAndValue{}
287267
if end {
288-
sortAttributes(rdn.Attributes)
289268
dn.RDNs = append(dn.RDNs, rdn)
290269
rdn = &RelativeDN{}
291270
}

dn_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ func TestSuccessfulDNParsing(t *testing.T) {
2222
}},
2323
"OU=Sales+CN=J. Smith,DC=example,DC=net": {[]*RelativeDN{
2424
{[]*AttributeTypeAndValue{
25-
{"CN", "J. Smith"},
2625
{"OU", "Sales"},
26+
{"CN", "J. Smith"},
2727
}},
2828
{[]*AttributeTypeAndValue{{"DC", "example"}}},
2929
{[]*AttributeTypeAndValue{{"DC", "net"}}},
@@ -114,7 +114,7 @@ func TestSuccessfulDNParsing(t *testing.T) {
114114
{[]*AttributeTypeAndValue{{"OU", "Foo===Long"}}},
115115
{[]*AttributeTypeAndValue{{"ou", "Ba # rq"}}},
116116
{[]*AttributeTypeAndValue{{"ou", "Baz"}}},
117-
{[]*AttributeTypeAndValue{{"c", "US"}, {"o", "C; orp."}}},
117+
{[]*AttributeTypeAndValue{{"o", "C; orp."}, {"c", "US"}}},
118118
}},
119119
}
120120

v3/dn.go

+23-38
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package ldap
22

33
import (
4-
"bytes"
54
"encoding/asn1"
65
"encoding/hex"
76
"errors"
@@ -72,29 +71,12 @@ type RelativeDN struct {
7271
// String returns a normalized string representation of this relative DN which
7372
// is the a join of all attributes (sorted in increasing order) with a "+".
7473
func (r *RelativeDN) String() string {
75-
builder := strings.Builder{}
76-
sortedAttributes := make([]*AttributeTypeAndValue, len(r.Attributes))
77-
copy(sortedAttributes, r.Attributes)
78-
sortAttributes(sortedAttributes)
79-
for i, atv := range sortedAttributes {
80-
builder.WriteString(atv.String())
81-
if i < len(sortedAttributes)-1 {
82-
builder.WriteByte('+')
83-
}
74+
attrs := make([]string, len(r.Attributes))
75+
for i := range r.Attributes {
76+
attrs[i] = r.Attributes[i].String()
8477
}
85-
return builder.String()
86-
}
87-
88-
func sortAttributes(atvs []*AttributeTypeAndValue) {
89-
sort.Slice(atvs, func(i, j int) bool {
90-
ti := foldString(atvs[i].Type)
91-
tj := foldString(atvs[j].Type)
92-
if ti != tj {
93-
return ti < tj
94-
}
95-
96-
return atvs[i].Value < atvs[j].Value
97-
})
78+
sort.Strings(attrs)
79+
return strings.Join(attrs, "+")
9880
}
9981

10082
// DN represents a distinguishedName from https://tools.ietf.org/html/rfc4514
@@ -105,14 +87,11 @@ type DN struct {
10587
// String returns a normalized string representation of this DN which is the
10688
// join of all relative DNs with a ",".
10789
func (d *DN) String() string {
108-
builder := strings.Builder{}
109-
for i, rdn := range d.RDNs {
110-
builder.WriteString(rdn.String())
111-
if i < len(d.RDNs)-1 {
112-
builder.WriteByte(',')
113-
}
90+
rdns := make([]string, len(d.RDNs))
91+
for i := range d.RDNs {
92+
rdns[i] = d.RDNs[i].String()
11493
}
115-
return builder.String()
94+
return strings.Join(rdns, ",")
11695
}
11796

11897
func stripLeadingAndTrailingSpaces(inVal string) string {
@@ -194,18 +173,21 @@ func decodeString(str string) (string, error) {
194173

195174
// Escape a string according to RFC 4514
196175
func encodeString(value string, isValue bool) string {
197-
encodedBuf := bytes.Buffer{}
176+
builder := strings.Builder{}
198177

199178
escapeChar := func(c byte) {
200-
encodedBuf.WriteByte('\\')
201-
encodedBuf.WriteByte(c)
179+
builder.WriteByte('\\')
180+
builder.WriteByte(c)
202181
}
203182

204183
escapeHex := func(c byte) {
205-
encodedBuf.WriteByte('\\')
206-
encodedBuf.WriteString(hex.EncodeToString([]byte{c}))
184+
builder.WriteByte('\\')
185+
builder.WriteString(hex.EncodeToString([]byte{c}))
207186
}
208187

188+
// Loop through each byte and escape as necessary.
189+
// Runes that take up more than one byte are escaped
190+
// byte by byte (since both bytes are non-ASCII).
209191
for i := 0; i < len(value); i++ {
210192
char := value[i]
211193
if i == 0 && (char == ' ' || char == '#') {
@@ -242,10 +224,10 @@ func encodeString(value string, isValue bool) string {
242224
}
243225

244226
// Any other character does not require escaping.
245-
encodedBuf.WriteByte(char)
227+
builder.WriteByte(char)
246228
}
247229

248-
return encodedBuf.String()
230+
return builder.String()
249231
}
250232

251233
func decodeEncodedString(str string) (string, error) {
@@ -283,13 +265,16 @@ func ParseDN(str string) (*DN, error) {
283265
rdn.Attributes = append(rdn.Attributes, attr)
284266
attr = &AttributeTypeAndValue{}
285267
if end {
286-
sortAttributes(rdn.Attributes)
287268
dn.RDNs = append(dn.RDNs, rdn)
288269
rdn = &RelativeDN{}
289270
}
290271
}
291272
)
292273

274+
// Loop through each character in the string and
275+
// build up the attribute type and value pairs.
276+
// We only check for ascii characters here, which
277+
// allows us to iterate over the string byte by byte.
293278
for i := 0; i < len(str); i++ {
294279
char := str[i]
295280
switch {

v3/dn_test.go

+34-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ func TestSuccessfulDNParsing(t *testing.T) {
2222
}},
2323
"OU=Sales+CN=J. Smith,DC=example,DC=net": {[]*RelativeDN{
2424
{[]*AttributeTypeAndValue{
25-
{"CN", "J. Smith"},
2625
{"OU", "Sales"},
26+
{"CN", "J. Smith"},
2727
}},
2828
{[]*AttributeTypeAndValue{{"DC", "example"}}},
2929
{[]*AttributeTypeAndValue{{"DC", "net"}}},
@@ -114,7 +114,7 @@ func TestSuccessfulDNParsing(t *testing.T) {
114114
{[]*AttributeTypeAndValue{{"OU", "Foo===Long"}}},
115115
{[]*AttributeTypeAndValue{{"ou", "Ba # rq"}}},
116116
{[]*AttributeTypeAndValue{{"ou", "Baz"}}},
117-
{[]*AttributeTypeAndValue{{"c", "US"}, {"o", "C; orp."}}},
117+
{[]*AttributeTypeAndValue{{"o", "C; orp."}, {"c", "US"}}},
118118
}},
119119
}
120120

@@ -384,3 +384,35 @@ func TestRoundTripLiteralSubject(t *testing.T) {
384384
assert.Equal(t, subjOut, newRDNSeq.String())
385385
}
386386
}
387+
388+
func TestDecodeString(t *testing.T) {
389+
successTestcases := map[string]string{
390+
"foo-long.com": "foo-long.com",
391+
"foo-lon❤️\\,g.com": "foo-lon❤️,g.com",
392+
"fo\x00o-long.com": "fo\x00o-long.com",
393+
"fo\\00o-long.com": "fo\x00o-long.com",
394+
}
395+
396+
for encoded, decoded := range successTestcases {
397+
t.Logf("Testing encoded string: %s", encoded)
398+
decodedString, err := decodeString(encoded)
399+
if err != nil {
400+
t.Fatal(err)
401+
}
402+
403+
assert.Equal(t, decoded, decodedString)
404+
}
405+
406+
errorTestcases := map[string]string{
407+
"fo\\": "got corrupted escaped character: 'fo\\'",
408+
"fo\\0": "failed to decode escaped character: encoding/hex: invalid byte: 0",
409+
"fo\\UU️o-long.com": "failed to decode escaped character: encoding/hex: invalid byte: U+0055 'U'",
410+
"fo\\0❤️o-long.com": "failed to decode escaped character: invalid byte: 0❤",
411+
}
412+
413+
for encoded, expectedError := range errorTestcases {
414+
t.Logf("Testing encoded string: %s", encoded)
415+
_, err := decodeString(encoded)
416+
assert.EqualError(t, err, expectedError)
417+
}
418+
}

0 commit comments

Comments
 (0)