123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You 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.poi.openxml4j.opc;
-
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertFalse;
- import static org.junit.Assert.assertNotNull;
- import static org.junit.Assert.assertTrue;
- import static org.junit.Assert.fail;
-
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- import java.io.UnsupportedEncodingException;
-
- import org.apache.poi.POIDataSamples;
- import org.apache.poi.POITextExtractor;
- import org.apache.poi.POIXMLException;
- import org.apache.poi.extractor.ExtractorFactory;
- import org.apache.poi.hssf.HSSFTestDataSamples;
- import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
- import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
- import org.apache.poi.openxml4j.exceptions.ODFNotOfficeXmlFileException;
- import org.apache.poi.sl.usermodel.SlideShow;
- import org.apache.poi.sl.usermodel.SlideShowFactory;
- import org.apache.poi.ss.usermodel.Workbook;
- import org.apache.poi.ss.usermodel.WorkbookFactory;
- import org.apache.poi.xssf.XSSFTestDataSamples;
- import org.apache.poi.xwpf.usermodel.XWPFRelation;
- import org.apache.xmlbeans.XmlException;
- import org.junit.Test;
-
- public class TestZipPackage {
- @Test
- public void testBug56479() throws Exception {
- InputStream is = OpenXML4JTestDataSamples.openSampleStream("dcterms_bug_56479.zip");
- OPCPackage p = OPCPackage.open(is);
-
- // Check we found the contents of it
- boolean foundCoreProps = false, foundDocument = false, foundTheme1 = false;
- for (PackagePart part : p.getParts()) {
- if (part.getPartName().toString().equals("/docProps/core.xml")) {
- assertEquals(ContentTypes.CORE_PROPERTIES_PART, part.getContentType());
- foundCoreProps = true;
- }
- if (part.getPartName().toString().equals("/word/document.xml")) {
- assertEquals(XWPFRelation.DOCUMENT.getContentType(), part.getContentType());
- foundDocument = true;
- }
- if (part.getPartName().toString().equals("/word/theme/theme1.xml")) {
- assertEquals(XWPFRelation.THEME.getContentType(), part.getContentType());
- foundTheme1 = true;
- }
- }
- assertTrue("Core not found in " + p.getParts(), foundCoreProps);
- assertFalse("Document should not be found in " + p.getParts(), foundDocument);
- assertFalse("Theme1 should not found in " + p.getParts(), foundTheme1);
- p.close();
- is.close();
- }
-
- @Test
- public void testZipEntityExpansionTerminates() throws IOException {
- try {
- Workbook wb = XSSFTestDataSamples.openSampleWorkbook("poc-xmlbomb.xlsx");
- wb.close();
- fail("Should catch exception due to entity expansion limitations");
- } catch (POIXMLException e) {
- assertEntityLimitReached(e);
- }
- }
-
- private void assertEntityLimitReached(Exception e) throws UnsupportedEncodingException {
- ByteArrayOutputStream str = new ByteArrayOutputStream();
- PrintWriter writer = new PrintWriter(new OutputStreamWriter(str, "UTF-8"));
- try {
- e.printStackTrace(writer);
- } finally {
- writer.close();
- }
- String string = new String(str.toByteArray(), "UTF-8");
- assertTrue("Had: " + string, string.contains("The parser has encountered more than"));
- }
-
- @Test
- public void testZipEntityExpansionExceedsMemory() throws Exception {
- try {
- Workbook wb = WorkbookFactory.create(XSSFTestDataSamples.openSamplePackage("poc-xmlbomb.xlsx"));
- wb.close();
- fail("Should catch exception due to entity expansion limitations");
- } catch (POIXMLException e) {
- assertEntityLimitReached(e);
- }
-
- try {
- POITextExtractor extractor = ExtractorFactory.createExtractor(HSSFTestDataSamples.getSampleFile("poc-xmlbomb.xlsx"));
- try {
- assertNotNull(extractor);
-
- try {
- extractor.getText();
- } catch (IllegalStateException e) {
- // expected due to shared strings expansion
- }
- } finally {
- extractor.close();
- }
- } catch (POIXMLException e) {
- assertEntityLimitReached(e);
- }
- }
-
- @Test
- public void testZipEntityExpansionSharedStringTable() throws Exception {
- Workbook wb = WorkbookFactory.create(XSSFTestDataSamples.openSamplePackage("poc-shared-strings.xlsx"));
- wb.close();
-
- POITextExtractor extractor = ExtractorFactory.createExtractor(HSSFTestDataSamples.getSampleFile("poc-shared-strings.xlsx"));
- try {
- assertNotNull(extractor);
-
- try {
- extractor.getText();
- } catch (IllegalStateException e) {
- // expected due to shared strings expansion
- }
- } finally {
- extractor.close();
- }
- }
-
- @Test
- public void testZipEntityExpansionSharedStringTableEvents() throws Exception {
- boolean before = ExtractorFactory.getThreadPrefersEventExtractors();
- ExtractorFactory.setThreadPrefersEventExtractors(true);
- try {
- POITextExtractor extractor = ExtractorFactory.createExtractor(HSSFTestDataSamples.getSampleFile("poc-shared-strings.xlsx"));
- try {
- assertNotNull(extractor);
-
- try {
- extractor.getText();
- } catch (IllegalStateException e) {
- // expected due to shared strings expansion
- }
- } finally {
- extractor.close();
- }
- } catch (XmlException e) {
- assertEntityLimitReached(e);
- } finally {
- ExtractorFactory.setThreadPrefersEventExtractors(before);
- }
- }
-
- @Test
- public void unparseableCentralDirectory() throws IOException {
- File f = OpenXML4JTestDataSamples.getSampleFile("at.pzp.www_uploads_media_PP_Scheinecker-jdk6error.pptx");
- SlideShow<?,?> ppt = SlideShowFactory.create(f, null, true);
- ppt.close();
- }
-
- @Test
- public void testClosingStreamOnException() throws IOException {
- InputStream is = OpenXML4JTestDataSamples.openSampleStream("dcterms_bug_56479.zip");
- File tmp = File.createTempFile("poi-test-truncated-zip", "");
- // create a corrupted zip file by truncating a valid zip file to the first 100 bytes
- OutputStream os = new FileOutputStream(tmp);
- for (int i = 0; i < 100; i++) {
- os.write(is.read());
- }
- os.flush();
- os.close();
- is.close();
-
- // feed the corrupted zip file to OPCPackage
- try {
- OPCPackage.open(tmp, PackageAccess.READ);
- } catch (Exception e) {
- // expected: the zip file is invalid
- // this test does not care if open() throws an exception or not.
- }
- // If the stream is not closed on exception, it will keep a file descriptor to tmp,
- // and requests to the OS to delete the file will fail.
- assertTrue("Can't delete tmp file", tmp.delete());
- }
-
- /**
- * If ZipPackage is passed an invalid file, a call to close
- * (eg from the OPCPackage open method) should tidy up the
- * stream / file the broken file is being read from.
- * See bug #60128 for more
- */
- @Test
- public void testTidyStreamOnInvalidFile() throws Exception {
- // Spreadsheet has a good mix of alternate file types
- POIDataSamples files = POIDataSamples.getSpreadSheetInstance();
-
- File[] notValidF = new File[] {
- files.getFile("SampleSS.ods"), files.getFile("SampleSS.txt")
- };
- InputStream[] notValidS = new InputStream[] {
- files.openResourceAsStream("SampleSS.ods"), files.openResourceAsStream("SampleSS.txt")
- };
-
- for (File notValid : notValidF) {
- ZipPackage pkg = new ZipPackage(notValid, PackageAccess.READ);
- assertNotNull(pkg.getZipArchive());
- assertFalse(pkg.getZipArchive().isClosed());
- try {
- pkg.getParts();
- fail("Shouldn't work");
- } catch (ODFNotOfficeXmlFileException e) {
- } catch (NotOfficeXmlFileException ne) {}
- pkg.close();
-
- assertNotNull(pkg.getZipArchive());
- assertTrue(pkg.getZipArchive().isClosed());
- }
- for (InputStream notValid : notValidS) {
- ZipPackage pkg = new ZipPackage(notValid, PackageAccess.READ);
- assertNotNull(pkg.getZipArchive());
- assertFalse(pkg.getZipArchive().isClosed());
- try {
- pkg.getParts();
- fail("Shouldn't work");
- } catch (ODFNotOfficeXmlFileException e) {
- } catch (NotOfficeXmlFileException ne) {}
- pkg.close();
-
- assertNotNull(pkg.getZipArchive());
- assertTrue(pkg.getZipArchive().isClosed());
- }
- }
- }
|