From f4444c2154722cd731fa2b59bfed223c7dd3a2c0 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Thu, 1 Dec 2016 12:20:56 -0500 Subject: [PATCH 1/2] Ignore unescaped leading/trailing spaces in RDN type/value --- dn.go | 29 ++++++++++++++++++++++++----- dn_test.go | 23 +++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/dn.go b/dn.go index cc70c894..5e7ab6da 100644 --- a/dn.go +++ b/dn.go @@ -83,9 +83,19 @@ func ParseDN(str string) (*DN, error) { attribute := new(AttributeTypeAndValue) escaping := false + unescapedTrailingSpaces := 0 + stringFromBuffer := func() string { + s := buffer.String() + s = s[0 : len(s)-unescapedTrailingSpaces] + buffer.Reset() + unescapedTrailingSpaces = 0 + return s + } + for i := 0; i < len(str); i++ { char := str[i] if escaping { + unescapedTrailingSpaces = 0 escaping = false switch char { case ' ', '"', '#', '+', ',', ';', '<', '=', '>', '\\': @@ -107,10 +117,10 @@ func ParseDN(str string) (*DN, error) { buffer.WriteByte(dst[0]) i++ } else if char == '\\' { + unescapedTrailingSpaces = 0 escaping = true } else if char == '=' { - attribute.Type = buffer.String() - buffer.Reset() + attribute.Type = stringFromBuffer() // Special case: If the first character in the value is # the // following data is BER encoded so we can just fast forward // and decode. @@ -133,7 +143,7 @@ func ParseDN(str string) (*DN, error) { } } else if char == ',' || char == '+' { // We're done with this RDN or value, push it - attribute.Value = buffer.String() + attribute.Value = stringFromBuffer() rdn.Attributes = append(rdn.Attributes, attribute) attribute = new(AttributeTypeAndValue) if char == ',' { @@ -141,8 +151,17 @@ func ParseDN(str string) (*DN, error) { rdn = new(RelativeDN) rdn.Attributes = make([]*AttributeTypeAndValue, 0) } - buffer.Reset() + } else if char == ' ' && buffer.Len() == 0 { + // ignore unescaped leading spaces + continue } else { + if char == ' ' { + // Track unescaped spaces in case they are trailing and we need to remove them + unescapedTrailingSpaces++ + } else { + // Reset if we see a non-space char + unescapedTrailingSpaces = 0 + } buffer.WriteByte(char) } } @@ -150,7 +169,7 @@ func ParseDN(str string) (*DN, error) { if len(attribute.Type) == 0 { return nil, errors.New("DN ended with incomplete type, value pair") } - attribute.Value = buffer.String() + attribute.Value = stringFromBuffer() rdn.Attributes = append(rdn.Attributes, attribute) dn.RDNs = append(dn.RDNs, rdn) } diff --git a/dn_test.go b/dn_test.go index 39817c42..c78180a3 100644 --- a/dn_test.go +++ b/dn_test.go @@ -31,6 +31,22 @@ func TestSuccessfulDNParsing(t *testing.T) { &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"DC", "net"}}}}}, "CN=Lu\\C4\\8Di\\C4\\87": ldap.DN{[]*ldap.RelativeDN{ &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"CN", "Lučić"}}}}}, + " CN = Lu\\C4\\8Di\\C4\\87 ": ldap.DN{[]*ldap.RelativeDN{ + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"CN", "Lučić"}}}}}, + ` A = 1 , B = 2 `: ldap.DN{[]*ldap.RelativeDN{ + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"A", "1"}}}, + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{"B", "2"}}}}}, + ` A = 1 + B = 2 `: ldap.DN{[]*ldap.RelativeDN{ + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{ + &ldap.AttributeTypeAndValue{"A", "1"}, + &ldap.AttributeTypeAndValue{"B", "2"}}}}}, + ` \ \ A\ \ = \ \ 1\ \ , \ \ B\ \ = \ \ 2\ \ `: ldap.DN{[]*ldap.RelativeDN{ + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{" A ", " 1 "}}}, + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{&ldap.AttributeTypeAndValue{" B ", " 2 "}}}}}, + ` \ \ A\ \ = \ \ 1\ \ + \ \ B\ \ = \ \ 2\ \ `: ldap.DN{[]*ldap.RelativeDN{ + &ldap.RelativeDN{[]*ldap.AttributeTypeAndValue{ + &ldap.AttributeTypeAndValue{" A ", " 1 "}, + &ldap.AttributeTypeAndValue{" B ", " 2 "}}}}}, } for test, answer := range testcases { @@ -41,6 +57,13 @@ func TestSuccessfulDNParsing(t *testing.T) { } if !reflect.DeepEqual(dn, &answer) { t.Errorf("Parsed DN %s is not equal to the expected structure", test) + t.Logf("Expected:") + for _, rdn := range answer.RDNs { + for _, attribs := range rdn.Attributes { + t.Logf("#%v\n", attribs) + } + } + t.Logf("Actual:") for _, rdn := range dn.RDNs { for _, attribs := range rdn.Attributes { t.Logf("#%v\n", attribs) From 682bd534ad49a1befbd86849debee41de7f01b82 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Thu, 1 Dec 2016 12:33:27 -0500 Subject: [PATCH 2/2] Limit vet/lint checks to 1.6+ --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b672bc02..e32a2aa7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ language: go env: global: - - VET_VERSIONS="1.5 1.6 1.7 tip" - - LINT_VERSIONS="1.5 1.6 1.7 tip" + - VET_VERSIONS="1.6 1.7 tip" + - LINT_VERSIONS="1.6 1.7 tip" go: - 1.2 - 1.3