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.

TestHwmfParsing.java 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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.hwmf;
  16. import static org.apache.poi.POITestCase.assertContains;
  17. import static org.junit.jupiter.api.Assertions.assertEquals;
  18. import static org.junit.jupiter.api.Assertions.assertThrows;
  19. import java.io.File;
  20. import java.io.FileInputStream;
  21. import java.io.IOException;
  22. import java.io.InputStream;
  23. import java.nio.charset.Charset;
  24. import java.nio.charset.StandardCharsets;
  25. import java.util.List;
  26. import org.apache.poi.POIDataSamples;
  27. import org.apache.poi.hwmf.record.HwmfFont;
  28. import org.apache.poi.hwmf.record.HwmfRecord;
  29. import org.apache.poi.hwmf.record.HwmfRecordType;
  30. import org.apache.poi.hwmf.record.HwmfText;
  31. import org.apache.poi.hwmf.usermodel.HwmfPicture;
  32. import org.apache.poi.util.LocaleUtil;
  33. import org.apache.poi.util.RecordFormatException;
  34. import org.junit.jupiter.api.Disabled;
  35. import org.junit.jupiter.api.Test;
  36. import org.junit.jupiter.params.ParameterizedTest;
  37. import org.junit.jupiter.params.provider.CsvSource;
  38. public class TestHwmfParsing {
  39. private static final POIDataSamples samples = POIDataSamples.getSlideShowInstance();
  40. // ******************************************************************************
  41. // for manual mass parsing and rendering tests of .wmfs use HemfPictureTest.paint() !
  42. // ******************************************************************************
  43. @ParameterizedTest
  44. @CsvSource({
  45. "santa.wmf, 581",
  46. /* Bug 65063 */
  47. "empty-polygon-close.wmf, 272"
  48. })
  49. public void parse(String file, int recordCnt) throws IOException {
  50. try (InputStream fis = samples.openResourceAsStream(file)) {
  51. HwmfPicture wmf = new HwmfPicture(fis);
  52. List<HwmfRecord> records = wmf.getRecords();
  53. assertEquals(recordCnt, records.size());
  54. }
  55. }
  56. @Test
  57. public void testInfiniteLoop() throws Exception {
  58. try (InputStream is = samples.openResourceAsStream("61338.wmf")) {
  59. assertThrows(RecordFormatException.class, () -> new HwmfPicture(is));
  60. }
  61. }
  62. @Test
  63. @Disabled("If we decide we can use common crawl file specified, we can turn this back on")
  64. public void testCyrillic() throws Exception {
  65. //TODO: move test file to framework and fix this
  66. File dir = new File("C:/somethingOrOther");
  67. File f = new File(dir, "ZMLH54SPLI76NQ7XMKVB7SMUJA2HTXTS-2.wmf");
  68. HwmfPicture wmf = new HwmfPicture(new FileInputStream(f));
  69. Charset charset = LocaleUtil.CHARSET_1252;
  70. StringBuilder sb = new StringBuilder();
  71. //this is pure hackery for specifying the font
  72. //this happens to work on this test file, but you need to
  73. //do what Graphics does by maintaining the stack, etc.!
  74. for (HwmfRecord r : wmf.getRecords()) {
  75. if (r.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) {
  76. HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont();
  77. charset = (font.getCharset().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharset().getCharset();
  78. }
  79. if (r.getWmfRecordType().equals(HwmfRecordType.extTextOut)) {
  80. HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r;
  81. sb.append(textOut.getText(charset)).append("\n");
  82. }
  83. }
  84. String txt = sb.toString();
  85. assertContains(txt, "\u041E\u0431\u0449\u043E");
  86. assertContains(txt, "\u0411\u0430\u043B\u0430\u043D\u0441");
  87. }
  88. @Test
  89. public void testShift_JIS() throws Exception {
  90. //this file derives from common crawl: see Bug 60677
  91. HwmfPicture wmf = null;
  92. try (InputStream fis = samples.openResourceAsStream("60677.wmf")) {
  93. wmf = new HwmfPicture(fis);
  94. }
  95. Charset charset = LocaleUtil.CHARSET_1252;
  96. StringBuilder sb = new StringBuilder();
  97. //this is pure hackery for specifying the font
  98. //this happens to work on this test file, but you need to
  99. //do what Graphics does by maintaining the stack, etc.!
  100. for (HwmfRecord r : wmf.getRecords()) {
  101. if (r.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) {
  102. HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont();
  103. charset = (font.getCharset().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharset().getCharset();
  104. }
  105. if (r.getWmfRecordType().equals(HwmfRecordType.extTextOut)) {
  106. HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r;
  107. sb.append(textOut.getText(charset)).append("\n");
  108. }
  109. }
  110. String txt = sb.toString();
  111. assertContains(txt, "\u822A\u7A7A\u60C5\u5831\u696D\u52D9\u3078\u306E\uFF27\uFF29\uFF33");
  112. }
  113. @Test
  114. public void testLengths() throws Exception {
  115. //both substring and length rely on char, not codepoints.
  116. //This test confirms that the substring calls in HwmfText
  117. //will not truncate even beyond-bmp data.
  118. //The last character (Deseret AY U+1040C) is comprised of 2 utf16 surrogates/codepoints
  119. String s = "\u666E\u6797\u65AF\uD801\uDC0C";
  120. Charset utf16LE = StandardCharsets.UTF_16LE;
  121. byte[] bytes = s.getBytes(utf16LE);
  122. String rebuilt = new String(bytes, utf16LE);
  123. rebuilt = rebuilt.substring(0, Math.min(bytes.length, rebuilt.length()));
  124. assertEquals(s, rebuilt);
  125. assertEquals(5, rebuilt.length());
  126. long cnt = rebuilt.codePoints().count();
  127. assertEquals(4, cnt);
  128. }
  129. }