You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2010/09/19 09:25:25 UTC

svn commit: r998606 - in /directory/apacheds/trunk/ldif-partition/src: main/java/org/apache/directory/server/core/partition/ldif/LdifPartition.java test/java/org/apache/directory/server/core/partition/LdifPartitionTest.java

Author: seelmann
Date: Sun Sep 19 07:25:24 2010
New Revision: 998606

URL: http://svn.apache.org/viewvc?rev=998606&view=rev
Log:
Fix for DIRSERVER-1551 (LdifPartition file names on Unix and Windows): URL encode all characters that may cause trouble in file systems

Modified:
    directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/LdifPartition.java
    directory/apacheds/trunk/ldif-partition/src/test/java/org/apache/directory/server/core/partition/LdifPartitionTest.java

Modified: directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/LdifPartition.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/LdifPartition.java?rev=998606&r1=998605&r2=998606&view=diff
==============================================================================
--- directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/LdifPartition.java (original)
+++ directory/apacheds/trunk/ldif-partition/src/main/java/org/apache/directory/server/core/partition/ldif/LdifPartition.java Sun Sep 19 07:25:24 2010
@@ -28,7 +28,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.UUID;
 
-import org.apache.commons.lang.SystemUtils;
 import org.apache.directory.server.core.entry.ClonedServerEntry;
 import org.apache.directory.server.core.interceptor.context.AddOperationContext;
 import org.apache.directory.server.core.interceptor.context.BindOperationContext;
@@ -621,103 +620,80 @@ public class LdifPartition extends Abstr
 
 
     /**
-     * Get a OS compatible file name
+     * Get a OS compatible file name. We URL encode all characters that may cause trouble
+     * according to http://en.wikipedia.org/wiki/Filenames. This includes C0 control characters
+     * [0x00-0x1F] and 0x7F, see http://en.wikipedia.org/wiki/Control_characters.
      */
     private String getOSFileName( String fileName )
     {
-        if ( SystemUtils.IS_OS_WINDOWS )
-        {
-            // On Windows, we escape '/', '<', '>', '\', '|', '"', ':', '+', ' ', '[', ']',
-            // '*', [0x00-0x1F], '?', and '%' with "%xx" where xx is the hex value of the character.
-            StringBuilder sb = new StringBuilder();
-
-            for ( char c : fileName.toCharArray() )
-            {
-                switch ( c )
-                {
-                    case 0x00:
-                    case 0x01:
-                    case 0x02:
-                    case 0x03:
-                    case 0x04:
-                    case 0x05:
-                    case 0x06:
-                    case 0x07:
-                    case 0x08:
-                    case 0x09:
-                    case 0x0A:
-                    case 0x0B:
-                    case 0x0C:
-                    case 0x0D:
-                    case 0x0E:
-                    case 0x0F:
-                    case 0x10:
-                    case 0x11:
-                    case 0x12:
-                    case 0x13:
-                    case 0x14:
-                    case 0x15:
-                    case 0x16:
-                    case 0x17:
-                    case 0x18:
-                    case 0x19:
-                    case 0x1A:
-                    case 0x1B:
-                    case 0x1C:
-                    case 0x1D:
-                    case 0x1E:
-                    case 0x1F:
-                    case '/':
-                    case '\\':
-                    case '<':
-                    case '>':
-                    case '|':
-                    case '"':
-                    case ':':
-                    case '+':
-                    case ' ':
-                    case '[':
-                    case ']':
-                    case '*':
-                    case '?':
-                    case '%':
-                        sb.append( "%" ).append( StringTools.dumpHex( ( byte ) ( c >> 4 ) ) )
-                                        .append( StringTools.dumpHex( ( byte ) ( c & 0xF ) ) );
-                        break;
-
-                    default:
-                        sb.append( c );
-                        break;
-                }
-            }
+        StringBuilder sb = new StringBuilder();
 
-            return sb.toString().toLowerCase();
-        }
-        else
+        for ( char c : fileName.toCharArray() )
         {
-            // On linux, just escape '/' and null
-            StringBuilder sb = new StringBuilder();
-
-            for ( char c : fileName.toCharArray() )
+            switch ( c )
             {
-                switch ( c )
-                {
-                    case '/':
-                        sb.append( "\\/" );
-                        break;
-
-                    case '\0':
-                        sb.append( "\\00" );
-                        break;
-
-                    default:
-                        sb.append( c );
-                        break;
-                }
+                case 0x00:
+                case 0x01:
+                case 0x02:
+                case 0x03:
+                case 0x04:
+                case 0x05:
+                case 0x06:
+                case 0x07:
+                case 0x08:
+                case 0x09:
+                case 0x0A:
+                case 0x0B:
+                case 0x0C:
+                case 0x0D:
+                case 0x0E:
+                case 0x0F:
+                case 0x10:
+                case 0x11:
+                case 0x12:
+                case 0x13:
+                case 0x14:
+                case 0x15:
+                case 0x16:
+                case 0x17:
+                case 0x18:
+                case 0x19:
+                case 0x1A:
+                case 0x1B:
+                case 0x1C:
+                case 0x1D:
+                case 0x1E:
+                case 0x1F:
+                case 0x7F:
+                case ' ': // 0x20
+                case '"': // 0x22
+                case '%': // 0x25
+                case '&': // 0x26
+                case '(': // 0x28
+                case ')': // 0x29
+                case '*': // 0x2A
+                case '+': // 0x2B
+                case '/': // 0x2F
+                case ':': // 0x3A
+                case ';': // 0x3B
+                case '<': // 0x3C
+                case '>': // 0x3E
+                case '?': // 0x3F
+                case '[': // 0x5B
+                case '\\': // 0x5C
+                case ']': // 0x5D
+                case '|': // 0x7C
+                    sb.append( "%" ).append( StringTools.dumpHex( ( byte ) ( c >> 4 ) ) )
+                                    .append( StringTools.dumpHex( ( byte ) ( c & 0xF ) ) );
+                    break;
+
+                default:
+                    sb.append( c );
+                    break;
             }
-
-            return sb.toString().toLowerCase();
         }
+
+        return sb.toString().toLowerCase();
     }
 
 

