You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2005/09/27 00:08:47 UTC
svn commit: r291765 - in /jakarta/commons/proper/io/trunk: RELEASE-NOTES.txt
project.xml src/java/org/apache/commons/io/FileUtils.java
src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java
src/test/org/apache/commons/io/PackageTestSuite.java
Author: scolebourne
Date: Mon Sep 26 15:08:40 2005
New Revision: 291765
URL: http://svn.apache.org/viewcvs?rev=291765&view=rev
Log:
Handle security restricted directories
bug 36801, from Chris Eldredge
Added:
jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java (with props)
Modified:
jakarta/commons/proper/io/trunk/RELEASE-NOTES.txt
jakarta/commons/proper/io/trunk/project.xml
jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java
jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/PackageTestSuite.java
Modified: jakarta/commons/proper/io/trunk/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/RELEASE-NOTES.txt?rev=291765&r1=291764&r2=291765&view=diff
==============================================================================
--- jakarta/commons/proper/io/trunk/RELEASE-NOTES.txt (original)
+++ jakarta/commons/proper/io/trunk/RELEASE-NOTES.txt Mon Sep 26 15:08:40 2005
@@ -21,7 +21,9 @@
Source compatible - ???
-Semantic compatible - ???
+Semantic compatible - Yes, except:
+- FileUtils.sizeOfDirectory()
+ May now return a size of 0 if the directory is security restricted
Deprecations from 1.0
@@ -57,6 +59,10 @@
- AbstractFileFilter - accept(File, String) [30992]
Fixed broken implementation
+
+- FileUtils [36801]
+ Previously threw NPE when listing files in a security restricted directory
+ Now throw IOException with a better message
Enhancements from 1.0
Modified: jakarta/commons/proper/io/trunk/project.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/project.xml?rev=291765&r1=291764&r2=291765&view=diff
==============================================================================
--- jakarta/commons/proper/io/trunk/project.xml (original)
+++ jakarta/commons/proper/io/trunk/project.xml Mon Sep 26 15:08:40 2005
@@ -172,6 +172,9 @@
<name>Nathan Beyer</name>
</contributor>
<contributor>
+ <name>Chris Eldredge</name>
+ </contributor>
+ <contributor>
<name>Marcelo Liberato</name>
</contributor>
<contributor>
Modified: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java?rev=291765&r1=291764&r2=291765&view=diff
==============================================================================
--- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java (original)
+++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java Mon Sep 26 15:08:40 2005
@@ -64,6 +64,7 @@
* @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
* @author Stephen Colebourne
* @author Ian Springer
+ * @autor Chris Eldredge
* @version $Id$
*/
public class FileUtils {
@@ -605,6 +606,9 @@
}
// recurse
File[] files = srcDir.listFiles();
+ if (files == null) { // null if security restricted
+ throw new IOException("Failed to list contents of " + srcDir);
+ }
for (int i = 0; i < files.length; i++) {
File copiedFile = new File(destDir, files[i].getName());
if (files[i].isDirectory()) {
@@ -686,8 +690,7 @@
* @param directory directory to clean
* @throws IOException in case cleaning is unsuccessful
*/
- public static void cleanDirectory(File directory)
- throws IOException {
+ public static void cleanDirectory(File directory) throws IOException {
if (!directory.exists()) {
String message = directory + " does not exist";
throw new IllegalArgumentException(message);
@@ -698,9 +701,12 @@
throw new IllegalArgumentException(message);
}
- IOException exception = null;
-
File[] files = directory.listFiles();
+ if (files == null) { // null if security restricted
+ throw new IOException("Failed to list contents of " + directory);
+ }
+
+ IOException exception = null;
for (int i = 0; i < files.length; i++) {
File file = files[i];
try {
@@ -929,8 +935,7 @@
* @param directory directory to clean.
* @throws IOException in case cleaning is unsuccessful
*/
- private static void cleanDirectoryOnExit(File directory)
- throws IOException {
+ private static void cleanDirectoryOnExit(File directory) throws IOException {
if (!directory.exists()) {
String message = directory + " does not exist";
throw new IllegalArgumentException(message);
@@ -941,9 +946,12 @@
throw new IllegalArgumentException(message);
}
- IOException exception = null;
-
File[] files = directory.listFiles();
+ if (files == null) { // null if security restricted
+ throw new IOException("Failed to list contents of " + directory);
+ }
+
+ IOException exception = null;
for (int i = 0; i < files.length; i++) {
File file = files[i];
try {
@@ -990,7 +998,7 @@
* Recursively count size of a directory (sum of the length of all files).
*
* @param directory directory to inspect
- * @return size of directory in bytes.
+ * @return size of directory in bytes, 0 if directory is security restricted
*/
public static long sizeOfDirectory(File directory) {
if (!directory.exists()) {
@@ -1006,6 +1014,9 @@
long size = 0;
File[] files = directory.listFiles();
+ if (files == null) { // null if security restricted
+ return 0L;
+ }
for (int i = 0; i < files.length; i++) {
File file = files[i];
Added: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java?rev=291765&view=auto
==============================================================================
--- jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java (added)
+++ jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java Mon Sep 26 15:08:40 2005
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2005 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.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.testtools.FileBasedTestCase;
+
+/**
+ * Test cases for FileUtils.cleanDirectory() method.
+ *
+ * @version $Id$
+ * @author Chris Eldredge
+ */
+public class FileUtilsCleanDirectoryTestCase extends FileBasedTestCase {
+ final File top = getLocalTestDirectory();
+
+ public static void main(String[] args) {
+ TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ return new TestSuite(FileUtilsCleanDirectoryTestCase.class);
+ }
+
+ public FileUtilsCleanDirectoryTestCase(String name) {
+ super(name);
+ }
+
+ private File getLocalTestDirectory() {
+ return new File(getTestDirectory(), "list-files");
+ }
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ top.mkdirs();
+ }
+
+ /**
+ * @see junit.framework.TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ chmod(top, 775, true);
+ FileUtils.deleteDirectory(top);
+ }
+
+ //-----------------------------------------------------------------------
+ public void testCleanEmpty() throws Exception {
+ assertEquals(0, top.list().length);
+
+ FileUtils.cleanDirectory(top);
+
+ assertEquals(0, top.list().length);
+ }
+
+ public void testDeletesRegular() throws Exception {
+ FileUtils.touch(new File(top, "regular"));
+ FileUtils.touch(new File(top, ".hidden"));
+
+ assertEquals(2, top.list().length);
+
+ FileUtils.cleanDirectory(top);
+
+ assertEquals(0, top.list().length);
+ }
+
+ public void testDeletesNested() throws Exception {
+ final File nested = new File(top, "nested");
+
+ assertTrue(nested.mkdirs());
+
+ FileUtils.touch(new File(nested, "file"));
+
+ assertEquals(1, top.list().length);
+
+ FileUtils.cleanDirectory(top);
+
+ assertEquals(0, top.list().length);
+ }
+
+ public void testThrowsOnNullList() throws Exception {
+ if (!chmod(top, 0, false)) {
+ // test wont work if we can't restrict permissions on the
+ // directory, so skip it.
+ return;
+ }
+
+ 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 the
+ // directory, so skip it.
+ return;
+ }
+
+ try {
+ FileUtils.cleanDirectory(top);
+ fail("expected IOException");
+ } catch (IOException e) {
+ assertEquals("Unable to delete file: " +
+ file.getAbsolutePath(), e.getMessage());
+ }
+ }
+
+ private boolean chmod(File file, int mode, boolean recurse)
+ throws IOException, InterruptedException {
+ // TODO: Refactor this to FileSystemUtils
+ List args = new ArrayList();
+ args.add("chmod");
+
+ if (recurse) {
+ args.add("-R");
+ }
+
+ args.add(Integer.toString(mode));
+ args.add(file.getAbsolutePath());
+
+ Process proc;
+
+ try {
+ proc = Runtime.getRuntime().exec(
+ (String[]) args.toArray(new String[args.size()]));
+ } catch (IOException e) {
+ return false;
+ }
+ int result = proc.waitFor();
+ assertEquals(0, result);
+ return true;
+ }
+
+}
Propchange: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileUtilsCleanDirectoryTestCase.java
------------------------------------------------------------------------------
svn:keywords = "author date id revision"
Modified: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/PackageTestSuite.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/PackageTestSuite.java?rev=291765&r1=291764&r2=291765&view=diff
==============================================================================
--- jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/PackageTestSuite.java (original)
+++ jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/PackageTestSuite.java Mon Sep 26 15:08:40 2005
@@ -44,6 +44,7 @@
suite.addTest(new TestSuite(FileSystemUtilsTestCase.class));
suite.addTest(new TestSuite(FileUtilsFileNewerTestCase.class));
suite.addTest(new TestSuite(FileUtilsListFilesTestCase.class));
+ suite.addTest(new TestSuite(FileUtilsCleanDirectoryTestCase.class));
suite.addTest(new TestSuite(FileUtilsTestCase.class));
suite.addTest(new TestSuite(FileFilterTestCase.class));
suite.addTest(new TestSuite(HexDumpTest.class));
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org