You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2013/10/31 08:33:58 UTC

svn commit: r1537394 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/io/ testing/org/apache/derbyTesting/functionTests/tests/engine/ testing/org/apache/derbyTesting/functionTests/util/

Author: kahatlen
Date: Thu Oct 31 07:33:58 2013
New Revision: 1537394

URL: http://svn.apache.org/r1537394
Log:
DERBY-6396: NullPointerException in DirFile

Check that the array returned by File.list() is non-null before
attempting to iterate through it. Null is a valid return value.

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/Derby6396Test.java   (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirFile.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/_Suite.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/PrivilegedFileOpsForTests.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirFile.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirFile.java?rev=1537394&r1=1537393&r2=1537394&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirFile.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirFile.java Thu Oct 31 07:33:58 2013
@@ -402,11 +402,21 @@ class DirFile extends File implements St
      */
     public boolean deleteAll()
     {
-        if( !exists())
+        // Nothing to do if the file doesn't exist.
+        if (!exists()) {
             return false;
-        if( isDirectory())
+        }
+
+        // If the file is a directory, delete its contents recursively.
+        // File.list() will return null if it is not a directory, or if the
+        // contents of the directory cannot be read. Skip the recursive step
+        // in both of those cases. If it turns out that the file in fact is a
+        // directory, and we couldn't delete its contents, the delete() call
+        // at the end of this method will return false to notify the caller
+        // that the directory could not be deleted.
+        String[] childList = super.list();
+        if (childList != null)
         {
-            String[] childList = super.list();
             String parentName = getPath();
             for( int i = 0; i < childList.length; i++)
             {
@@ -417,6 +427,9 @@ class DirFile extends File implements St
                     return false;
             }
         }
+
+        // Finally, attempt to delete the file (or directory) and return
+        // whether or not we succeeded.
         return delete();
     } // end of deleteAll
 

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/Derby6396Test.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/Derby6396Test.java?rev=1537394&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/Derby6396Test.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/Derby6396Test.java Thu Oct 31 07:33:58 2013
@@ -0,0 +1,77 @@
+/*
+  Class org.apache.derbyTesting.functionTests.tests.engine.Derby6396Test
+
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to you under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+*/
+
+package org.apache.derbyTesting.functionTests.tests.engine;
+
+import java.io.File;
+import java.sql.SQLException;
+import junit.framework.Test;
+import org.apache.derbyTesting.functionTests.util.PrivilegedFileOpsForTests;
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.TestConfiguration;
+
+/**
+ * Regression test case for DERBY-6396. Verify that booting the database
+ * does not fail with a NullPointerException if the user lacks read access
+ * on the temporary directory.
+ */
+public class Derby6396Test extends BaseJDBCTestCase {
+    private File tmpDir;
+
+    public Derby6396Test(String name) {
+        super(name);
+    }
+
+    public static Test suite() {
+        // Use a separate database for this test to reduce the risk of
+        // interfering with other tests when changing file permissions.
+        return TestConfiguration.singleUseDatabaseDecorator(
+                TestConfiguration.embeddedSuite(Derby6396Test.class));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (tmpDir != null) {
+            // Reset the permission of the temporary directory so that we
+            // don't run into problems when dropping the database.
+            PrivilegedFileOpsForTests.setReadable(tmpDir, true, true);
+            tmpDir = null;
+        }
+        super.tearDown();
+    }
+
+    public void testTempNotReadable() throws SQLException {
+        final TestConfiguration config = TestConfiguration.getCurrent();
+
+        // First make sure the database exists and is not booted.
+        getConnection().close();
+        config.shutdownDatabase();
+
+        // Now make sure the database has a tmp directory that cannot be read.
+        tmpDir = new File(
+            config.getDatabasePath(config.getDefaultDatabaseName()), "tmp");
+        assertTrue(PrivilegedFileOpsForTests.mkdir(tmpDir));
+        PrivilegedFileOpsForTests.setReadable(tmpDir, false, true);
+
+        // Booting the database used to fail with a NullPointerException.
+        // Should succeed now.
+        getConnection().close();
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/Derby6396Test.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/_Suite.java?rev=1537394&r1=1537393&r2=1537394&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/_Suite.java Thu Oct 31 07:33:58 2013
@@ -54,6 +54,7 @@ public class _Suite extends BaseTestCase
         suite.addTest(ModuleLoadingTest.suite());
         suite.addTest(ReadMeFilesTest.suite());
         suite.addTest(ShutdownWithoutDeregisterPermissionTest.suite());
+        suite.addTest(Derby6396Test.suite());
 
         return suite;
     }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/PrivilegedFileOpsForTests.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/PrivilegedFileOpsForTests.java?rev=1537394&r1=1537393&r2=1537394&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/PrivilegedFileOpsForTests.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/PrivilegedFileOpsForTests.java Thu Oct 31 07:33:58 2013
@@ -162,6 +162,37 @@ public class PrivilegedFileOpsForTests {
     }
 
     /**
+     * Create a directory.
+     * @param dir the directory to create
+     * @return {@code true} if and only if the directory was created
+     */
+    public static boolean mkdir(final File dir) {
+        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+            public Boolean run() {
+                return dir.mkdir();
+            }
+        });
+    }
+
+    /**
+     * Set the read permission for a file.
+     * @param file      the file to set the read permission for
+     * @param readable  {@code true} to allow read, {@code false} to deny it
+     * @param ownerOnly {@code true} if it should be set for the owner only,
+     *                  {@code false} if it should be set for everyone
+     * @return {@code true} if the operation succeeded, {@code false} otherwise
+     */
+    public static boolean setReadable(final File file,
+                                      final boolean readable,
+                                      final boolean ownerOnly) {
+        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+            public Boolean run() {
+                return file.setReadable(readable, ownerOnly);
+            }
+        });
+    }
+
+    /**
      * Obtains a reader for the specified file.
      *
      * @param file the file to obtain a reader for
@@ -193,7 +224,6 @@ public class PrivilegedFileOpsForTests {
      *
      * @param file the file to obtain a writer for
      * @return An writer for the specified file.
-     * @throws IOException 
      * @throws IOException if the file cannot be opened
      * @throws SecurityException if the required permissions to write to the file,
      *      or the path it is in, are missing