From c67f36cfee5532ff168d0b542409be86d570f3c9 Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sun, 3 Jan 2016 09:16:59 +0000 Subject: [PATCH] bug 58779: check if SlideShowFactory.create() modifies the file being read when the slideshow is closed. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1722707 13f79535-47bb-0310-9956-ffa450edef68 --- .../usermodel/TestXSLFSlideShowFactory.java | 22 ++++- .../org/apache/poi/POIDataSamples.java | 2 +- .../usermodel/BaseTestSlideShowFactory.java | 99 ++++++++++++++++--- 3 files changed, 108 insertions(+), 15 deletions(-) diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShowFactory.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShowFactory.java index 2c9492c983..9bfc695a8e 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShowFactory.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShowFactory.java @@ -33,14 +33,29 @@ import org.apache.poi.sl.usermodel.BaseTestSlideShowFactory; import org.apache.poi.util.IOUtils; import org.apache.poi.util.TempFile; import org.junit.Test; +import org.junit.Rule; +import org.junit.rules.ExpectedException; public final class TestXSLFSlideShowFactory extends BaseTestSlideShowFactory { private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); private static final String filename = "SampleShow.pptx"; private static final String password = "opensesame"; + private static final String removeExpectedExceptionMsg = + "This functionality this unit test is trying to test is now passing. " + + "The unit test needs to be updated by deleting the expected exception code. Status and close any related bugs."; + + @Rule + public ExpectedException thrown = ExpectedException.none(); @Test public void testFactoryFromFile() throws Exception { + // Remove thrown.* when bug 58779 is resolved + // In the mean time, this function will modify SampleShow.pptx on disk. + thrown.expect(AssertionError.class); + // thrown.expectCause(Matcher); + thrown.expectMessage("SampleShow.pptx sample file was modified as a result of closing the slideshow"); + thrown.reportMissingExceptionWithMessage("Bug 58779: " + removeExpectedExceptionMsg); + testFactoryFromFile(filename); } @@ -51,6 +66,11 @@ public final class TestXSLFSlideShowFactory extends BaseTestSlideShowFactory { @Test public void testFactoryFromNative() throws Exception { + // Remove thrown.* when unit test for XSLF SlideShowFactory.create(OPCPackage) is implemented + thrown.expect(UnsupportedOperationException.class); + thrown.expectMessage("Test not implemented"); + thrown.reportMissingExceptionWithMessage(removeExpectedExceptionMsg); + testFactoryFromNative(filename); } @@ -88,7 +108,7 @@ public final class TestXSLFSlideShowFactory extends BaseTestSlideShowFactory { os.close(); fis.close(); - File tf = TempFile.createTempFile("test-xslf-slidefactory", "pptx"); + File tf = TempFile.createTempFile("test-xslf-slidefactory", ".pptx"); FileOutputStream fos = new FileOutputStream(tf); fs.writeFilesystem(fos); fos.close(); diff --git a/src/testcases/org/apache/poi/POIDataSamples.java b/src/testcases/org/apache/poi/POIDataSamples.java index c0376e7676..ef9da4767f 100644 --- a/src/testcases/org/apache/poi/POIDataSamples.java +++ b/src/testcases/org/apache/poi/POIDataSamples.java @@ -255,7 +255,7 @@ public final class POIDataSamples { /** * @param fileName the file to open - * @return byte array of sample file content from file found in standard hssf test data dir + * @return byte array of sample file content from file found in standard test-data directory */ public byte[] readFile(String fileName) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); diff --git a/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java b/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java index a2998053b5..a6652fd048 100644 --- a/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java +++ b/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShowFactory.java @@ -17,25 +17,32 @@ package org.apache.poi.sl.usermodel; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.ByteArrayOutputStream; + import org.apache.poi.POIDataSamples; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; public class BaseTestSlideShowFactory { - private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); + private static final POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); + private static final POILogger LOGGER = POILogFactory.getLogger(BaseTestSlideShowFactory.class); protected static void testFactoryFromFile(String file) throws Exception { SlideShow ss; // from file ss = SlideShowFactory.create(fromFile(file)); assertNotNull(ss); - ss.close(); + assertCloseDoesNotModifyFile(file, ss); } protected static void testFactoryFromStream(String file) throws Exception { @@ -43,18 +50,26 @@ public class BaseTestSlideShowFactory { // from stream ss = SlideShowFactory.create(fromStream(file)); assertNotNull(ss); - ss.close(); + assertCloseDoesNotModifyFile(file, ss); } protected static void testFactoryFromNative(String file) throws Exception { SlideShow ss; // from NPOIFS - if (!file.contains("pptx")) { + if (file.endsWith(".ppt")) { NPOIFSFileSystem npoifs = new NPOIFSFileSystem(fromFile(file)); ss = SlideShowFactory.create(npoifs); assertNotNull(ss); npoifs.close(); - ss.close(); + assertCloseDoesNotModifyFile(file, ss); + } + // from OPCPackage + else if (file.endsWith(".pptx")) { + // not implemented + throw new UnsupportedOperationException("Test not implemented"); + } + else { + fail("Unexpected file extension: " + file); } } @@ -63,7 +78,7 @@ public class BaseTestSlideShowFactory { // from protected file ss = SlideShowFactory.create(fromFile(protectedFile), password); assertNotNull(ss); - ss.close(); + assertCloseDoesNotModifyFile(protectedFile, ss); } protected static void testFactoryFromProtectedStream(String protectedFile, String password) throws Exception { @@ -71,17 +86,25 @@ public class BaseTestSlideShowFactory { // from protected stream ss = SlideShowFactory.create(fromStream(protectedFile), password); assertNotNull(ss); - ss.close(); + assertCloseDoesNotModifyFile(protectedFile, ss); } protected static void testFactoryFromProtectedNative(String protectedFile, String password) throws Exception { SlideShow ss; + // Encryption layer is a BIFF8 binary format that can be read by NPOIFSFileSystem, + // used for both HSLF and XSLF + // from protected NPOIFS - NPOIFSFileSystem npoifs = new NPOIFSFileSystem(fromFile(protectedFile)); - ss = SlideShowFactory.create(npoifs, password); - assertNotNull(ss); - npoifs.close(); - ss.close(); + if (protectedFile.endsWith(".ppt") || protectedFile.endsWith(".pptx")) { + NPOIFSFileSystem npoifs = new NPOIFSFileSystem(fromFile(protectedFile)); + ss = SlideShowFactory.create(npoifs, password); + assertNotNull(ss); + npoifs.close(); + assertCloseDoesNotModifyFile(protectedFile, ss); + } + else { + fail("Unrecognized file extension: " + protectedFile); + } } public static void testFactory(String file, String protectedFile, String password) @@ -94,7 +117,57 @@ public class BaseTestSlideShowFactory { testFactoryFromProtectedStream(protectedFile, password); testFactoryFromProtectedNative(protectedFile, password); } - + + /** + * reads either a test-data file (filename) or a file outside the test-data folder (full path) + */ + private static byte[] readFile(String filename) { + byte[] bytes; + try { + bytes = _slTests.readFile(filename); + } catch (final Exception e) { + bytes = readExternalFile(filename); + } + return bytes; + } + + private static byte[] readExternalFile(String path) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try { + InputStream fis = new FileInputStream(path); + byte[] buf = new byte[512]; + while (true) { + int bytesRead = fis.read(buf); + if (bytesRead < 1) { + break; + } + baos.write(buf, 0, bytesRead); + } + fis.close(); + } catch (final IOException e) { + throw new RuntimeException(e); + } + final byte[] bytes = baos.toByteArray(); + return bytes; + } + + /** + * FIXME: + * bug 58779: Closing an XMLSlideShow that was created with {@link SlideShowFactory#create(File)} modifies the file + * + * @param filename the sample filename or full path of the slideshow to check before and after closing + * @param ss the slideshow to close or revert + * @throws IOException + */ + private static void assertCloseDoesNotModifyFile(String filename, SlideShow ss) throws IOException { + final byte[] before = readFile(filename); + ss.close(); + final byte[] after = readFile(filename); + assertArrayEquals(filename + " sample file was modified as a result of closing the slideshow", + before, after); + } + private static File fromFile(String file) { return (file.contains("/") || file.contains("\\")) ? new File(file)