Skip to content

Commit

Permalink
undo unnessary changes
Browse files Browse the repository at this point in the history
Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com>
  • Loading branch information
inteon committed Apr 4, 2024
1 parent e2a6a07 commit 2bcde73
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 72 deletions.
39 changes: 9 additions & 30 deletions dn.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,29 +71,12 @@ type RelativeDN struct {
// String returns a normalized string representation of this relative DN which
// is the a join of all attributes (sorted in increasing order) with a "+".
func (r *RelativeDN) String() string {
builder := strings.Builder{}
sortedAttributes := make([]*AttributeTypeAndValue, len(r.Attributes))
copy(sortedAttributes, r.Attributes)
sortAttributes(sortedAttributes)
for i, atv := range sortedAttributes {
builder.WriteString(atv.String())
if i < len(sortedAttributes)-1 {
builder.WriteByte('+')
}
attrs := make([]string, len(r.Attributes))
for i := range r.Attributes {
attrs[i] = r.Attributes[i].String()
}
return builder.String()
}

func sortAttributes(atvs []*AttributeTypeAndValue) {
sort.Slice(atvs, func(i, j int) bool {
ti := foldString(atvs[i].Type)
tj := foldString(atvs[j].Type)
if ti != tj {
return ti < tj
}

return atvs[i].Value < atvs[j].Value
})
sort.Strings(attrs)
return strings.Join(attrs, "+")
}

// DN represents a distinguishedName from https://tools.ietf.org/html/rfc4514
Expand All @@ -104,14 +87,11 @@ type DN struct {
// String returns a normalized string representation of this DN which is the
// join of all relative DNs with a ",".
func (d *DN) String() string {
builder := strings.Builder{}
for i, rdn := range d.RDNs {
builder.WriteString(rdn.String())
if i < len(d.RDNs)-1 {
builder.WriteByte(',')
}
rdns := make([]string, len(d.RDNs))
for i := range d.RDNs {
rdns[i] = d.RDNs[i].String()
}
return builder.String()
return strings.Join(rdns, ",")
}

func stripLeadingAndTrailingSpaces(inVal string) string {
Expand Down Expand Up @@ -285,7 +265,6 @@ func ParseDN(str string) (*DN, error) {
rdn.Attributes = append(rdn.Attributes, attr)
attr = &AttributeTypeAndValue{}
if end {
sortAttributes(rdn.Attributes)
dn.RDNs = append(dn.RDNs, rdn)
rdn = &RelativeDN{}
}
Expand Down
4 changes: 2 additions & 2 deletions dn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ func TestSuccessfulDNParsing(t *testing.T) {
}},
"OU=Sales+CN=J. Smith,DC=example,DC=net": {[]*RelativeDN{
{[]*AttributeTypeAndValue{
{"CN", "J. Smith"},
{"OU", "Sales"},
{"CN", "J. Smith"},
}},
{[]*AttributeTypeAndValue{{"DC", "example"}}},
{[]*AttributeTypeAndValue{{"DC", "net"}}},
Expand Down Expand Up @@ -114,7 +114,7 @@ func TestSuccessfulDNParsing(t *testing.T) {
{[]*AttributeTypeAndValue{{"OU", "Foo===Long"}}},
{[]*AttributeTypeAndValue{{"ou", "Ba # rq"}}},
{[]*AttributeTypeAndValue{{"ou", "Baz"}}},
{[]*AttributeTypeAndValue{{"c", "US"}, {"o", "C; orp."}}},
{[]*AttributeTypeAndValue{{"o", "C; orp."}, {"c", "US"}}},
}},
}

Expand Down
61 changes: 23 additions & 38 deletions v3/dn.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ldap

import (
"bytes"
"encoding/asn1"
"encoding/hex"
"errors"
Expand Down Expand Up @@ -72,29 +71,12 @@ type RelativeDN struct {
// String returns a normalized string representation of this relative DN which
// is the a join of all attributes (sorted in increasing order) with a "+".
func (r *RelativeDN) String() string {
builder := strings.Builder{}
sortedAttributes := make([]*AttributeTypeAndValue, len(r.Attributes))
copy(sortedAttributes, r.Attributes)
sortAttributes(sortedAttributes)
for i, atv := range sortedAttributes {
builder.WriteString(atv.String())
if i < len(sortedAttributes)-1 {
builder.WriteByte('+')
}
attrs := make([]string, len(r.Attributes))
for i := range r.Attributes {
attrs[i] = r.Attributes[i].String()
}
return builder.String()
}

func sortAttributes(atvs []*AttributeTypeAndValue) {
sort.Slice(atvs, func(i, j int) bool {
ti := foldString(atvs[i].Type)
tj := foldString(atvs[j].Type)
if ti != tj {
return ti < tj
}

return atvs[i].Value < atvs[j].Value
})
sort.Strings(attrs)
return strings.Join(attrs, "+")
}

// DN represents a distinguishedName from https://tools.ietf.org/html/rfc4514
Expand All @@ -105,14 +87,11 @@ type DN struct {
// String returns a normalized string representation of this DN which is the
// join of all relative DNs with a ",".
func (d *DN) String() string {
builder := strings.Builder{}
for i, rdn := range d.RDNs {
builder.WriteString(rdn.String())
if i < len(d.RDNs)-1 {
builder.WriteByte(',')
}
rdns := make([]string, len(d.RDNs))
for i := range d.RDNs {
rdns[i] = d.RDNs[i].String()
}
return builder.String()
return strings.Join(rdns, ",")
}

func stripLeadingAndTrailingSpaces(inVal string) string {
Expand Down Expand Up @@ -194,18 +173,21 @@ func decodeString(str string) (string, error) {

// Escape a string according to RFC 4514
func encodeString(value string, isValue bool) string {
encodedBuf := bytes.Buffer{}
builder := strings.Builder{}

escapeChar := func(c byte) {
encodedBuf.WriteByte('\\')
encodedBuf.WriteByte(c)
builder.WriteByte('\\')
builder.WriteByte(c)
}

escapeHex := func(c byte) {
encodedBuf.WriteByte('\\')
encodedBuf.WriteString(hex.EncodeToString([]byte{c}))
builder.WriteByte('\\')
builder.WriteString(hex.EncodeToString([]byte{c}))
}

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

// Any other character does not require escaping.
encodedBuf.WriteByte(char)
builder.WriteByte(char)
}

return encodedBuf.String()
return builder.String()
}

func decodeEncodedString(str string) (string, error) {
Expand Down Expand Up @@ -283,13 +265,16 @@ func ParseDN(str string) (*DN, error) {
rdn.Attributes = append(rdn.Attributes, attr)
attr = &AttributeTypeAndValue{}
if end {
sortAttributes(rdn.Attributes)
dn.RDNs = append(dn.RDNs, rdn)
rdn = &RelativeDN{}
}
}
)

// Loop through each character in the string and
// build up the attribute type and value pairs.
// We only check for ascii characters here, which
// allows us to iterate over the string byte by byte.
for i := 0; i < len(str); i++ {
char := str[i]
switch {
Expand Down
36 changes: 34 additions & 2 deletions v3/dn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ func TestSuccessfulDNParsing(t *testing.T) {
}},
"OU=Sales+CN=J. Smith,DC=example,DC=net": {[]*RelativeDN{
{[]*AttributeTypeAndValue{
{"CN", "J. Smith"},
{"OU", "Sales"},
{"CN", "J. Smith"},
}},
{[]*AttributeTypeAndValue{{"DC", "example"}}},
{[]*AttributeTypeAndValue{{"DC", "net"}}},
Expand Down Expand Up @@ -114,7 +114,7 @@ func TestSuccessfulDNParsing(t *testing.T) {
{[]*AttributeTypeAndValue{{"OU", "Foo===Long"}}},
{[]*AttributeTypeAndValue{{"ou", "Ba # rq"}}},
{[]*AttributeTypeAndValue{{"ou", "Baz"}}},
{[]*AttributeTypeAndValue{{"c", "US"}, {"o", "C; orp."}}},
{[]*AttributeTypeAndValue{{"o", "C; orp."}, {"c", "US"}}},
}},
}

Expand Down Expand Up @@ -384,3 +384,35 @@ func TestRoundTripLiteralSubject(t *testing.T) {
assert.Equal(t, subjOut, newRDNSeq.String())
}
}

func TestDecodeString(t *testing.T) {
successTestcases := map[string]string{
"foo-long.com": "foo-long.com",
"foo-lon❤️\\,g.com": "foo-lon❤️,g.com",
"fo\x00o-long.com": "fo\x00o-long.com",
"fo\\00o-long.com": "fo\x00o-long.com",
}

for encoded, decoded := range successTestcases {
t.Logf("Testing encoded string: %s", encoded)
decodedString, err := decodeString(encoded)
if err != nil {
t.Fatal(err)
}

assert.Equal(t, decoded, decodedString)
}

errorTestcases := map[string]string{
"fo\\": "got corrupted escaped character: 'fo\\'",
"fo\\0": "failed to decode escaped character: encoding/hex: invalid byte: 0",
"fo\\UU️o-long.com": "failed to decode escaped character: encoding/hex: invalid byte: U+0055 'U'",
"fo\\0❤️o-long.com": "failed to decode escaped character: invalid byte: 0❤",
}

for encoded, expectedError := range errorTestcases {
t.Logf("Testing encoded string: %s", encoded)
_, err := decodeString(encoded)
assert.EqualError(t, err, expectedError)
}
}

0 comments on commit 2bcde73

Please sign in to comment.