Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
1.0
-
None
-
None
-
Operating System: All
Platform: All
-
36801
Description
java.io.File.list() returns null if an I/O error occurs. In practice this can
be triggered by trying to list the contents of a directory to which the user
does not have sufficient permissions (e.g. a directory with mode 0 on a
unix-like filesystem).
In this case, FileUtils.cleanDirectory currently throws NPE because it assumes
that File.list() will always return successfully. The correct behavior should
be to throw IOException instead.
Following inline is a patch against trunk which resolves the issue.
Index: src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java
===================================================================
— src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java (revision 0)
+++ src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java (revision 0)
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2003,2004 The Apache Software Foundation.
+ *
+ * Licensed 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.commons.io;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.testtools.FileBasedTestCase;
+
+/**
+ * Test cases for FileUtils.cleanDirectory() method.
+ */
+public class FileUtilsCleanDirectoryTestCase extends FileBasedTestCase {
+ final File top = getLocalTestDirectory();
+
+ public FileUtilsCleanDirectoryTestCase(String name)
+
+ private File getLocalTestDirectory()
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception
+
+ /**
+ * @see junit.framework.TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception
+
+ public void testCleanEmpty() throws Exception
+
+ public void testDeletesRegular() throws Exception
+
+ public void testDeletesNested() throws Exception
+
+ public void testThrowsOnNullList() throws Exception {
+ if (!chmod(top, 0, false))
+
+ try { + FileUtils.cleanDirectory(top); + fail("expected IOException"); + } catch (IOException e) { + assertEquals("Failed to list contents of " + top.getAbsolutePath(), e.getMessage()); + }
+ }
+
+ public void testThrowsOnCannotDeleteFile() throws Exception {
+ final File file = new File(top, "restricted");
+ FileUtils.touch(file);
+
+ if (!chmod(top, 500, false)) {+ // test wont work if we can't restrict permissions on thedirectory; skip it.+ return;+ }
+
+ try
catch (IOException e)
{ + assertEquals("Unable to delete file: " + file.getAbsolutePath(), e.getMessage()); + }+ }
+
+ private boolean chmod(File file, int mode, boolean recurse) throws
IOException, InterruptedException {
+ List args = new ArrayList();
+ args.add("chmod");
+
+ if (recurse)
+
+ args.add(Integer.toString(mode));
+ args.add(file.getAbsolutePath());
+
+ Process proc;
+
+ try
catch (IOException e)
{ + return false; + }+
+ int result = proc.waitFor();
+
+ assertEquals(0, result);
+ return true;
+ }
+}
Index: src/java/org/apache/commons/io/FileUtils.java
===================================================================
— src/java/org/apache/commons/io/FileUtils.java (revision 291328)
+++ src/java/org/apache/commons/io/FileUtils.java (working copy)
@@ -701,6 +701,11 @@
IOException exception = null;
File[] files = directory.listFiles();
+
+ if (files == null)
+
for (int i = 0; i < files.length; i++) {
File file = files[i];
try {