Author: markt Date: Thu Jul 25 16:16:15 2013 New Revision: 1507048 URL: http://svn.apache.org/r1507048 Log: When deserializing DiskFileItems ensure that the repository location, if any, is a valid one. Patch provided by Arun Babu Neelicattu.
Modified: commons/proper/fileupload/trunk/src/changes/changes.xml commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java commons/proper/fileupload/trunk/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.java Modified: commons/proper/fileupload/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/fileupload/trunk/src/changes/changes.xml?rev=1507048&r1=1507047&r2=1507048&view=diff ============================================================================== --- commons/proper/fileupload/trunk/src/changes/changes.xml (original) +++ commons/proper/fileupload/trunk/src/changes/changes.xml Thu Jul 25 16:16:15 2013 @@ -43,6 +43,13 @@ The <action> type attribute can be add,u </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="a...@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"> Modified: commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java URL: http://svn.apache.org/viewvc/commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java?rev=1507048&r1=1507047&r2=1507048&view=diff ============================================================================== --- commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java (original) +++ commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java Thu Jul 25 16:16:15 2013 @@ -656,6 +656,26 @@ public class DiskFileItem // 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); Modified: commons/proper/fileupload/trunk/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.java URL: http://svn.apache.org/viewvc/commons/proper/fileupload/trunk/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.java?rev=1507048&r1=1507047&r2=1507048&view=diff ============================================================================== --- commons/proper/fileupload/trunk/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.java (original) +++ commons/proper/fileupload/trunk/src/test/java/org/apache/commons/fileupload/DiskFileItemSerializeTest.java Thu Jul 25 16:16:15 2013 @@ -24,6 +24,7 @@ import static org.junit.Assert.fail; 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 @@ public class DiskFileItemSerializeTest { 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 @@ public class DiskFileItemSerializeTest { // 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 class DiskFileItemSerializeTest { 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 @@ public class DiskFileItemSerializeTest { // 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 @@ public class DiskFileItemSerializeTest { } /** - * 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 @@ public class DiskFileItemSerializeTest { 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; }