Modified: directory/apacheds/trunk/ldif-partition/src/test/java/org/apache/directory/server/core/partition/LdifPartitionTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/ldif-partition/src/test/java/org/apache/directory/server/core/partition/LdifPartitionTest.java?rev=998606&r1=998605&r2=998606&view=diff
==============================================================================
--- directory/apacheds/trunk/ldif-partition/src/test/java/org/apache/directory/server/core/partition/LdifPartitionTest.java (original)
+++ directory/apacheds/trunk/ldif-partition/src/test/java/org/apache/directory/server/core/partition/LdifPartitionTest.java Sun Sep 19 07:25:24 2010
@@ -66,10 +66,11 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.schema.manager.impl.DefaultSchemaManager;
 import org.apache.directory.shared.ldap.schema.normalizers.ConcreteNameComponentNormalizer;
 import org.apache.directory.shared.ldap.util.LdapExceptionUtils;
-import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -88,6 +89,9 @@ public class LdifPartitionTest
     private static SchemaManager schemaManager = null;
     private static CsnFactory defaultCSNFactory;
 
+    @Rule
+    public static TemporaryFolder folder = new TemporaryFolder();
+
 
     @BeforeClass
     public static void init() throws Exception
@@ -115,11 +119,6 @@ public class LdifPartitionTest
         }
 
         defaultCSNFactory = new CsnFactory( 0 );
-
-        wkdir = File.createTempFile( LdifPartitionTest.class.getSimpleName(), "db" );
-        wkdir.delete();
-        wkdir = new File( wkdir.getParentFile(), LdifPartitionTest.class.getSimpleName() );
-        FileUtils.deleteDirectory( wkdir );
     }
 
 
@@ -133,10 +132,8 @@ public class LdifPartitionTest
                 "ou: test";
 
         // setup the working directory for the store
-        wkdir = File.createTempFile( getClass().getSimpleName(), "db" );
-        wkdir.delete();
-        wkdir = new File( wkdir.getParentFile(), getClass().getSimpleName() );
-        wkdir.mkdirs();
+        wkdir = folder.newFile( "db" );
+        wkdir = folder.getRoot();
 
         // initialize the store
         // initialize the partition
@@ -154,14 +151,6 @@ public class LdifPartitionTest
     }
 
 
