您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

TestFileMagic.java 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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 static org.junit.Assert.assertEquals;
  17. import static org.junit.Assert.assertFalse;
  18. import static org.junit.Assert.assertNotNull;
  19. import static org.junit.Assert.assertNotSame;
  20. import static org.junit.Assert.assertSame;
  21. import static org.junit.Assert.assertTrue;
  22. import static org.junit.Assert.fail;
  23. import java.io.BufferedInputStream;
  24. import java.io.File;
  25. import java.io.FileInputStream;
  26. import java.io.FileOutputStream;
  27. import java.io.IOException;
  28. import java.io.InputStream;
  29. import java.nio.charset.StandardCharsets;
  30. import java.util.Arrays;
  31. import java.util.Random;
  32. import org.apache.poi.POIDataSamples;
  33. import org.apache.poi.util.TempFile;
  34. import org.junit.Test;
  35. public class TestFileMagic {
  36. @Test
  37. public void testFileMagic() {
  38. assertEquals(FileMagic.XML, FileMagic.valueOf("XML"));
  39. assertEquals(FileMagic.XML, FileMagic.valueOf("<?xml".getBytes(StandardCharsets.UTF_8)));
  40. assertEquals(FileMagic.HTML, FileMagic.valueOf("HTML"));
  41. assertEquals(FileMagic.HTML, FileMagic.valueOf("<!DOCTYP".getBytes(StandardCharsets.UTF_8)));
  42. assertEquals(FileMagic.HTML, FileMagic.valueOf("<!DOCTYPE".getBytes(StandardCharsets.UTF_8)));
  43. assertEquals(FileMagic.HTML, FileMagic.valueOf("<html".getBytes(StandardCharsets.UTF_8)));
  44. assertEquals(FileMagic.HTML, FileMagic.valueOf("\n\r<html".getBytes(StandardCharsets.UTF_8)));
  45. assertEquals(FileMagic.HTML, FileMagic.valueOf("\n<html".getBytes(StandardCharsets.UTF_8)));
  46. assertEquals(FileMagic.HTML, FileMagic.valueOf("\r\n<html".getBytes(StandardCharsets.UTF_8)));
  47. assertEquals(FileMagic.HTML, FileMagic.valueOf("\r<html".getBytes(StandardCharsets.UTF_8)));
  48. assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xDB }));
  49. assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xE0, 'a', 'b', 'J', 'F', 'I', 'F', 0x00, 0x01 }));
  50. assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xEE }));
  51. assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xE1, 'd', 'c', 'E', 'x', 'i', 'f', 0x00, 0x00 }));
  52. assertEquals(FileMagic.UNKNOWN, FileMagic.valueOf("something".getBytes(StandardCharsets.UTF_8)));
  53. assertEquals(FileMagic.UNKNOWN, FileMagic.valueOf(new byte[0]));
  54. try {
  55. FileMagic.valueOf("some string");
  56. fail("Should catch exception here");
  57. } catch (IllegalArgumentException e) {
  58. // expected here
  59. }
  60. }
  61. @Test
  62. public void testFileMagicFile() throws IOException {
  63. assertEquals(FileMagic.OLE2, FileMagic.valueOf(POIDataSamples.getSpreadSheetInstance().getFile("SampleSS.xls")));
  64. assertEquals(FileMagic.OOXML, FileMagic.valueOf(POIDataSamples.getSpreadSheetInstance().getFile("SampleSS.xlsx")));
  65. }
  66. @Test
  67. public void testFileMagicStream() throws IOException {
  68. try (InputStream stream = new BufferedInputStream(new FileInputStream(POIDataSamples.getSpreadSheetInstance().getFile("SampleSS.xls")))) {
  69. assertEquals(FileMagic.OLE2, FileMagic.valueOf(stream));
  70. }
  71. try (InputStream stream = new BufferedInputStream(new FileInputStream(POIDataSamples.getSpreadSheetInstance().getFile("SampleSS.xlsx")))) {
  72. assertEquals(FileMagic.OOXML, FileMagic.valueOf(stream));
  73. }
  74. }
  75. @Test
  76. public void testPrepare() throws IOException {
  77. try (InputStream stream = new BufferedInputStream(new FileInputStream(POIDataSamples.getSpreadSheetInstance().getFile("SampleSS.xlsx")))) {
  78. assertSame(stream, FileMagic.prepareToCheckMagic(stream));
  79. }
  80. try (InputStream stream = new InputStream() {
  81. @Override
  82. public int read() {
  83. return 0;
  84. }
  85. }) {
  86. assertNotSame(stream, FileMagic.prepareToCheckMagic(stream));
  87. }
  88. }
  89. @Test
  90. public void testMatchingButTooLessData() {
  91. // this matches JPG, but is not long enough, previously this caused an Exception
  92. byte[] data = new byte[] { -1, -40, -1, -32, 0, 16, 74, 70 };
  93. assertEquals(FileMagic.UNKNOWN, FileMagic.valueOf(data));
  94. }
  95. @Test
  96. public void testShortFile() throws IOException {
  97. // having a file shorter than 8 bytes previously caused an exception
  98. fetchMagicFromData(new byte[] { -1, -40, -1, -32, 0 });
  99. fetchMagicFromData(new byte[] { -1, -40, -1, -32 });
  100. fetchMagicFromData(new byte[] { -1, -40, -1 });
  101. fetchMagicFromData(new byte[] { -1, -40 });
  102. fetchMagicFromData(new byte[] { -1 });
  103. fetchMagicFromData(new byte[0]);
  104. }
  105. private void fetchMagicFromData(byte[] data) throws IOException {
  106. File file = TempFile.createTempFile("TestFileMagic", ".bin");
  107. try {
  108. try (FileOutputStream fos = new FileOutputStream(file)) {
  109. fos.write(data);
  110. }
  111. assertEquals(FileMagic.UNKNOWN, FileMagic.valueOf(file));
  112. } finally {
  113. assertTrue(file.delete());
  114. }
  115. }
  116. @Test(expected = IOException.class)
  117. public void testMarkRequired() throws IOException {
  118. byte[] data = new byte[] { -1, -40, -1, -32, 0 };
  119. File file = TempFile.createTempFile("TestFileMagic", ".bin");
  120. try {
  121. try (FileOutputStream fos = new FileOutputStream(file)) {
  122. fos.write(data);
  123. }
  124. // a FileInputStream does not support "marking"
  125. try (FileInputStream str = new FileInputStream(file)) {
  126. assertFalse(str.markSupported());
  127. FileMagic.valueOf(str);
  128. }
  129. } finally {
  130. assertTrue(file.delete());
  131. }
  132. }
  133. @Test
  134. public void testPatterns() {
  135. // just try to trash the functionality with some byte-patterns
  136. for(int i = 0; i < 256;i++) {
  137. final byte[] data = new byte[12];
  138. for(int j = 0;j < 12; j++) {
  139. data[j] = (byte)i;
  140. assertEquals(FileMagic.UNKNOWN, FileMagic.valueOf(data));
  141. }
  142. }
  143. }
  144. @Test
  145. public void testRandomPatterns() {
  146. Random random = new Random();
  147. // just try to trash the functionality with some byte-patterns
  148. for(int i = 0; i < 1000;i++) {
  149. final byte[] data = new byte[12];
  150. random.nextBytes(data);
  151. // we cannot check for UNKNOWN as we might hit valid byte-patterns here as well
  152. try {
  153. assertNotNull(FileMagic.valueOf(data));
  154. } catch (Exception e) {
  155. throw new IllegalStateException("Failed with pattern " + Arrays.toString(data), e);
  156. }
  157. }
  158. }
  159. }