directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From seelm...@apache.org
Subject svn commit: r493859 - in /directory/branches/shared/0.9.5/ldap/src: main/antlr/ main/java/org/apache/directory/shared/ldap/filter/ test/java/org/apache/directory/shared/ldap/aci/ test/java/org/apache/directory/shared/ldap/filter/
Date Sun, 07 Jan 2007 22:05:12 GMT
Author: seelmann
Date: Sun Jan  7 14:05:11 2007
New Revision: 493859

URL: http://svn.apache.org/viewvc?view=rev&rev=493859
Log:
Fix for DIRSERVER-814: Improved filter detection in ACI lexer; Added check for balanced parenthesis into filter parser (parser hangs in an infinite loop)

Modified:
    directory/branches/shared/0.9.5/ldap/src/main/antlr/ACIItem.g
    directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-lexer.g
    directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-value-lexer.g
    directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-value-parser.g
    directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParserImpl.java
    directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/aci/ACIItemParserTest.java
    directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/filter/FilterParserImplTest.java

Modified: directory/branches/shared/0.9.5/ldap/src/main/antlr/ACIItem.g
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/antlr/ACIItem.g?view=diff&rev=493859&r1=493858&r2=493859
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/antlr/ACIItem.g (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/antlr/ACIItem.g Sun Jan  7 14:05:11 2007
@@ -1469,7 +1469,13 @@
       "attributeValue"! ( SP! )+ '{'! ( options { greedy = false; } : . )* '}'!
       { $setType( ATTRIBUTE_VALUE_CANDIDATE ); }
     | ( "rangeOfValues" ( SP! )+ '(' ) =>
-      "rangeOfValues"! ( SP! )+ '(' ( options { greedy = false; } : . )* ')'
+      "rangeOfValues"! ( SP! )+ FILTER
       { $setType( RANGE_OF_VALUES_CANDIDATE ); }
     | ALPHA ( ALPHA | DIGIT | HYPHEN )*
     ;
+
+protected FILTER : '(' ( ( '&' (SP)* (FILTER)+ ) | ( '|' (SP)* (FILTER)+ ) | ( '!' (SP)* FILTER ) | FILTER_VALUE ) ')' (SP)* ;
+
+protected FILTER_VALUE : (options{greedy=true;}: ~( ')' | '(' | '&' | '|' | '!' ) ( ~(')') )* ) ;
+
+    
\ No newline at end of file

Modified: directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-lexer.g
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-lexer.g?view=diff&rev=493859&r1=493858&r2=493859
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-lexer.g (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-lexer.g Sun Jan  7 14:05:11 2007
@@ -49,6 +49,7 @@
 	charVocabulary='\u0001'..'\u0127';
 	exportVocab = FilterLexer;
 	importVocab = FilterValueLexer;
+	defaultErrorHandler=false;
 }
 
 

Modified: directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-value-lexer.g
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-value-lexer.g?view=diff&rev=493859&r1=493858&r2=493859
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-value-lexer.g (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-value-lexer.g Sun Jan  7 14:05:11 2007
@@ -53,6 +53,7 @@
 	// allow any unicode characters
 	charVocabulary='\u0000'..'\uFFFE';
 	exportVocab=FilterValueLexer;
+	defaultErrorHandler=false;
 }
 
 

Modified: directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-value-parser.g
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-value-parser.g?view=diff&rev=493859&r1=493858&r2=493859
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-value-parser.g (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/antlr/filter-value-parser.g Sun Jan  7 14:05:11 2007
@@ -54,6 +54,7 @@
 {
     k = 3;
 	importVocab = FilterValueLexer;
+	defaultErrorHandler=false;
 }
 
 

Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParserImpl.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParserImpl.java?view=diff&rev=493859&r1=493858&r2=493859
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParserImpl.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/filter/FilterParserImpl.java Sun Jan  7 14:05:11 2007
@@ -114,7 +114,25 @@
         {
             filter = StringTools.trimConsecutiveToOne( filter, '*' );
         }
-
+        
+        // check balanced parenthesis
+        int balanced = 0;
+        for(int i=0; i<filter.length(); i++)
+        {
+            if(filter.charAt( i ) == '(')
+            {
+                balanced++;
+            }
+            else if(filter.charAt( i ) == ')')
+            {
+                balanced--;
+            }
+        }
+        if(balanced != 0)
+        {
+            throw new ParseException( "Unbalanced parenthesis", 0 );
+        }
+        
         this.parserPipe.write( filter.getBytes() );
         this.parserPipe.write( '\n' );
         this.parserPipe.flush();

Modified: directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/aci/ACIItemParserTest.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/aci/ACIItemParserTest.java?view=diff&rev=493859&r1=493858&r2=493859
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/aci/ACIItemParserTest.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/aci/ACIItemParserTest.java Sun Jan  7 14:05:11 2007
@@ -63,6 +63,28 @@
         parser = new ACIItemParser( null );
     }
 
+    
+    /**
+     * Tests the parser with a rangeOfValues with a nested filter.
+     */
+    public void testRangeOfValues() throws Exception
+    {
+        String spec = " {  identificationTag  \"id1\" , precedence 114  , authenticationLevel simple  , "
+            + "itemOrUserFirst itemFirst  :{ protectedItems  "
+            + "{ rangeOfValues (&(&(|(|(cn=ccc)(!(cn=ddd))(&(cn=aaa)(cn=bbb)))))) " + "}  , itemPermissions {  } } }";
+
+        parser.parse( spec );
+        
+        
+        spec = " { identificationTag \"id8\", precedence 0, authenticationLevel simple "
+            + ", itemOrUserFirst userFirst: { userClasses { allUsers }, userPermissions { "
+            + " { protectedItems { rangeOfValues (& (cn=test) (sn=test) ) }, grantsAndDenials { grantAdd } }, "
+            + "{ protectedItems { rangeOfValues (| (! (cn=aaa) ) (sn=bbb) ) }, grantsAndDenials { grantAdd } } "
+            + " } } }";
+        
+        parser.parse( spec );
+    }
+
 
     /**
      * Tests the parser with an ACIItem of ItemFirst main component.

Modified: directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/filter/FilterParserImplTest.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/filter/FilterParserImplTest.java?view=diff&rev=493859&r1=493858&r2=493859
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/filter/FilterParserImplTest.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/filter/FilterParserImplTest.java Sun Jan  7 14:05:11 2007
@@ -19,7 +19,6 @@
  */
 package org.apache.directory.shared.ldap.filter;
 
-
 import java.io.IOException;
 import java.text.ParseException;
 
@@ -34,606 +33,583 @@
 
 import junit.framework.TestCase;
 
-
 /**
  * Tests the FilterParserImpl class.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class FilterParserImplTest extends TestCase
-{
-    private FilterParserImpl parser;
-
-
-    protected void setUp() throws Exception
-    {
-        parser = new FilterParserImpl();
-    }
-
-
-    protected void tearDown() throws Exception
-    {
-        parser = null;
-    }
-
-
-    public void testItemFilter() throws IOException, ParseException
-    {
-        SimpleNode node = ( SimpleNode ) parser.parse( "( ou ~= people )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( "people", node.getValue() );
-        assertEquals( AbstractExprNode.APPROXIMATE, node.getAssertionType() );
-    }
-
-
-    public void testAndFilter() throws IOException, ParseException
-    {
-        BranchNode node = ( BranchNode ) parser.parse( "(& ( ou ~= people ) (age>=30) ) " );
-        assertEquals( 2, node.getChildren().size() );
-        assertEquals( AbstractExprNode.AND, node.getOperator() );
-    }
-
-
-    public void testAndFilterOneChildOnly() throws IOException, ParseException
-    {
-        BranchNode node = ( BranchNode ) parser.parse( "(& ( ou ~= people ) ) " );
-        assertEquals( 1, node.getChildren().size() );
-        assertEquals( AbstractExprNode.AND, node.getOperator() );
-    }
-
-
-    public void testOrFilter() throws IOException, ParseException
-    {
-        BranchNode node = ( BranchNode ) parser.parse( "(| ( ou ~= people ) (age>=30) ) " );
-        assertEquals( 2, node.getChildren().size() );
-        assertEquals( AbstractExprNode.OR, node.getOperator() );
-    }
-
-
-    public void testOrFilterOneChildOnly() throws IOException, ParseException
-    {
-        BranchNode node = ( BranchNode ) parser.parse( "(| (age>=30) ) " );
-        assertEquals( 1, node.getChildren().size() );
-        assertEquals( AbstractExprNode.OR, node.getOperator() );
-    }
-
-
-    public void testNotFilter() throws IOException, ParseException
-    {
-        BranchNode node = ( BranchNode ) parser.parse( "( ! (& ( ou ~= people ) (age>=30) ) )" );
-        assertEquals( 1, node.getChildren().size() );
-        assertEquals( AbstractExprNode.NOT, node.getOperator() );
-    }
-
-
-    public void testOptionAndEscapesFilter() throws IOException, ParseException
-    {
-        SimpleNode node = ( SimpleNode ) parser.parse( "( ou;lang-de >= \\23\\42asdl fkajsd )" );
-        assertEquals( "ou;lang-de", node.getAttribute() );
-        assertEquals( "\\23\\42asdl fkajsd", node.getValue() );
-    }
-
-
-    public void testOptionsAndEscapesFilter() throws IOException, ParseException
-    {
-        SimpleNode node = ( SimpleNode ) parser.parse( "( ou;lang-de;version-124 >= \\23\\42asdl fkajsd )" );
-        assertEquals( "ou;lang-de;version-124", node.getAttribute() );
-        assertEquals( "\\23\\42asdl fkajsd", node.getValue() );
-    }
-
-
-    public void testNumericoidOptionsAndEscapesFilter() throws IOException, ParseException
-    {
-        SimpleNode node = ( SimpleNode ) parser.parse( "( 1.3.4.2;lang-de;version-124 >= \\23\\42asdl fkajsd )" );
-        assertEquals( "1.3.4.2;lang-de;version-124", node.getAttribute() );
-        assertEquals( "\\23\\42asdl fkajsd", node.getValue() );
-    }
-
-
-    public void testPresentFilter() throws IOException, ParseException
-    {
-        PresenceNode node = ( PresenceNode ) parser.parse( "( ou =*)" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-
-        node = ( PresenceNode ) parser.parse( "( ou =* )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-
-        node = ( PresenceNode ) parser.parse( "( ou =  * )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-
-        node = ( PresenceNode ) parser.parse( "(  ou = *)" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-
-        node = ( PresenceNode ) parser.parse( "( ou =* ) " );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-
-        node = ( PresenceNode ) parser.parse( "( ou =*)" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-    }
-
-
-    public void testNumericoidPresentFilter() throws IOException, ParseException
-    {
-        PresenceNode node = ( PresenceNode ) parser.parse( "( 1.2.3.4 = * )" );
-        assertEquals( "1.2.3.4", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-
-        node = ( PresenceNode ) parser.parse( "( 1.2.3.4 =  * )" );
-        assertEquals( "1.2.3.4", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-
-        node = ( PresenceNode ) parser.parse( "(  1.2.3.4 = *)" );
-        assertEquals( "1.2.3.4", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-
-        node = ( PresenceNode ) parser.parse( "( 1.2.3.4 =* ) " );
-        assertEquals( "1.2.3.4", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-
-        node = ( PresenceNode ) parser.parse( "( 1.2.3.4 =*)" );
-        assertEquals( "1.2.3.4", node.getAttribute() );
-        assertEquals( AbstractExprNode.PRESENCE, node.getAssertionType() );
-    }
-
-
-    public void testEqualsFilter() throws IOException, ParseException
-    {
-        SimpleNode node = ( SimpleNode ) parser.parse( "( ou = people )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( "people", node.getValue() );
-        assertEquals( AbstractExprNode.EQUALITY, node.getAssertionType() );
-    }
-
-
-    public void testBadEqualsFilter() throws IOException, ParseException
-    {
-        try
-        {
-            parser.parse( "ou = people" );
-            
-            // The parsing should fail
-            fail( "should fail with bad filter" );
-        }
-        catch( ParseException pe )
-        {
-        }
-    }
-
-
-    public void testEqualsWithForwardSlashFilter() throws IOException, ParseException
-    {
-        SimpleNode node = ( SimpleNode ) parser.parse( "( ou = people/in/my/company )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( "people/in/my/company", node.getValue() );
-        assertEquals( AbstractExprNode.EQUALITY, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm1() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser.parse( "( ou :dn :stupidMatch := dummyAssertion\\23\\ac )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( "stupidMatch", node.getMatchingRuleId() );
-        assertTrue( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm1WithNumericOid() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser
-            .parse( "( 1.2.3.4 :dn :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        assertEquals( "1.2.3.4", node.getAttribute() );
-        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( "1.3434.23.2", node.getMatchingRuleId() );
-        assertTrue( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm1NoDnAttr() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser.parse( "( ou :stupidMatch := dummyAssertion\\23\\ac )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( "stupidMatch", node.getMatchingRuleId() );
-        assertFalse( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm1OptionOnRule() throws IOException, ParseException
-    {
-        try
-        {
-            parser.parse( "( ou :stupidMatch;lang-de := dummyAssertion\\23\\ac )" );
-            fail( "we should never get here" );
-        }
-        catch ( IOException e )
-        {
-        }
-        catch ( ParseException e )
-        {
-        }
-    }
-
-
-    public void testExtensibleFilterForm1NoAttrNoMatchingRule() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser.parse( "( ou := dummyAssertion\\23\\ac )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( null, node.getMatchingRuleId() );
-        assertFalse( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm1NoDnAttrWithNumericOidNoAttr() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser.parse( "( 1.2.3.4 :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        assertEquals( "1.2.3.4", node.getAttribute() );
-        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( "1.3434.23.2", node.getMatchingRuleId() );
-        assertFalse( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm2() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser.parse( "( :dn :stupidMatch := dummyAssertion\\23\\ac )" );
-        assertEquals( null, node.getAttribute() );
-        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( "stupidMatch", node.getMatchingRuleId() );
-        assertTrue( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm2OptionOnRule() throws IOException, ParseException
-    {
-        try
-        {
-            parser.parse( "( :dn :stupidMatch;lang-en := dummyAssertion\\23\\ac )" );
-            fail( "we should never get here" );
-        }
-        catch ( IOException e )
-        {
-        }
-        catch ( ParseException e )
-        {
-        }
-    }
-
-
-    public void testExtensibleFilterForm2WithNumericOid() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser.parse( "( :dn :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        assertEquals( null, node.getAttribute() );
-        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( "1.3434.23.2", node.getMatchingRuleId() );
-        assertTrue( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm2NoDnAttr() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser.parse( "( :stupidMatch := dummyAssertion\\23\\ac )" );
-        assertEquals( null, node.getAttribute() );
-        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( "stupidMatch", node.getMatchingRuleId() );
-        assertFalse( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm2NoDnAttrWithNumericOidNoAttr() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser.parse( "( :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        assertEquals( null, node.getAttribute() );
-        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( "1.3434.23.2", node.getMatchingRuleId() );
-        assertFalse( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm3() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser.parse( "( := dummyAssertion )" );
-        assertEquals( null, node.getAttribute() );
-        assertEquals( "dummyAssertion", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( null, node.getMatchingRuleId() );
-        assertFalse( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testExtensibleFilterForm3WithEscapes() throws IOException, ParseException
-    {
-        ExtensibleNode node = ( ExtensibleNode ) parser.parse( "( := dummyAssertion\\23\\ac )" );
-        assertEquals( null, node.getAttribute() );
-        assertEquals( "dummyAssertion\\23\\ac", StringTools.utf8ToString( node.getValue() ) );
-        assertEquals( null, node.getMatchingRuleId() );
-        assertFalse( node.dnAttributes() );
-        assertEquals( AbstractExprNode.EXTENSIBLE, node.getAssertionType() );
-    }
-
-
-    public void testReuseParser() throws IOException, ParseException
-    {
-        parser.parse( "( ou ~= people )" );
-        parser.parse( "(& ( ou ~= people ) (age>=30) ) " );
-        parser.parse( "(| ( ou ~= people ) (age>=30) ) " );
-        parser.parse( "( ! (& ( ou ~= people ) (age>=30) ) )" );
-        parser.parse( "( ou;lang-de >= \\23\\42asdl fkajsd )" );
-        parser.parse( "( ou;lang-de;version-124 >= \\23\\42asdl fkajsd )" );
-        parser.parse( "( 1.3.4.2;lang-de;version-124 >= \\23\\42asdl fkajsd )" );
-        parser.parse( "( ou =* )" );
-        parser.parse( "( 1.2.3.4 = * )" );
-        parser.parse( "( ou = people )" );
-        parser.parse( "( ou = people/in/my/company )" );
-        parser.parse( "( ou :dn :stupidMatch := dummyAssertion\\23\\ac )" );
-        parser.parse( "( 1.2.3.4 :dn :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        parser.parse( "( ou :stupidMatch := dummyAssertion\\23\\ac )" );
-        parser.parse( "( ou := dummyAssertion\\23\\ac )" );
-        parser.parse( "( 1.2.3.4 :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        parser.parse( "( :dn :stupidMatch := dummyAssertion\\23\\ac )" );
-        parser.parse( "( :dn :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        parser.parse( "( :stupidMatch := dummyAssertion\\23\\ac )" );
-        parser.parse( "( :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        parser.parse( "( := dummyAssertion\\23\\ac )" );
-    }
-
-
-    public void testReuseParserAfterFailures() throws IOException, ParseException
-    {
-        parser.parse( "( ou ~= people )" );
-        parser.parse( "(& ( ou ~= people ) (age>=30) ) " );
-        parser.parse( "(| ( ou ~= people ) (age>=30) ) " );
-        parser.parse( "( ! (& ( ou ~= people ) (age>=30) ) )" );
-        parser.parse( "( ou;lang-de >= \\23\\42asdl fkajsd )" );
-        parser.parse( "( ou;lang-de;version-124 >= \\23\\42asdl fkajsd )" );
-        parser.parse( "( 1.3.4.2;lang-de;version-124 >= \\23\\42asdl fkajsd )" );
-        try
-        {
-            parser.parse( "( ou :stupidMatch;lang-de := dummyAssertion\\23\\ac )" );
-            fail( "we should never get here" );
-        }
-        catch ( IOException e )
-        {
-        }
-        catch ( ParseException e )
-        {
-        }
-        parser.parse( "( ou =* )" );
-        parser.parse( "( 1.2.3.4 = * )" );
-        parser.parse( "( ou = people )" );
-        parser.parse( "( ou = people/in/my/company )" );
-        parser.parse( "( ou :dn :stupidMatch := dummyAssertion\\23\\ac )" );
-        parser.parse( "( 1.2.3.4 :dn :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        parser.parse( "( ou :stupidMatch := dummyAssertion\\23\\ac )" );
-        try
-        {
-            parser.parse( "( :dn :stupidMatch;lang-en := dummyAssertion\\23\\ac )" );
-            fail( "we should never get here" );
-        }
-        catch ( IOException e )
-        {
-        }
-        catch ( ParseException e )
-        {
-        }
-        parser.parse( "( ou := dummyAssertion\\23\\ac )" );
-        parser.parse( "( 1.2.3.4 :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        parser.parse( "( :dn :stupidMatch := dummyAssertion\\23\\ac )" );
-        parser.parse( "( :dn :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        parser.parse( "( :stupidMatch := dummyAssertion\\23\\ac )" );
-        parser.parse( "( :1.3434.23.2 := dummyAssertion\\23\\ac )" );
-        parser.parse( "( := dummyAssertion\\23\\ac )" );
-    }
-
-
-    public void testNullOrEmptyString() throws IOException, ParseException
-    {
-        assertNull( parser.parse( null ) );
-        assertNull( parser.parse( "" ) );
-    }
-
-
-    public void testSubstringNoAnyNoFinal() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou = foo* )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 0, node.getAny().size() );
-        assertFalse( node.getAny().contains( "" ) );
-        assertEquals( "foo", node.getInitial() );
-        assertEquals( null, node.getFinal() );
-    }
-
-
-    public void testSubstringNoAny() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou = foo*bar )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 0, node.getAny().size() );
-        assertFalse( node.getAny().contains( "" ) );
-        assertEquals( "foo", node.getInitial() );
-        assertEquals( "bar", node.getFinal() );
-    }
-
-
-    public void testSubstringNoAnyNoIni() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou = *bar )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 0, node.getAny().size() );
-        assertFalse( node.getAny().contains( "" ) );
-        assertEquals( null, node.getInitial() );
-        assertEquals( "bar", node.getFinal() );
-    }
-
-
-    public void testSubstringOneAny() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou = foo*guy*bar )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 1, node.getAny().size() );
-        assertFalse( node.getAny().contains( "" ) );
-        assertTrue( node.getAny().contains( "guy" ) );
-        assertEquals( "foo", node.getInitial() );
-        assertEquals( "bar", node.getFinal() );
-    }
-
-
-    public void testSubstringManyAny() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou =a*b*c*d*e*f )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 4, node.getAny().size() );
-        assertFalse( node.getAny().contains( "" ) );
-        assertTrue( node.getAny().contains( "b" ) );
-        assertTrue( node.getAny().contains( "c" ) );
-        assertTrue( node.getAny().contains( "d" ) );
-        assertTrue( node.getAny().contains( "e" ) );
-        assertEquals( "a", node.getInitial() );
-        assertEquals( "f", node.getFinal() );
-    }
-
-
-    public void testSubstringNoIniManyAny() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou =*b*c*d*e*f )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 4, node.getAny().size() );
-        assertFalse( node.getAny().contains( "" ) );
-        assertTrue( node.getAny().contains( "e" ) );
-        assertTrue( node.getAny().contains( "b" ) );
-        assertTrue( node.getAny().contains( "c" ) );
-        assertTrue( node.getAny().contains( "d" ) );
-        assertEquals( null, node.getInitial() );
-        assertEquals( "f", node.getFinal() );
-    }
-
-
-    public void testSubstringManyAnyNoFinal() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou =a*b*c*d*e* )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 4, node.getAny().size() );
-        assertFalse( node.getAny().contains( "" ) );
-        assertTrue( node.getAny().contains( "e" ) );
-        assertTrue( node.getAny().contains( "b" ) );
-        assertTrue( node.getAny().contains( "c" ) );
-        assertTrue( node.getAny().contains( "d" ) );
-        assertEquals( "a", node.getInitial() );
-        assertEquals( null, node.getFinal() );
-    }
-
-
-    public void testSubstringNoIniManyAnyNoFinal() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou =*b*c*d*e* )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 4, node.getAny().size() );
-        assertFalse( node.getAny().contains( "" ) );
-        assertTrue( node.getAny().contains( "e" ) );
-        assertTrue( node.getAny().contains( "b" ) );
-        assertTrue( node.getAny().contains( "c" ) );
-        assertTrue( node.getAny().contains( "d" ) );
-        assertEquals( null, node.getInitial() );
-        assertEquals( null, node.getFinal() );
-    }
-
-
-    public void testSubstringNoAnyDoubleSpaceStar() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou = foo* *bar )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 0, node.getAny().size() );
-        assertFalse( node.getAny().contains( "" ) );
-        assertFalse( node.getAny().contains( " " ) );
-        assertEquals( "foo", node.getInitial() );
-        assertEquals( "bar", node.getFinal() );
-    }
-
-
-    public void testSubstringAnyDoubleSpaceStar() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou = foo* a *bar )" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 1, node.getAny().size() );
-        assertFalse( node.getAny().contains( "" ) );
-        assertTrue( node.getAny().contains( "a" ) );
-        assertEquals( "foo", node.getInitial() );
-        assertEquals( "bar", node.getFinal() );
-    }
-
-
-    /**
-     * Enrique just found this bug with the filter parser when parsing substring
-     * expressions like *any*. Here's the JIRA issue: <a
-     * href="http://nagoya.apache.org/jira/browse/DIRLDAP-21">DIRLDAP-21</a>.
-     */
-    public void testSubstringStarAnyStar() throws IOException, ParseException
-    {
-        SubstringNode node = ( SubstringNode ) parser.parse( "( ou =*foo*)" );
-        assertEquals( "ou", node.getAttribute() );
-        assertEquals( AbstractExprNode.SUBSTRING, node.getAssertionType() );
-
-        assertEquals( 1, node.getAny().size() );
-        assertTrue( node.getAny().contains( "foo" ) );
-        assertNull( node.getInitial() );
-        assertNull( node.getFinal() );
-    }
-
-    /* @todo look at custom error handlers for the parser */
-    // ///// Causes parser to hang rather than really bombing out. Looks like
-    // ///// we may need to implement a custom error handler for this parser.
-    // public void testSubstringNoAnyDoubleStar() throws IOException,
-    // ParseException
-    // {
-    // SubstringNode node = null;
-    //
-    // try
-    // {
-    // node = ( SubstringNode ) parser.parse( "( ou = foo**bar )" );
-    // fail("should not get here");
-    // }
-    // catch( Exception e )
-    // {
-    // }
-    //
-    // assertNull( node );
-    // }
+public class FilterParserImplTest extends TestCase {
+	private FilterParserImpl parser;
+
+	protected void setUp() throws Exception {
+		parser = new FilterParserImpl();
+	}
+
+	protected void tearDown() throws Exception {
+		parser = null;
+	}
+
+	/**
+	 * Tests to avoid deadlocks for invalid filters. 
+	 * 
+	 */
+	public void testInvalidFilters() throws IOException, ParseException {
+		try {
+			parser.parse("(cn=)");
+			fail("Invalid filter '(cn=)'");
+		} catch (Exception e) {
+			// Expected, invalid filter
+		}
+
+		try {
+			parser.parse("(cn=test(");
+			fail("Invalid filter '(cn=test('");
+		} catch (Exception e) {
+			// Expected, invalid filter
+		}
+
+		try {
+			parser.parse("(cn=aaaaa");
+			fail("Invalid filter '(cn=aaaaa'");
+		} catch (Exception e) {
+			// Expected, invalid filter
+		}
+
+		try {
+			parser.parse("(&(cn=abc)");
+			fail("Invalid filter '(&(cn=abc)'");
+		} catch (Exception e) {
+			// Expected, invalid filter
+		}
+	}
+
+	public void testItemFilter() throws IOException, ParseException {
+		SimpleNode node = (SimpleNode) parser.parse("( ou ~= people )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals("people", node.getValue());
+		assertEquals(AbstractExprNode.APPROXIMATE, node.getAssertionType());
+	}
+
+	public void testAndFilter() throws IOException, ParseException {
+		BranchNode node = (BranchNode) parser
+				.parse("(& ( ou ~= people ) (age>=30) ) ");
+		assertEquals(2, node.getChildren().size());
+		assertEquals(AbstractExprNode.AND, node.getOperator());
+	}
+
+	public void testAndFilterOneChildOnly() throws IOException, ParseException {
+		BranchNode node = (BranchNode) parser.parse("(& ( ou ~= people ) ) ");
+		assertEquals(1, node.getChildren().size());
+		assertEquals(AbstractExprNode.AND, node.getOperator());
+	}
+
+	public void testOrFilter() throws IOException, ParseException {
+		BranchNode node = (BranchNode) parser
+				.parse("(| ( ou ~= people ) (age>=30) ) ");
+		assertEquals(2, node.getChildren().size());
+		assertEquals(AbstractExprNode.OR, node.getOperator());
+	}
+
+	public void testOrFilterOneChildOnly() throws IOException, ParseException {
+		BranchNode node = (BranchNode) parser.parse("(| (age>=30) ) ");
+		assertEquals(1, node.getChildren().size());
+		assertEquals(AbstractExprNode.OR, node.getOperator());
+	}
+
+	public void testNotFilter() throws IOException, ParseException {
+		BranchNode node = (BranchNode) parser
+				.parse("( ! (& ( ou ~= people ) (age>=30) ) )");
+		assertEquals(1, node.getChildren().size());
+		assertEquals(AbstractExprNode.NOT, node.getOperator());
+	}
+
+	public void testOptionAndEscapesFilter() throws IOException, ParseException {
+		SimpleNode node = (SimpleNode) parser
+				.parse("( ou;lang-de >= \\23\\42asdl fkajsd )");
+		assertEquals("ou;lang-de", node.getAttribute());
+		assertEquals("\\23\\42asdl fkajsd", node.getValue());
+	}
+
+	public void testOptionsAndEscapesFilter() throws IOException,
+			ParseException {
+		SimpleNode node = (SimpleNode) parser
+				.parse("( ou;lang-de;version-124 >= \\23\\42asdl fkajsd )");
+		assertEquals("ou;lang-de;version-124", node.getAttribute());
+		assertEquals("\\23\\42asdl fkajsd", node.getValue());
+	}
+
+	public void testNumericoidOptionsAndEscapesFilter() throws IOException,
+			ParseException {
+		SimpleNode node = (SimpleNode) parser
+				.parse("( 1.3.4.2;lang-de;version-124 >= \\23\\42asdl fkajsd )");
+		assertEquals("1.3.4.2;lang-de;version-124", node.getAttribute());
+		assertEquals("\\23\\42asdl fkajsd", node.getValue());
+	}
+
+	public void testPresentFilter() throws IOException, ParseException {
+		PresenceNode node = (PresenceNode) parser.parse("( ou =*)");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+
+		node = (PresenceNode) parser.parse("( ou =* )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+
+		node = (PresenceNode) parser.parse("( ou =  * )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+
+		node = (PresenceNode) parser.parse("(  ou = *)");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+
+		node = (PresenceNode) parser.parse("( ou =* ) ");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+
+		node = (PresenceNode) parser.parse("( ou =*)");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+	}
+
+	public void testNumericoidPresentFilter() throws IOException,
+			ParseException {
+		PresenceNode node = (PresenceNode) parser.parse("( 1.2.3.4 = * )");
+		assertEquals("1.2.3.4", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+
+		node = (PresenceNode) parser.parse("( 1.2.3.4 =  * )");
+		assertEquals("1.2.3.4", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+
+		node = (PresenceNode) parser.parse("(  1.2.3.4 = *)");
+		assertEquals("1.2.3.4", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+
+		node = (PresenceNode) parser.parse("( 1.2.3.4 =* ) ");
+		assertEquals("1.2.3.4", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+
+		node = (PresenceNode) parser.parse("( 1.2.3.4 =*)");
+		assertEquals("1.2.3.4", node.getAttribute());
+		assertEquals(AbstractExprNode.PRESENCE, node.getAssertionType());
+	}
+
+	public void testEqualsFilter() throws IOException, ParseException {
+		SimpleNode node = (SimpleNode) parser.parse("( ou = people )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals("people", node.getValue());
+		assertEquals(AbstractExprNode.EQUALITY, node.getAssertionType());
+	}
+
+	public void testBadEqualsFilter() throws IOException, ParseException {
+		try {
+			parser.parse("ou = people");
+
+			// The parsing should fail
+			fail("should fail with bad filter");
+		} catch (ParseException pe) {
+		}
+	}
+
+	public void testEqualsWithForwardSlashFilter() throws IOException,
+			ParseException {
+		SimpleNode node = (SimpleNode) parser
+				.parse("( ou = people/in/my/company )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals("people/in/my/company", node.getValue());
+		assertEquals(AbstractExprNode.EQUALITY, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm1() throws IOException, ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( ou :dn :stupidMatch := dummyAssertion\\23\\ac )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals("dummyAssertion\\23\\ac", StringTools.utf8ToString(node
+				.getValue()));
+		assertEquals("stupidMatch", node.getMatchingRuleId());
+		assertTrue(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm1WithNumericOid() throws IOException,
+			ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( 1.2.3.4 :dn :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		assertEquals("1.2.3.4", node.getAttribute());
+		assertEquals("dummyAssertion\\23\\ac", StringTools.utf8ToString(node
+				.getValue()));
+		assertEquals("1.3434.23.2", node.getMatchingRuleId());
+		assertTrue(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm1NoDnAttr() throws IOException,
+			ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( ou :stupidMatch := dummyAssertion\\23\\ac )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals("dummyAssertion\\23\\ac", StringTools.utf8ToString(node
+				.getValue()));
+		assertEquals("stupidMatch", node.getMatchingRuleId());
+		assertFalse(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm1OptionOnRule() throws IOException,
+			ParseException {
+		try {
+			parser
+					.parse("( ou :stupidMatch;lang-de := dummyAssertion\\23\\ac )");
+			fail("we should never get here");
+		} catch (IOException e) {
+		} catch (ParseException e) {
+		}
+	}
+
+	public void testExtensibleFilterForm1NoAttrNoMatchingRule()
+			throws IOException, ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( ou := dummyAssertion\\23\\ac )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals("dummyAssertion\\23\\ac", StringTools.utf8ToString(node
+				.getValue()));
+		assertEquals(null, node.getMatchingRuleId());
+		assertFalse(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm1NoDnAttrWithNumericOidNoAttr()
+			throws IOException, ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( 1.2.3.4 :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		assertEquals("1.2.3.4", node.getAttribute());
+		assertEquals("dummyAssertion\\23\\ac", StringTools.utf8ToString(node
+				.getValue()));
+		assertEquals("1.3434.23.2", node.getMatchingRuleId());
+		assertFalse(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm2() throws IOException, ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( :dn :stupidMatch := dummyAssertion\\23\\ac )");
+		assertEquals(null, node.getAttribute());
+		assertEquals("dummyAssertion\\23\\ac", StringTools.utf8ToString(node
+				.getValue()));
+		assertEquals("stupidMatch", node.getMatchingRuleId());
+		assertTrue(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm2OptionOnRule() throws IOException,
+			ParseException {
+		try {
+			parser
+					.parse("( :dn :stupidMatch;lang-en := dummyAssertion\\23\\ac )");
+			fail("we should never get here");
+		} catch (IOException e) {
+		} catch (ParseException e) {
+		}
+	}
+
+	public void testExtensibleFilterForm2WithNumericOid() throws IOException,
+			ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( :dn :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		assertEquals(null, node.getAttribute());
+		assertEquals("dummyAssertion\\23\\ac", StringTools.utf8ToString(node
+				.getValue()));
+		assertEquals("1.3434.23.2", node.getMatchingRuleId());
+		assertTrue(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm2NoDnAttr() throws IOException,
+			ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( :stupidMatch := dummyAssertion\\23\\ac )");
+		assertEquals(null, node.getAttribute());
+		assertEquals("dummyAssertion\\23\\ac", StringTools.utf8ToString(node
+				.getValue()));
+		assertEquals("stupidMatch", node.getMatchingRuleId());
+		assertFalse(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm2NoDnAttrWithNumericOidNoAttr()
+			throws IOException, ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		assertEquals(null, node.getAttribute());
+		assertEquals("dummyAssertion\\23\\ac", StringTools.utf8ToString(node
+				.getValue()));
+		assertEquals("1.3434.23.2", node.getMatchingRuleId());
+		assertFalse(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm3() throws IOException, ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( := dummyAssertion )");
+		assertEquals(null, node.getAttribute());
+		assertEquals("dummyAssertion", StringTools
+				.utf8ToString(node.getValue()));
+		assertEquals(null, node.getMatchingRuleId());
+		assertFalse(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testExtensibleFilterForm3WithEscapes() throws IOException,
+			ParseException {
+		ExtensibleNode node = (ExtensibleNode) parser
+				.parse("( := dummyAssertion\\23\\ac )");
+		assertEquals(null, node.getAttribute());
+		assertEquals("dummyAssertion\\23\\ac", StringTools.utf8ToString(node
+				.getValue()));
+		assertEquals(null, node.getMatchingRuleId());
+		assertFalse(node.dnAttributes());
+		assertEquals(AbstractExprNode.EXTENSIBLE, node.getAssertionType());
+	}
+
+	public void testReuseParser() throws IOException, ParseException {
+		parser.parse("( ou ~= people )");
+		parser.parse("(& ( ou ~= people ) (age>=30) ) ");
+		parser.parse("(| ( ou ~= people ) (age>=30) ) ");
+		parser.parse("( ! (& ( ou ~= people ) (age>=30) ) )");
+		parser.parse("( ou;lang-de >= \\23\\42asdl fkajsd )");
+		parser.parse("( ou;lang-de;version-124 >= \\23\\42asdl fkajsd )");
+		parser.parse("( 1.3.4.2;lang-de;version-124 >= \\23\\42asdl fkajsd )");
+		parser.parse("( ou =* )");
+		parser.parse("( 1.2.3.4 = * )");
+		parser.parse("( ou = people )");
+		parser.parse("( ou = people/in/my/company )");
+		parser.parse("( ou :dn :stupidMatch := dummyAssertion\\23\\ac )");
+		parser.parse("( 1.2.3.4 :dn :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		parser.parse("( ou :stupidMatch := dummyAssertion\\23\\ac )");
+		parser.parse("( ou := dummyAssertion\\23\\ac )");
+		parser.parse("( 1.2.3.4 :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		parser.parse("( :dn :stupidMatch := dummyAssertion\\23\\ac )");
+		parser.parse("( :dn :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		parser.parse("( :stupidMatch := dummyAssertion\\23\\ac )");
+		parser.parse("( :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		parser.parse("( := dummyAssertion\\23\\ac )");
+	}
+
+	public void testReuseParserAfterFailures() throws IOException,
+			ParseException {
+		parser.parse("( ou ~= people )");
+		parser.parse("(& ( ou ~= people ) (age>=30) ) ");
+		parser.parse("(| ( ou ~= people ) (age>=30) ) ");
+		parser.parse("( ! (& ( ou ~= people ) (age>=30) ) )");
+		parser.parse("( ou;lang-de >= \\23\\42asdl fkajsd )");
+		parser.parse("( ou;lang-de;version-124 >= \\23\\42asdl fkajsd )");
+		parser.parse("( 1.3.4.2;lang-de;version-124 >= \\23\\42asdl fkajsd )");
+		try {
+			parser
+					.parse("( ou :stupidMatch;lang-de := dummyAssertion\\23\\ac )");
+			fail("we should never get here");
+		} catch (IOException e) {
+		} catch (ParseException e) {
+		}
+		parser.parse("( ou =* )");
+		parser.parse("( 1.2.3.4 = * )");
+		parser.parse("( ou = people )");
+		parser.parse("( ou = people/in/my/company )");
+		parser.parse("( ou :dn :stupidMatch := dummyAssertion\\23\\ac )");
+		parser.parse("( 1.2.3.4 :dn :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		parser.parse("( ou :stupidMatch := dummyAssertion\\23\\ac )");
+		try {
+			parser
+					.parse("( :dn :stupidMatch;lang-en := dummyAssertion\\23\\ac )");
+			fail("we should never get here");
+		} catch (IOException e) {
+		} catch (ParseException e) {
+		}
+		parser.parse("( ou := dummyAssertion\\23\\ac )");
+		parser.parse("( 1.2.3.4 :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		parser.parse("( :dn :stupidMatch := dummyAssertion\\23\\ac )");
+		parser.parse("( :dn :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		parser.parse("( :stupidMatch := dummyAssertion\\23\\ac )");
+		parser.parse("( :1.3434.23.2 := dummyAssertion\\23\\ac )");
+		parser.parse("( := dummyAssertion\\23\\ac )");
+	}
+
+	public void testNullOrEmptyString() throws IOException, ParseException {
+		assertNull(parser.parse(null));
+		assertNull(parser.parse(""));
+	}
+
+	public void testSubstringNoAnyNoFinal() throws IOException, ParseException {
+		SubstringNode node = (SubstringNode) parser.parse("( ou = foo* )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(0, node.getAny().size());
+		assertFalse(node.getAny().contains(""));
+		assertEquals("foo", node.getInitial());
+		assertEquals(null, node.getFinal());
+	}
+
+	public void testSubstringNoAny() throws IOException, ParseException {
+		SubstringNode node = (SubstringNode) parser.parse("( ou = foo*bar )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(0, node.getAny().size());
+		assertFalse(node.getAny().contains(""));
+		assertEquals("foo", node.getInitial());
+		assertEquals("bar", node.getFinal());
+	}
+
+	public void testSubstringNoAnyNoIni() throws IOException, ParseException {
+		SubstringNode node = (SubstringNode) parser.parse("( ou = *bar )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(0, node.getAny().size());
+		assertFalse(node.getAny().contains(""));
+		assertEquals(null, node.getInitial());
+		assertEquals("bar", node.getFinal());
+	}
+
+	public void testSubstringOneAny() throws IOException, ParseException {
+		SubstringNode node = (SubstringNode) parser
+				.parse("( ou = foo*guy*bar )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(1, node.getAny().size());
+		assertFalse(node.getAny().contains(""));
+		assertTrue(node.getAny().contains("guy"));
+		assertEquals("foo", node.getInitial());
+		assertEquals("bar", node.getFinal());
+	}
+
+	public void testSubstringManyAny() throws IOException, ParseException {
+		SubstringNode node = (SubstringNode) parser
+				.parse("( ou =a*b*c*d*e*f )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(4, node.getAny().size());
+		assertFalse(node.getAny().contains(""));
+		assertTrue(node.getAny().contains("b"));
+		assertTrue(node.getAny().contains("c"));
+		assertTrue(node.getAny().contains("d"));
+		assertTrue(node.getAny().contains("e"));
+		assertEquals("a", node.getInitial());
+		assertEquals("f", node.getFinal());
+	}
+
+	public void testSubstringNoIniManyAny() throws IOException, ParseException {
+		SubstringNode node = (SubstringNode) parser.parse("( ou =*b*c*d*e*f )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(4, node.getAny().size());
+		assertFalse(node.getAny().contains(""));
+		assertTrue(node.getAny().contains("e"));
+		assertTrue(node.getAny().contains("b"));
+		assertTrue(node.getAny().contains("c"));
+		assertTrue(node.getAny().contains("d"));
+		assertEquals(null, node.getInitial());
+		assertEquals("f", node.getFinal());
+	}
+
+	public void testSubstringManyAnyNoFinal() throws IOException,
+			ParseException {
+		SubstringNode node = (SubstringNode) parser.parse("( ou =a*b*c*d*e* )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(4, node.getAny().size());
+		assertFalse(node.getAny().contains(""));
+		assertTrue(node.getAny().contains("e"));
+		assertTrue(node.getAny().contains("b"));
+		assertTrue(node.getAny().contains("c"));
+		assertTrue(node.getAny().contains("d"));
+		assertEquals("a", node.getInitial());
+		assertEquals(null, node.getFinal());
+	}
+
+	public void testSubstringNoIniManyAnyNoFinal() throws IOException,
+			ParseException {
+		SubstringNode node = (SubstringNode) parser.parse("( ou =*b*c*d*e* )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(4, node.getAny().size());
+		assertFalse(node.getAny().contains(""));
+		assertTrue(node.getAny().contains("e"));
+		assertTrue(node.getAny().contains("b"));
+		assertTrue(node.getAny().contains("c"));
+		assertTrue(node.getAny().contains("d"));
+		assertEquals(null, node.getInitial());
+		assertEquals(null, node.getFinal());
+	}
+
+	public void testSubstringNoAnyDoubleSpaceStar() throws IOException,
+			ParseException {
+		SubstringNode node = (SubstringNode) parser.parse("( ou = foo* *bar )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(0, node.getAny().size());
+		assertFalse(node.getAny().contains(""));
+		assertFalse(node.getAny().contains(" "));
+		assertEquals("foo", node.getInitial());
+		assertEquals("bar", node.getFinal());
+	}
+
+	public void testSubstringAnyDoubleSpaceStar() throws IOException,
+			ParseException {
+		SubstringNode node = (SubstringNode) parser
+				.parse("( ou = foo* a *bar )");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(1, node.getAny().size());
+		assertFalse(node.getAny().contains(""));
+		assertTrue(node.getAny().contains("a"));
+		assertEquals("foo", node.getInitial());
+		assertEquals("bar", node.getFinal());
+	}
+
+	/**
+	 * Enrique just found this bug with the filter parser when parsing substring
+	 * expressions like *any*. Here's the JIRA issue: <a
+	 * href="http://nagoya.apache.org/jira/browse/DIRLDAP-21">DIRLDAP-21</a>.
+	 */
+	public void testSubstringStarAnyStar() throws IOException, ParseException {
+		SubstringNode node = (SubstringNode) parser.parse("( ou =*foo*)");
+		assertEquals("ou", node.getAttribute());
+		assertEquals(AbstractExprNode.SUBSTRING, node.getAssertionType());
+
+		assertEquals(1, node.getAny().size());
+		assertTrue(node.getAny().contains("foo"));
+		assertNull(node.getInitial());
+		assertNull(node.getFinal());
+	}
+
+	/* @todo look at custom error handlers for the parser */
+	// ///// Causes parser to hang rather than really bombing out. Looks like
+	// ///// we may need to implement a custom error handler for this parser.
+	// public void testSubstringNoAnyDoubleStar() throws IOException,
+	// ParseException
+	// {
+	// SubstringNode node = null;
+	//
+	// try
+	// {
+	// node = ( SubstringNode ) parser.parse( "( ou = foo**bar )" );
+	// fail("should not get here");
+	// }
+	// catch( Exception e )
+	// {
+	// }
+	//
+	// assertNull( node );
+	// }
 }



Mime
View raw message