diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index a0816adfcf..1eebeb0d11 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 52385 - avoid trancated array and vector data when reading OLE properties 52662 - CharacterRun NPE fix when fetching symbol fonts, where no fonts are defined 52658 - support mergin table cells in XSLF validate row number and column index in SXSSF when creating new rows / cells diff --git a/src/java/org/apache/poi/hpsf/Property.java b/src/java/org/apache/poi/hpsf/Property.java index 90cc014082..026ff32260 100644 --- a/src/java/org/apache/poi/hpsf/Property.java +++ b/src/java/org/apache/poi/hpsf/Property.java @@ -414,9 +414,9 @@ public class Property b.append(getType()); final Object value = getValue(); b.append(", value: "); - b.append(value.toString()); if (value instanceof String) { + b.append(value.toString()); final String s = (String) value; final int l = s.length(); final byte[] bytes = new byte[l * 2]; @@ -428,11 +428,25 @@ public class Property bytes[i * 2] = high; bytes[i * 2 + 1] = low; } - final String hex = HexDump.dump(bytes, 0L, 0); b.append(" ["); - b.append(hex); + if(bytes.length > 0) { + final String hex = HexDump.dump(bytes, 0L, 0); + b.append(hex); + } b.append("]"); } + else if (value instanceof byte[]) + { + byte[] bytes = (byte[])value; + if(bytes.length > 0) { + String hex = HexDump.dump(bytes, 0L, 0); + b.append(hex); + } + } + else + { + b.append(value.toString()); + } b.append(']'); return b.toString(); } diff --git a/src/java/org/apache/poi/hpsf/TypedPropertyValue.java b/src/java/org/apache/poi/hpsf/TypedPropertyValue.java index 982139ba8a..43ac27aeba 100644 --- a/src/java/org/apache/poi/hpsf/TypedPropertyValue.java +++ b/src/java/org/apache/poi/hpsf/TypedPropertyValue.java @@ -68,7 +68,7 @@ class TypedPropertyValue + offset + " MUST be 0, but it's value is " + padding ); } - offset += readValuePadded( data, offset ); + offset += readValue( data, offset ); return offset - startOffset; } diff --git a/src/java/org/apache/poi/hpsf/Vector.java b/src/java/org/apache/poi/hpsf/Vector.java index 9cfa14310b..145a660cdb 100644 --- a/src/java/org/apache/poi/hpsf/Vector.java +++ b/src/java/org/apache/poi/hpsf/Vector.java @@ -16,6 +16,7 @@ ==================================================================== */ package org.apache.poi.hpsf; +import org.apache.poi.util.HexDump; import org.apache.poi.util.Internal; import org.apache.poi.util.LittleEndian; @@ -78,4 +79,7 @@ class Vector return offset - startOffset; } + TypedPropertyValue[] getValues(){ + return _values; + } } diff --git a/src/testcases/org/apache/poi/hpsf/TestVariantSupport.java b/src/testcases/org/apache/poi/hpsf/TestVariantSupport.java new file mode 100644 index 0000000000..963f657b96 --- /dev/null +++ b/src/testcases/org/apache/poi/hpsf/TestVariantSupport.java @@ -0,0 +1,88 @@ +/* + * ==================================================================== + * 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.hpsf; + +import junit.framework.TestCase; +import org.apache.poi.hpsf.wellknown.PropertyIDMap; +import org.apache.poi.util.HexRead; + +import java.io.ByteArrayInputStream; + +/** + * @author Yegor Kozlov + */ +public class TestVariantSupport extends TestCase { + + public void test52337() throws Exception { + // document summary stream from test1-excel.doc attached to Bugzilla 52337 + String hex = + "FE FF 00 00 05 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00" + + "00 00 00 00 02 00 00 00 02 D5 CD D5 9C 2E 1B 10 93 97 08 00" + + "2B 2C F9 AE 44 00 00 00 05 D5 CD D5 9C 2E 1B 10 93 97 08 00" + + "2B 2C F9 AE 58 01 00 00 14 01 00 00 0C 00 00 00 01 00 00 00" + + "68 00 00 00 0F 00 00 00 70 00 00 00 05 00 00 00 98 00 00 00" + + "06 00 00 00 A0 00 00 00 11 00 00 00 A8 00 00 00 17 00 00 00" + + "B0 00 00 00 0B 00 00 00 B8 00 00 00 10 00 00 00 C0 00 00 00" + + "13 00 00 00 C8 00 00 00 16 00 00 00 D0 00 00 00 0D 00 00 00" + + "D8 00 00 00 0C 00 00 00 F3 00 00 00 02 00 00 00 E4 04 00 00" + + "1E 00 00 00 20 00 00 00 44 65 70 61 72 74 6D 65 6E 74 20 6F" + + "66 20 49 6E 74 65 72 6E 61 6C 20 41 66 66 61 69 72 73 00 00" + + "03 00 00 00 05 00 00 00 03 00 00 00 01 00 00 00 03 00 00 00" + + "47 03 00 00 03 00 00 00 0F 27 0B 00 0B 00 00 00 00 00 00 00" + + "0B 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0B 00 00 00" + + "00 00 00 00 1E 10 00 00 01 00 00 00 0F 00 00 00 54 68 69 73" + + "20 69 73 20 61 20 74 65 73 74 00 0C 10 00 00 02 00 00 00 1E" + + "00 00 00 06 00 00 00 54 69 74 6C 65 00 03 00 00 00 01 00 00" + + "00 00 00 00 A8 00 00 00 03 00 00 00 00 00 00 00 20 00 00 00" + + "01 00 00 00 38 00 00 00 02 00 00 00 40 00 00 00 01 00 00 00" + + "02 00 00 00 0C 00 00 00 5F 50 49 44 5F 48 4C 49 4E 4B 53 00" + + "02 00 00 00 E4 04 00 00 41 00 00 00 60 00 00 00 06 00 00 00" + + "03 00 00 00 74 00 74 00 03 00 00 00 09 00 00 00 03 00 00 00" + + "00 00 00 00 03 00 00 00 05 00 00 00 1F 00 00 00 0C 00 00 00" + + "4E 00 6F 00 72 00 6D 00 61 00 6C 00 32 00 2E 00 78 00 6C 00" + + "73 00 00 00 1F 00 00 00 0A 00 00 00 53 00 68 00 65 00 65 00" + + "74 00 31 00 21 00 44 00 32 00 00 00 "; + byte[] bytes = HexRead.readFromString(hex); + + PropertySet ps = PropertySetFactory.create(new ByteArrayInputStream(bytes)); + DocumentSummaryInformation dsi = (DocumentSummaryInformation) ps; + Section s = (Section) dsi.getSections().get(0); + + Object hdrs = s.getProperty(PropertyIDMap.PID_HEADINGPAIR); + + assertNotNull("PID_HEADINGPAIR was not found", hdrs); + + assertTrue("PID_HEADINGPAIR: expected byte[] but was "+ hdrs.getClass(), hdrs instanceof byte[]); + // parse the value + Vector v = new Vector((short)Variant.VT_VARIANT); + v.read((byte[])hdrs, 0); + + TypedPropertyValue[] items = v.getValues(); + assertEquals(2, items.length); + + assertNotNull(items[0].getValue()); + assertTrue("first item must be CodePageString but was "+ items[0].getValue().getClass(), + items[0].getValue() instanceof CodePageString); + assertNotNull(items[1].getValue()); + assertTrue("second item must be Integer but was "+ items[1].getValue().getClass(), + items[1].getValue() instanceof Integer); + assertEquals(1, (int)(Integer)items[1].getValue()); + + } +}