-    @After
-    public void destroyStore() throws Exception
-    {
-        // Delete the directory and its content
-        FileUtils.deleteDirectory( wkdir );
-    }
-
-
     private ClonedServerEntry createEntry( String dn ) throws Exception
     {
         Entry entry = new DefaultEntry( schemaManager );
@@ -218,10 +207,8 @@ public class LdifPartitionTest
         assertTrue( new File( wkdir, "ou=test,ou=system/dc=test.ldif" ).exists() );
         assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=test" ).exists() );
         assertTrue( new File( wkdir, "ou=test,ou=system/dc=test/dc=test.ldif" ).exists() );
-        assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn+objectclass=domain" ).exists()
-            || new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain" ).exists() );
-        assertTrue( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn+objectclass=domain.ldif" ).exists()
-            || new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain.ldif" ).exists() );
+        assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain" ).exists() );
+        assertTrue( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain.ldif" ).exists() );
     }
 
 
@@ -336,10 +323,8 @@ public class LdifPartitionTest
         assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=test1.ldif" ).exists() );
         assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=test2" ).exists() );
         assertTrue( new File( wkdir, "ou=test,ou=system/dc=test/dc=test2.ldif" ).exists() );
-        assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn+objectclass=domain" ).exists()
-            || new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain" ).exists() );
-        assertTrue( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn+objectclass=domain.ldif" ).exists()
-            || new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain.ldif" ).exists() );
+        assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain" ).exists() );
+        assertTrue( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain.ldif" ).exists() );
 
         dn = new DN( "dc=test2,dc=test,ou=test,ou=system", schemaManager );
 
@@ -359,10 +344,8 @@ public class LdifPartitionTest
         assertTrue( new File( wkdir, "ou=test,ou=system/dc=test.ldif" ).exists() );
         assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=test2" ).exists() );
         assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=test2.ldif" ).exists() );
-        assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn+objectclass=domain" ).exists()
-            || new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain" ).exists() );
-        assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn+objectclass=domain.ldif" ).exists()
-            || new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain.ldif" ).exists() );
+        assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain" ).exists() );
+        assertFalse( new File( wkdir, "ou=test,ou=system/dc=test/dc=mvrdn%2bobjectclass=domain.ldif" ).exists() );
     }
 
 
@@ -596,6 +579,70 @@ public class LdifPartitionTest
     }
 
 
+    /**
+     * Test for DIRSERVER-1551 (LdifPartition file names on Unix and Windows).
+     * Ensure that special characters (http://en.wikipedia.org/wiki/Filenames) are encoded.
+     */
+    @Test
+    public void testSpecialCharacters() throws Exception
+    {
+        DN adminDn = new DN( "uid=admin,ou=system", schemaManager );
+        CoreSession session = new MockCoreSession( new LdapPrincipal( adminDn, AuthenticationLevel.STRONG ),
+            new MockDirectoryService( 1 ) );
+        AddOperationContext addCtx = new AddOperationContext( session );
+
+        String rdnWithForbiddenChars = "dc=- -\\\"-%-&-(-)-*-\\+-/-:-\\;-\\<-\\>-?-[-\\5C-]-|-";
+        String rdnWithEscapedChars = "dc=-%20-%22-%25-%26-%28-%29-%2a-%2b-%2f-%3a-%3b-%3c-%3e-%3f-%5b-%5c-%5d-%7c-";
+
+        ClonedServerEntry entry1 = createEntry( rdnWithForbiddenChars + ",ou=test,ou=system" );
+        entry1.put( "objectClass", "top", "domain" );
+        addCtx.setEntry( entry1 );
+
+        partition.add( addCtx );
+
+        assertTrue( new File( wkdir, "ou=test,ou=system" ).exists() );
+        assertTrue( new File( wkdir, "ou=test,ou=system.ldif" ).exists() );
+        assertFalse( new File( wkdir, "ou=test,ou=system/" + rdnWithEscapedChars ).exists() );
+        assertTrue( new File( wkdir, "ou=test,ou=system/" + rdnWithEscapedChars + ".ldif" ).exists() );
+    }
+
+
+    /**
+     * Test for DIRSERVER-1551 (LdifPartition file names on Unix and Windows).
+     * Ensure that C0 control characters (http://en.wikipedia.org/wiki/Control_characters) are encoded.
+     */
+    @Test
+    public void testControlCharacters() throws Exception
+    {
+        DN adminDn = new DN( "uid=admin,ou=system", schemaManager );
+        CoreSession session = new MockCoreSession( new LdapPrincipal( adminDn, AuthenticationLevel.STRONG ),
+            new MockDirectoryService( 1 ) );
+        AddOperationContext addCtx = new AddOperationContext( session );
+
+        String rdnWithControlChars = "userPassword=-\u0000-\u0001-\u0002-\u0003-\u0004-\u0005-\u0006-\u0007" +
+                "-\u0008-\u0009-\n-\u000B-\u000C-\r-\u000E-\u000F" +
+                "-\u0010-\u0011-\u0012-\u0013-\u0014-\u0015-\u0016-\u0017" +
+                "-\u0018-\u0019-\u001A-\u001B-\u001C-\u001D-\u001E-\u001F" +
+                "-\u007F";
+
+        String rdnWithEscapedChars = "userpassword=-%00-%01-%02-%03-%04-%05-%06-%07-%08-%09-%0a-%0b-%0c-%0d-%0e-%0f" +
+                "-%10-%11-%12-%13-%14-%15-%16-%17-%18-%19-%1a-%1b-%1c-%1d-%1e-%1f-%7f";
+
+        ClonedServerEntry entry1 = createEntry( rdnWithControlChars + ",ou=test,ou=system" );
+        entry1.put( "objectClass", "top", "person" );
+        entry1.put( "cn", "test" );
+        entry1.put( "sn", "test" );
+        addCtx.setEntry( entry1 );
+
+        partition.add( addCtx );
+
+        assertTrue( new File( wkdir, "ou=test,ou=system" ).exists() );
+        assertTrue( new File( wkdir, "ou=test,ou=system.ldif" ).exists() );
+        assertFalse( new File( wkdir, "ou=test,ou=system/" + rdnWithEscapedChars ).exists() );
+        assertTrue( new File( wkdir, "ou=test,ou=system/" + rdnWithEscapedChars + ".ldif" ).exists() );
+    }
+
+
     private CoreSession injectEntries() throws Exception
     {
         DN adminDn = new DN( "uid=admin,ou=system", schemaManager );