summaryrefslogtreecommitdiffstats
path: root/filter.go
diff options
context:
space:
mode:
authortmfkams <tmfkams@gmail.com>2014-01-19 23:04:16 +0100
committerSamuel Stauffer <samuel@descolada.com>2014-03-19 21:57:58 +0100
commite45f83457931e08f9f6d5aec48f51fd390a01eb8 (patch)
treed95a79f94932115bf5c0441f2eeb520959bbda0d /filter.go
parentMerge pull request #4 from bollenberger/master (diff)
downloadldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar.gz
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar.bz2
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar.lz
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar.xz
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.tar.zst
ldap-e45f83457931e08f9f6d5aec48f51fd390a01eb8.zip
Diffstat (limited to 'filter.go')
-rw-r--r--filter.go432
1 files changed, 216 insertions, 216 deletions
diff --git a/filter.go b/filter.go
index 1b8fd1e..66c8afe 100644
--- a/filter.go
+++ b/filter.go
@@ -6,244 +6,244 @@
package ldap
import (
+ "errors"
"fmt"
- "os"
- "github.com/mmitton/asn1-ber"
+ "github.com/tmfkams/asn1-ber"
)
const (
- FilterAnd = 0
- FilterOr = 1
- FilterNot = 2
- FilterEqualityMatch = 3
- FilterSubstrings = 4
- FilterGreaterOrEqual = 5
- FilterLessOrEqual = 6
- FilterPresent = 7
- FilterApproxMatch = 8
- FilterExtensibleMatch = 9
+ FilterAnd = 0
+ FilterOr = 1
+ FilterNot = 2
+ FilterEqualityMatch = 3
+ FilterSubstrings = 4
+ FilterGreaterOrEqual = 5
+ FilterLessOrEqual = 6
+ FilterPresent = 7
+ FilterApproxMatch = 8
+ FilterExtensibleMatch = 9
)
-var FilterMap = map[ uint64 ] string {
- FilterAnd : "And",
- FilterOr : "Or",
- FilterNot : "Not",
- FilterEqualityMatch : "Equality Match",
- FilterSubstrings : "Substrings",
- FilterGreaterOrEqual : "Greater Or Equal",
- FilterLessOrEqual : "Less Or Equal",
- FilterPresent : "Present",
- FilterApproxMatch : "Approx Match",
- FilterExtensibleMatch : "Extensible Match",
+var FilterMap = map[uint64]string{
+ FilterAnd: "And",
+ FilterOr: "Or",
+ FilterNot: "Not",
+ FilterEqualityMatch: "Equality Match",
+ FilterSubstrings: "Substrings",
+ FilterGreaterOrEqual: "Greater Or Equal",
+ FilterLessOrEqual: "Less Or Equal",
+ FilterPresent: "Present",
+ FilterApproxMatch: "Approx Match",
+ FilterExtensibleMatch: "Extensible Match",
}
const (
- FilterSubstringsInitial = 0
- FilterSubstringsAny = 1
- FilterSubstringsFinal = 2
+ FilterSubstringsInitial = 0
+ FilterSubstringsAny = 1
+ FilterSubstringsFinal = 2
)
-var FilterSubstringsMap = map[ uint64 ] string {
- FilterSubstringsInitial : "Substrings Initial",
- FilterSubstringsAny : "Substrings Any",
- FilterSubstringsFinal : "Substrings Final",
+var FilterSubstringsMap = map[uint64]string{
+ FilterSubstringsInitial: "Substrings Initial",
+ FilterSubstringsAny: "Substrings Any",
+ FilterSubstringsFinal: "Substrings Final",
}
-func CompileFilter( filter string ) ( *ber.Packet, *Error ) {
- if len( filter ) == 0 || filter[ 0 ] != '(' {
- return nil, NewError( ErrorFilterCompile, os.NewError( "Filter does not start with an '('" ) )
- }
- packet, pos, err := compileFilter( filter, 1 )
- if err != nil {
- return nil, err
- }
- if pos != len( filter ) {
- return nil, NewError( ErrorFilterCompile, os.NewError( "Finished compiling filter with extra at end.\n" + fmt.Sprint( filter[pos:] ) ) )
- }
- return packet, nil
+func CompileFilter(filter string) (*ber.Packet, *Error) {
+ if len(filter) == 0 || filter[0] != '(' {
+ return nil, NewError(ErrorFilterCompile, errors.New("Filter does not start with an '('"))
+ }
+ packet, pos, err := compileFilter(filter, 1)
+ if err != nil {
+ return nil, err
+ }
+ if pos != len(filter) {
+ return nil, NewError(ErrorFilterCompile, errors.New("Finished compiling filter with extra at end.\n"+fmt.Sprint(filter[pos:])))
+ }
+ return packet, nil
}
-func DecompileFilter( packet *ber.Packet ) (ret string, err *Error) {
- defer func() {
- if r := recover(); r != nil {
- err = NewError( ErrorFilterDecompile, os.NewError( "Error decompiling filter" ) )
- }
- }()
- ret = "("
- err = nil
- child_str := ""
+func DecompileFilter(packet *ber.Packet) (ret string, err *Error) {
+ defer func() {
+ if r := recover(); r != nil {
+ err = NewError(ErrorFilterDecompile, errors.New("Error decompiling filter"))
+ }
+ }()
+ ret = "("
+ err = nil
+ child_str := ""
- switch packet.Tag {
- case FilterAnd:
- ret += "&"
- for _, child := range packet.Children {
- child_str, err = DecompileFilter( child )
- if err != nil {
- return
- }
- ret += child_str
- }
- case FilterOr:
- ret += "|"
- for _, child := range packet.Children {
- child_str, err = DecompileFilter( child )
- if err != nil {
- return
- }
- ret += child_str
- }
- case FilterNot:
- ret += "!"
- child_str, err = DecompileFilter( packet.Children[ 0 ] )
- if err != nil {
- return
- }
- ret += child_str
+ switch packet.Tag {
+ case FilterAnd:
+ ret += "&"
+ for _, child := range packet.Children {
+ child_str, err = DecompileFilter(child)
+ if err != nil {
+ return
+ }
+ ret += child_str
+ }
+ case FilterOr:
+ ret += "|"
+ for _, child := range packet.Children {
+ child_str, err = DecompileFilter(child)
+ if err != nil {
+ return
+ }
+ ret += child_str
+ }
+ case FilterNot:
+ ret += "!"
+ child_str, err = DecompileFilter(packet.Children[0])
+ if err != nil {
+ return
+ }
+ ret += child_str
- case FilterSubstrings:
- ret += ber.DecodeString( packet.Children[ 0 ].Data.Bytes() )
- ret += "="
- switch packet.Children[ 1 ].Children[ 0 ].Tag {
- case FilterSubstringsInitial:
- ret += ber.DecodeString( packet.Children[ 1 ].Children[ 0 ].Data.Bytes() ) + "*"
- case FilterSubstringsAny:
- ret += "*" + ber.DecodeString( packet.Children[ 1 ].Children[ 0 ].Data.Bytes() ) + "*"
- case FilterSubstringsFinal:
- ret += "*" + ber.DecodeString( packet.Children[ 1 ].Children[ 0 ].Data.Bytes() )
- }
- case FilterEqualityMatch:
- ret += ber.DecodeString( packet.Children[ 0 ].Data.Bytes() )
- ret += "="
- ret += ber.DecodeString( packet.Children[ 1 ].Data.Bytes() )
- case FilterGreaterOrEqual:
- ret += ber.DecodeString( packet.Children[ 0 ].Data.Bytes() )
- ret += ">="
- ret += ber.DecodeString( packet.Children[ 1 ].Data.Bytes() )
- case FilterLessOrEqual:
- ret += ber.DecodeString( packet.Children[ 0 ].Data.Bytes() )
- ret += "<="
- ret += ber.DecodeString( packet.Children[ 1 ].Data.Bytes() )
- case FilterPresent:
- ret += ber.DecodeString( packet.Children[ 0 ].Data.Bytes() )
- ret += "=*"
- case FilterApproxMatch:
- ret += ber.DecodeString( packet.Children[ 0 ].Data.Bytes() )
- ret += "~="
- ret += ber.DecodeString( packet.Children[ 1 ].Data.Bytes() )
- }
+ case FilterSubstrings:
+ ret += ber.DecodeString(packet.Children[0].Data.Bytes())
+ ret += "="
+ switch packet.Children[1].Children[0].Tag {
+ case FilterSubstringsInitial:
+ ret += ber.DecodeString(packet.Children[1].Children[0].Data.Bytes()) + "*"
+ case FilterSubstringsAny:
+ ret += "*" + ber.DecodeString(packet.Children[1].Children[0].Data.Bytes()) + "*"
+ case FilterSubstringsFinal:
+ ret += "*" + ber.DecodeString(packet.Children[1].Children[0].Data.Bytes())
+ }
+ case FilterEqualityMatch:
+ ret += ber.DecodeString(packet.Children[0].Data.Bytes())
+ ret += "="
+ ret += ber.DecodeString(packet.Children[1].Data.Bytes())
+ case FilterGreaterOrEqual:
+ ret += ber.DecodeString(packet.Children[0].Data.Bytes())
+ ret += ">="
+ ret += ber.DecodeString(packet.Children[1].Data.Bytes())
+ case FilterLessOrEqual:
+ ret += ber.DecodeString(packet.Children[0].Data.Bytes())
+ ret += "<="
+ ret += ber.DecodeString(packet.Children[1].Data.Bytes())
+ case FilterPresent:
+ ret += ber.DecodeString(packet.Children[0].Data.Bytes())
+ ret += "=*"
+ case FilterApproxMatch:
+ ret += ber.DecodeString(packet.Children[0].Data.Bytes())
+ ret += "~="
+ ret += ber.DecodeString(packet.Children[1].Data.Bytes())
+ }
- ret += ")"
- return
+ ret += ")"
+ return
}
-func compileFilterSet( filter string, pos int, parent *ber.Packet ) ( int, *Error ) {
- for pos < len( filter ) && filter[ pos ] == '(' {
- child, new_pos, err := compileFilter( filter, pos + 1 )
- if err != nil {
- return pos, err
- }
- pos = new_pos
- parent.AppendChild( child )
- }
- if pos == len( filter ) {
- return pos, NewError( ErrorFilterCompile, os.NewError( "Unexpected end of filter" ) )
- }
+func compileFilterSet(filter string, pos int, parent *ber.Packet) (int, *Error) {
+ for pos < len(filter) && filter[pos] == '(' {
+ child, new_pos, err := compileFilter(filter, pos+1)
+ if err != nil {
+ return pos, err
+ }
+ pos = new_pos
+ parent.AppendChild(child)
+ }
+ if pos == len(filter) {
+ return pos, NewError(ErrorFilterCompile, errors.New("Unexpected end of filter"))
+ }
- return pos + 1, nil
+ return pos + 1, nil
}
-func compileFilter( filter string, pos int ) ( p *ber.Packet, new_pos int, err *Error ) {
- defer func() {
- if r := recover(); r != nil {
- err = NewError( ErrorFilterCompile, os.NewError( "Error compiling filter" ) )
- }
- }()
- p = nil
- new_pos = pos
- err = nil
+func compileFilter(filter string, pos int) (p *ber.Packet, new_pos int, err *Error) {
+ defer func() {
+ if r := recover(); r != nil {
+ err = NewError(ErrorFilterCompile, errors.New("Error compiling filter"))
+ }
+ }()
+ p = nil
+ new_pos = pos
+ err = nil
- switch filter[pos] {
- case '(':
- p, new_pos, err = compileFilter( filter, pos + 1 )
- new_pos++
- return
- case '&':
- p = ber.Encode( ber.ClassContext, ber.TypeConstructed, FilterAnd, nil, FilterMap[ FilterAnd ] )
- new_pos, err = compileFilterSet( filter, pos + 1, p )
- return
- case '|':
- p = ber.Encode( ber.ClassContext, ber.TypeConstructed, FilterOr, nil, FilterMap[ FilterOr ] )
- new_pos, err = compileFilterSet( filter, pos + 1, p )
- return
- case '!':
- p = ber.Encode( ber.ClassContext, ber.TypeConstructed, FilterNot, nil, FilterMap[ FilterNot ] )
- var child *ber.Packet
- child, new_pos, err = compileFilter( filter, pos + 1 )
- p.AppendChild( child )
- return
- default:
- attribute := ""
- condition := ""
- for new_pos < len( filter ) && filter[ new_pos ] != ')' {
- switch {
- case p != nil:
- condition += fmt.Sprintf( "%c", filter[ new_pos ] )
- case filter[ new_pos ] == '=':
- p = ber.Encode( ber.ClassContext, ber.TypeConstructed, FilterEqualityMatch, nil, FilterMap[ FilterEqualityMatch ] )
- case filter[ new_pos ] == '>' && filter[ new_pos + 1 ] == '=':
- p = ber.Encode( ber.ClassContext, ber.TypeConstructed, FilterGreaterOrEqual, nil, FilterMap[ FilterGreaterOrEqual ] )
- new_pos++
- case filter[ new_pos ] == '<' && filter[ new_pos + 1 ] == '=':
- p = ber.Encode( ber.ClassContext, ber.TypeConstructed, FilterLessOrEqual, nil, FilterMap[ FilterLessOrEqual ] )
- new_pos++
- case filter[ new_pos ] == '~' && filter[ new_pos + 1 ] == '=':
- p = ber.Encode( ber.ClassContext, ber.TypeConstructed, FilterApproxMatch, nil, FilterMap[ FilterLessOrEqual ] )
- new_pos++
- case p == nil:
- attribute += fmt.Sprintf( "%c", filter[ new_pos ] )
- }
- new_pos++
- }
- if new_pos == len( filter ) {
- err = NewError( ErrorFilterCompile, os.NewError( "Unexpected end of filter" ) )
- return
- }
- if p == nil {
- err = NewError( ErrorFilterCompile, os.NewError( "Error parsing filter" ) )
- return
- }
- p.AppendChild( ber.NewString( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, attribute, "Attribute" ) )
- switch {
- case p.Tag == FilterEqualityMatch && condition == "*":
- p.Tag = FilterPresent
- p.Description = FilterMap[ uint64(p.Tag) ]
- case p.Tag == FilterEqualityMatch && condition[ 0 ] == '*' && condition[ len( condition ) - 1 ] == '*':
- // Any
- p.Tag = FilterSubstrings
- p.Description = FilterMap[ uint64(p.Tag) ]
- seq := ber.Encode( ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings" )
- seq.AppendChild( ber.NewString( ber.ClassContext, ber.TypePrimative, FilterSubstringsAny, condition[ 1 : len( condition ) - 1 ], "Any Substring" ) )
- p.AppendChild( seq )
- case p.Tag == FilterEqualityMatch && condition[ 0 ] == '*':
- // Final
- p.Tag = FilterSubstrings
- p.Description = FilterMap[ uint64(p.Tag) ]
- seq := ber.Encode( ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings" )
- seq.AppendChild( ber.NewString( ber.ClassContext, ber.TypePrimative, FilterSubstringsFinal, condition[ 1: ], "Final Substring" ) )
- p.AppendChild( seq )
- case p.Tag == FilterEqualityMatch && condition[ len( condition ) - 1 ] == '*':
- // Initial
- p.Tag = FilterSubstrings
- p.Description = FilterMap[ uint64(p.Tag) ]
- seq := ber.Encode( ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings" )
- seq.AppendChild( ber.NewString( ber.ClassContext, ber.TypePrimative, FilterSubstringsInitial, condition[ :len( condition ) - 1 ], "Initial Substring" ) )
- p.AppendChild( seq )
- default:
- p.AppendChild( ber.NewString( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, condition, "Condition" ) )
- }
- new_pos++
- return
- }
- err = NewError( ErrorFilterCompile, os.NewError( "Reached end of filter without closing parens" ) )
- return
+ switch filter[pos] {
+ case '(':
+ p, new_pos, err = compileFilter(filter, pos+1)
+ new_pos++
+ return
+ case '&':
+ p = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterAnd, nil, FilterMap[FilterAnd])
+ new_pos, err = compileFilterSet(filter, pos+1, p)
+ return
+ case '|':
+ p = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterOr, nil, FilterMap[FilterOr])
+ new_pos, err = compileFilterSet(filter, pos+1, p)
+ return
+ case '!':
+ p = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterNot, nil, FilterMap[FilterNot])
+ var child *ber.Packet
+ child, new_pos, err = compileFilter(filter, pos+1)
+ p.AppendChild(child)
+ return
+ default:
+ attribute := ""
+ condition := ""
+ for new_pos < len(filter) && filter[new_pos] != ')' {
+ switch {
+ case p != nil:
+ condition += fmt.Sprintf("%c", filter[new_pos])
+ case filter[new_pos] == '=':
+ p = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterEqualityMatch, nil, FilterMap[FilterEqualityMatch])
+ case filter[new_pos] == '>' && filter[new_pos+1] == '=':
+ p = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterGreaterOrEqual, nil, FilterMap[FilterGreaterOrEqual])
+ new_pos++
+ case filter[new_pos] == '<' && filter[new_pos+1] == '=':
+ p = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterLessOrEqual, nil, FilterMap[FilterLessOrEqual])
+ new_pos++
+ case filter[new_pos] == '~' && filter[new_pos+1] == '=':
+ p = ber.Encode(ber.ClassContext, ber.TypeConstructed, FilterApproxMatch, nil, FilterMap[FilterLessOrEqual])
+ new_pos++
+ case p == nil:
+ attribute += fmt.Sprintf("%c", filter[new_pos])
+ }
+ new_pos++
+ }
+ if new_pos == len(filter) {
+ err = NewError(ErrorFilterCompile, errors.New("Unexpected end of filter"))
+ return
+ }
+ if p == nil {
+ err = NewError(ErrorFilterCompile, errors.New("Error parsing filter"))
+ return
+ }
+ p.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, attribute, "Attribute"))
+ switch {
+ case p.Tag == FilterEqualityMatch && condition == "*":
+ p.Tag = FilterPresent
+ p.Description = FilterMap[uint64(p.Tag)]
+ case p.Tag == FilterEqualityMatch && condition[0] == '*' && condition[len(condition)-1] == '*':
+ // Any
+ p.Tag = FilterSubstrings
+ p.Description = FilterMap[uint64(p.Tag)]
+ seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings")
+ seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimative, FilterSubstringsAny, condition[1:len(condition)-1], "Any Substring"))
+ p.AppendChild(seq)
+ case p.Tag == FilterEqualityMatch && condition[0] == '*':
+ // Final
+ p.Tag = FilterSubstrings
+ p.Description = FilterMap[uint64(p.Tag)]
+ seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings")
+ seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimative, FilterSubstringsFinal, condition[1:], "Final Substring"))
+ p.AppendChild(seq)
+ case p.Tag == FilterEqualityMatch && condition[len(condition)-1] == '*':
+ // Initial
+ p.Tag = FilterSubstrings
+ p.Description = FilterMap[uint64(p.Tag)]
+ seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Substrings")
+ seq.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimative, FilterSubstringsInitial, condition[:len(condition)-1], "Initial Substring"))
+ p.AppendChild(seq)
+ default:
+ p.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, condition, "Condition"))
+ }
+ new_pos++
+ return
+ }
+ err = NewError(ErrorFilterCompile, errors.New("Reached end of filter without closing parens"))
+ return
}