You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TestPOIFSFileSystem.java 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.poifs.filesystem;
  16. import java.io.ByteArrayOutputStream;
  17. import java.io.File;
  18. import java.io.FileInputStream;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import junit.framework.TestCase;
  22. import org.apache.poi.POIDataSamples;
  23. import org.apache.poi.hssf.HSSFTestDataSamples;
  24. import org.apache.poi.poifs.common.POIFSBigBlockSize;
  25. import org.apache.poi.poifs.storage.HeaderBlockReader;
  26. import org.apache.poi.poifs.storage.RawDataBlockList;
  27. /**
  28. * Tests for POIFSFileSystem
  29. *
  30. * @author Josh Micich
  31. */
  32. public final class TestPOIFSFileSystem extends TestCase {
  33. /**
  34. * Mock exception used to ensure correct error handling
  35. */
  36. private static final class MyEx extends RuntimeException {
  37. public MyEx() {
  38. // no fields to initialise
  39. }
  40. }
  41. /**
  42. * Helps facilitate testing. Keeps track of whether close() was called.
  43. * Also can throw an exception at a specific point in the stream.
  44. */
  45. private static final class TestIS extends InputStream {
  46. private final InputStream _is;
  47. private final int _failIndex;
  48. private int _currentIx;
  49. private boolean _isClosed;
  50. public TestIS(InputStream is, int failIndex) {
  51. _is = is;
  52. _failIndex = failIndex;
  53. _currentIx = 0;
  54. _isClosed = false;
  55. }
  56. public int read() throws IOException {
  57. int result = _is.read();
  58. if(result >=0) {
  59. checkRead(1);
  60. }
  61. return result;
  62. }
  63. public int read(byte[] b, int off, int len) throws IOException {
  64. int result = _is.read(b, off, len);
  65. checkRead(result);
  66. return result;
  67. }
  68. private void checkRead(int nBytes) {
  69. _currentIx += nBytes;
  70. if(_failIndex > 0 && _currentIx > _failIndex) {
  71. throw new MyEx();
  72. }
  73. }
  74. public void close() throws IOException {
  75. _isClosed = true;
  76. _is.close();
  77. }
  78. public boolean isClosed() {
  79. return _isClosed;
  80. }
  81. }
  82. /**
  83. * Test for undesired behaviour observable as of svn revision 618865 (5-Feb-2008).
  84. * POIFSFileSystem was not closing the input stream.
  85. */
  86. public void testAlwaysClose() {
  87. TestIS testIS;
  88. // Normal case - read until EOF and close
  89. testIS = new TestIS(openSampleStream("13224.xls"), -1);
  90. try {
  91. new POIFSFileSystem(testIS);
  92. } catch (IOException e) {
  93. throw new RuntimeException(e);
  94. }
  95. assertTrue("input stream was not closed", testIS.isClosed());
  96. // intended to crash after reading 10000 bytes
  97. testIS = new TestIS(openSampleStream("13224.xls"), 10000);
  98. try {
  99. new POIFSFileSystem(testIS);
  100. fail("ex should have been thrown");
  101. } catch (IOException e) {
  102. throw new RuntimeException(e);
  103. } catch (MyEx e) {
  104. // expected
  105. }
  106. assertTrue("input stream was not closed", testIS.isClosed()); // but still should close
  107. }
  108. /**
  109. * Test for bug # 48898 - problem opening an OLE2
  110. * file where the last block is short (i.e. not a full
  111. * multiple of 512 bytes)
  112. *
  113. * As yet, this problem remains. One school of thought is
  114. * not not issue an EOF when we discover the last block
  115. * is short, but this seems a bit wrong.
  116. * The other is to fix the handling of the last block in
  117. * POIFS, since it seems to be slight wrong
  118. */
  119. public void testShortLastBlock() throws Exception {
  120. String[] files = new String[] {
  121. "ShortLastBlock.qwp", "ShortLastBlock.wps"
  122. };
  123. POIDataSamples _samples = POIDataSamples.getPOIFSInstance();
  124. for(int i=0; i<files.length; i++) {
  125. // Open the file up
  126. POIFSFileSystem fs = new POIFSFileSystem(
  127. _samples.openResourceAsStream(files[i])
  128. );
  129. // Write it into a temp output array
  130. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  131. fs.writeFilesystem(baos);
  132. // Check sizes
  133. }
  134. }
  135. /**
  136. * Check that we do the right thing when the list of which
  137. * sectors are BAT blocks points off the list of
  138. * sectors that exist in the file.
  139. */
  140. public void testFATandDIFATsectors() throws Exception {
  141. POIDataSamples _samples = POIDataSamples.getPOIFSInstance();
  142. // Open the file up
  143. try {
  144. POIFSFileSystem fs = new POIFSFileSystem(
  145. _samples.openResourceAsStream("ReferencesInvalidSectors.mpp")
  146. );
  147. fail("File is corrupt and shouldn't have been opened");
  148. } catch(IOException e) {
  149. String msg = e.getMessage();
  150. assertTrue(msg.startsWith("Your file contains 695 sectors"));
  151. }
  152. }
  153. /**
  154. * Most OLE2 files use 512byte blocks. However, a small number
  155. * use 4k blocks. Check that we can open these.
  156. * DISABLED until we get a sample 4k block file that's under 22mb...
  157. */
  158. public void test4KBlocks() throws Exception {
  159. POIDataSamples _samples = POIDataSamples.getPOIFSInstance();
  160. InputStream inp = _samples.openResourceAsStream("BlockSize4096.zvi");
  161. // First up, check that we can process the header properly
  162. HeaderBlockReader header_block_reader = new HeaderBlockReader(inp);
  163. POIFSBigBlockSize bigBlockSize = header_block_reader.getBigBlockSize();
  164. assertEquals(4096, bigBlockSize.getBigBlockSize());
  165. // Check the fat info looks sane
  166. assertEquals(109, header_block_reader.getBATArray().length);
  167. assertTrue(header_block_reader.getBATCount() > 0);
  168. assertEquals(0, header_block_reader.getXBATCount());
  169. // Now check we can get the basic fat
  170. RawDataBlockList data_blocks = new RawDataBlockList(inp, bigBlockSize);
  171. // Now try and open properly
  172. POIFSFileSystem fs = new POIFSFileSystem(
  173. _samples.openResourceAsStream("BlockSize4096.zvi")
  174. );
  175. assertTrue(fs.getRoot().getEntryCount() > 3);
  176. // Finally, check we can do a similar 512byte one too
  177. fs = new POIFSFileSystem(
  178. _samples.openResourceAsStream("BlockSize512.zvi")
  179. );
  180. assertTrue(fs.getRoot().getEntryCount() > 3);
  181. }
  182. private static InputStream openSampleStream(String sampleFileName) {
  183. return HSSFTestDataSamples.openSampleFileStream(sampleFileName);
  184. }
  185. }