When deserializing DiskFileItems ensure that the repository location, if any, is a valid one.
Patch provided by Arun Babu Neelicattu.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/fileupload/trunk@1507048 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index f653b9b..974f97f 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -43,6 +43,13 @@
</properties>
<body>
+ <release version="1.3.1" description="maintenance release" date="TBD">
+ <action dev="markt" type="fix" due-to="Arun Babu Neelicattu" due-to-email="abn@redhat.com">
+ When deserializing DiskFileItems ensure that the repository location, if
+ any, is a valid one.
+ </action>
+ </release>
+
<release version="1.3" description="maintenance release, JDK1.5 update" date="2013-03-27">
<!-- important notes -->
<action dev="markt" type="fix">
diff --git a/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java b/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java
index 613c863..55c7daa 100644
--- a/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java
+++ b/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java
@@ -656,6 +656,26 @@
// read values
in.defaultReadObject();
+ /* One expected use of serialization is to migrate HTTP sessions
+ * containing a DiskFileItem between JVMs. Particularly if the JVMs are
+ * on different machines It is possible that the repository location is
+ * not valid so validate it.
+ */
+ if (repository != null) {
+ if (repository.isDirectory()) {
+ // Check path for nulls
+ if (repository.getPath().contains("\0")) {
+ throw new IOException(format(
+ "The repository [%s] contains a null character",
+ repository.getPath()));
+ }
+ } else {
+ throw new IOException(format(
+ "The repository [%s] is not a directory",
+ repository.getAbsolutePath()));
+ }
+ }
+
OutputStream output = getOutputStream();
if (cachedContent != null) {
output.write(cachedContent);
diff --git a/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.java b/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.java
index 8a77fd6..e823f74 100644
--- a/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.java
+++ b/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.java
@@ -24,6 +24,7 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -51,14 +52,10 @@
private static final int threshold = 16;
/**
- * Test creation of a field for which the amount of data falls below the
- * configured threshold.
+ * Helper method to test creation of a field when a repository is used.
*/
- @Test
- public void testBelowThreshold() throws Exception {
- // Create the FileItem
- byte[] testFieldValueBytes = createContentBytes(threshold - 1);
- FileItem item = createFileItem(testFieldValueBytes);
+ public void testInMemoryObject(byte[] testFieldValueBytes, File repository) {
+ FileItem item = createFileItem(testFieldValueBytes, repository);
// Check state is as expected
assertTrue("Initial: in memory", item.isInMemory());
@@ -75,6 +72,24 @@
// Compare FileItem's (except byte[])
compareFileItems(item, newItem);
}
+
+ /**
+ * Helper method to test creation of a field.
+ */
+ private void testInMemoryObject(byte[] testFieldValueBytes) {
+ testInMemoryObject(testFieldValueBytes, null);
+ }
+
+ /**
+ * Test creation of a field for which the amount of data falls below the
+ * configured threshold.
+ */
+ @Test
+ public void testBelowThreshold() throws Exception {
+ // Create the FileItem
+ byte[] testFieldValueBytes = createContentBytes(threshold - 1);
+ testInMemoryObject(testFieldValueBytes);
+ }
/**
* Test creation of a field for which the amount of data equals the
@@ -84,23 +99,7 @@
public void testThreshold() throws Exception {
// Create the FileItem
byte[] testFieldValueBytes = createContentBytes(threshold);
- FileItem item = createFileItem(testFieldValueBytes);
-
- // Check state is as expected
- assertTrue("Initial: in memory", item.isInMemory());
- assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
- compareBytes("Initial", item.get(), testFieldValueBytes);
-
-
- // Serialize & Deserialize
- FileItem newItem = (FileItem)serializeDeserialize(item);
-
- // Test deserialized content is as expected
- assertTrue("Check in memory", newItem.isInMemory());
- compareBytes("Check", testFieldValueBytes, newItem.get());
-
- // Compare FileItem's (except byte[])
- compareFileItems(item, newItem);
+ testInMemoryObject(testFieldValueBytes);
}
/**
@@ -128,6 +127,41 @@
// Compare FileItem's (except byte[])
compareFileItems(item, newItem);
}
+
+ /**
+ * Test serialization and deserialization when repository is not null.
+ */
+ @Test
+ public void testValidRepository() throws Exception {
+ // Create the FileItem
+ byte[] testFieldValueBytes = createContentBytes(threshold);
+ File repository = new File(System.getProperty("java.io.tmpdir"));
+ testInMemoryObject(testFieldValueBytes, repository);
+ }
+
+ /**
+ * Test deserialization fails when repository is not valid.
+ */
+ @Test(expected=IOException.class)
+ public void testInvalidRepository() throws Exception {
+ // Create the FileItem
+ byte[] testFieldValueBytes = createContentBytes(threshold);
+ File repository = new File(System.getProperty("java.io.tmpdir") + "file");
+ FileItem item = createFileItem(testFieldValueBytes, repository);
+ deserialize(serialize(item));
+ }
+
+ /**
+ * Test deserialization fails when repository contains a null character.
+ */
+ @Test(expected=IOException.class)
+ public void testInvalidRepositoryWithNullChar() throws Exception {
+ // Create the FileItem
+ byte[] testFieldValueBytes = createContentBytes(threshold);
+ File repository = new File(System.getProperty("java.io.tmpdir") + "\0");
+ FileItem item = createFileItem(testFieldValueBytes, repository);
+ deserialize(serialize(item));
+ }
/**
* Compare FileItem's (except the byte[] content)
@@ -169,10 +203,10 @@
}
/**
- * Create a FileItem with the specfied content bytes.
+ * Create a FileItem with the specfied content bytes and repository.
*/
- private FileItem createFileItem(byte[] contentBytes) {
- FileItemFactory factory = new DiskFileItemFactory(threshold, null);
+ private FileItem createFileItem(byte[] contentBytes, File repository) {
+ FileItemFactory factory = new DiskFileItemFactory(threshold, repository);
String textFieldName = "textField";
FileItem item = factory.createItem(
@@ -192,33 +226,60 @@
return item;
}
+
+ /**
+ * Create a FileItem with the specfied content bytes.
+ */
+ private FileItem createFileItem(byte[] contentBytes) {
+ return createFileItem(contentBytes, null);
+ }
+
+ /**
+ * Do serialization
+ */
+ private ByteArrayOutputStream serialize(Object target) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(target);
+ oos.flush();
+ oos.close();
+ return baos;
+ }
+
+ /**
+ * Do deserialization
+ */
+ private Object deserialize(ByteArrayOutputStream baos) throws Exception {
+ Object result = null;
+ ByteArrayInputStream bais =
+ new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ result = ois.readObject();
+ bais.close();
+ return result;
+ }
+
/**
* Do serialization and deserialization.
*/
private Object serializeDeserialize(Object target) {
// Serialize the test object
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ByteArrayOutputStream baos = null;
try {
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(target);
- oos.flush();
- oos.close();
+ baos = serialize(target);
} catch (Exception e) {
fail("Exception during serialization: " + e);
}
-
+
// Deserialize the test object
Object result = null;
try {
- ByteArrayInputStream bais =
- new ByteArrayInputStream(baos.toByteArray());
- ObjectInputStream ois = new ObjectInputStream(bais);
- result = ois.readObject();
- bais.close();
+ result = deserialize(baos);
} catch (Exception e) {
fail("Exception during deserialization: " + e);
}
+
return result;
}