fixes for ExternalNameRecord serialisation bug #44691
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@641964 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
00fec066b4
commit
60c8dc5688
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record;
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.Ptg;
|
import org.apache.poi.hssf.record.formula.Ptg;
|
||||||
@ -27,28 +26,26 @@ import org.apache.poi.util.StringUtil;
|
|||||||
/**
|
/**
|
||||||
* EXTERNALNAME<p/>
|
* EXTERNALNAME<p/>
|
||||||
*
|
*
|
||||||
* @author josh micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
public final class ExternalNameRecord extends Record {
|
public final class ExternalNameRecord extends Record {
|
||||||
|
|
||||||
public final static short sid = 0x23; // as per BIFF8. (some old versions used 0x223)
|
public final static short sid = 0x23; // as per BIFF8. (some old versions used 0x223)
|
||||||
|
|
||||||
|
|
||||||
private static final int OPT_BUILTIN_NAME = 0x0001;
|
private static final int OPT_BUILTIN_NAME = 0x0001;
|
||||||
private static final int OPT_AUTOMATIC_LINK = 0x0002;
|
private static final int OPT_AUTOMATIC_LINK = 0x0002;
|
||||||
private static final int OPT_PICTURE_LINK = 0x0004;
|
private static final int OPT_PICTURE_LINK = 0x0004;
|
||||||
private static final int OPT_STD_DOCUMENT_NAME = 0x0008;
|
private static final int OPT_STD_DOCUMENT_NAME = 0x0008;
|
||||||
private static final int OPT_OLE_LINK = 0x0010;
|
private static final int OPT_OLE_LINK = 0x0010;
|
||||||
// private static final int OPT_CLIP_FORMAT_MASK = 0x7FE0;
|
// private static final int OPT_CLIP_FORMAT_MASK = 0x7FE0;
|
||||||
private static final int OPT_ICONIFIED_PICTURE_LINK = 0x8000;
|
private static final int OPT_ICONIFIED_PICTURE_LINK= 0x8000;
|
||||||
|
|
||||||
|
|
||||||
private short field_1_option_flag;
|
private short field_1_option_flag;
|
||||||
private short field_2_index;
|
private short field_2_index;
|
||||||
private short field_3_not_used;
|
private short field_3_not_used;
|
||||||
private String field_4_name;
|
private String field_4_name;
|
||||||
private Stack field_5_name_definition;
|
private Ptg[] field_5_name_definition; // TODO - junits for name definition field
|
||||||
|
|
||||||
|
|
||||||
public ExternalNameRecord(RecordInputStream in) {
|
public ExternalNameRecord(RecordInputStream in) {
|
||||||
super(in);
|
super(in);
|
||||||
@ -105,7 +102,9 @@ public final class ExternalNameRecord extends Record {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getDataSize(){
|
private int getDataSize(){
|
||||||
return 2 + 2 + field_4_name.length() + 2 + getNameDefinitionSize();
|
return 3 * 2 // 3 short fields
|
||||||
|
+ 2 + field_4_name.length() // nameLen and name
|
||||||
|
+ 2 + getNameDefinitionSize(); // nameDefLen and nameDef
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,7 +117,6 @@ public final class ExternalNameRecord extends Record {
|
|||||||
* @return number of bytes written
|
* @return number of bytes written
|
||||||
*/
|
*/
|
||||||
public int serialize( int offset, byte[] data ) {
|
public int serialize( int offset, byte[] data ) {
|
||||||
// TODO - junit tests
|
|
||||||
int dataSize = getDataSize();
|
int dataSize = getDataSize();
|
||||||
|
|
||||||
LittleEndian.putShort( data, 0 + offset, sid );
|
LittleEndian.putShort( data, 0 + offset, sid );
|
||||||
@ -128,29 +126,24 @@ public final class ExternalNameRecord extends Record {
|
|||||||
LittleEndian.putShort( data, 8 + offset, field_3_not_used );
|
LittleEndian.putShort( data, 8 + offset, field_3_not_used );
|
||||||
short nameLen = (short) field_4_name.length();
|
short nameLen = (short) field_4_name.length();
|
||||||
LittleEndian.putShort( data, 10 + offset, nameLen );
|
LittleEndian.putShort( data, 10 + offset, nameLen );
|
||||||
StringUtil.putCompressedUnicode( field_4_name, data, 10 + offset );
|
StringUtil.putCompressedUnicode( field_4_name, data, 12 + offset );
|
||||||
short defLen = (short) getNameDefinitionSize();
|
short defLen = (short) getNameDefinitionSize();
|
||||||
LittleEndian.putShort( data, 12 + nameLen + offset, defLen );
|
LittleEndian.putShort( data, 12 + nameLen + offset, defLen );
|
||||||
Ptg.serializePtgStack(field_5_name_definition, data, 12 + nameLen + offset );
|
Ptg.serializePtgStack(toStack(field_5_name_definition), data, 14 + nameLen + offset );
|
||||||
return dataSize + 4;
|
return dataSize + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getNameDefinitionSize() {
|
private int getNameDefinitionSize() {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
List list = field_5_name_definition;
|
for (int i = 0; i < field_5_name_definition.length; i++) {
|
||||||
|
result += field_5_name_definition[i].getSize();
|
||||||
for (int k = 0; k < list.size(); k++)
|
|
||||||
{
|
|
||||||
Ptg ptg = ( Ptg ) list.get(k);
|
|
||||||
|
|
||||||
result += ptg.getSize();
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getRecordSize(){
|
public int getRecordSize(){
|
||||||
return 6 + 2 + field_4_name.length() + 2 + getNameDefinitionSize();
|
return 4 + getDataSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -161,7 +154,20 @@ public final class ExternalNameRecord extends Record {
|
|||||||
short nameLength = in.readShort();
|
short nameLength = in.readShort();
|
||||||
field_4_name = in.readCompressedUnicode(nameLength);
|
field_4_name = in.readCompressedUnicode(nameLength);
|
||||||
short formulaLen = in.readShort();
|
short formulaLen = in.readShort();
|
||||||
field_5_name_definition = Ptg.createParsedExpressionTokens(formulaLen, in);
|
field_5_name_definition = toPtgArray(Ptg.createParsedExpressionTokens(formulaLen, in));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Ptg[] toPtgArray(Stack s) {
|
||||||
|
Ptg[] result = new Ptg[s.size()];
|
||||||
|
s.toArray(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
private static Stack toStack(Ptg[] ptgs) {
|
||||||
|
Stack result = new Stack();
|
||||||
|
for (int i = 0; i < ptgs.length; i++) {
|
||||||
|
result.push(ptgs[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getSid() {
|
public short getSid() {
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
|
|
||||||
package org.apache.poi.hssf.record;
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.AllFormulaTests;
|
import org.apache.poi.hssf.record.formula.AllFormulaTests;
|
||||||
@ -28,10 +27,10 @@ import junit.framework.TestSuite;
|
|||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
public class AllRecordTests {
|
public final class AllRecordTests {
|
||||||
|
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record");
|
TestSuite result = new TestSuite(AllRecordTests.class.getName());
|
||||||
|
|
||||||
result.addTest(AllFormulaTests.suite());
|
result.addTest(AllFormulaTests.suite());
|
||||||
|
|
||||||
@ -56,6 +55,7 @@ public class AllRecordTests {
|
|||||||
result.addTestSuite(TestEmbeddedObjectRefSubRecord.class);
|
result.addTestSuite(TestEmbeddedObjectRefSubRecord.class);
|
||||||
result.addTestSuite(TestEndSubRecord.class);
|
result.addTestSuite(TestEndSubRecord.class);
|
||||||
result.addTestSuite(TestEscherAggregate.class);
|
result.addTestSuite(TestEscherAggregate.class);
|
||||||
|
result.addTestSuite(TestExternalNameRecord.class);
|
||||||
result.addTestSuite(TestFontBasisRecord.class);
|
result.addTestSuite(TestFontBasisRecord.class);
|
||||||
result.addTestSuite(TestFontIndexRecord.class);
|
result.addTestSuite(TestFontIndexRecord.class);
|
||||||
result.addTestSuite(TestFormulaRecord.class);
|
result.addTestSuite(TestFormulaRecord.class);
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.hssf.record;
|
||||||
|
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Josh Micich
|
||||||
|
*/
|
||||||
|
public final class TestExternalNameRecord extends TestCase {
|
||||||
|
|
||||||
|
private static final byte[] dataFDS = {
|
||||||
|
0, 0, 0, 0, 0, 0, 3, 0, 70, 68, 83, 0, 0,
|
||||||
|
};
|
||||||
|
private static ExternalNameRecord createSimpleENR() {
|
||||||
|
return new ExternalNameRecord(new TestcaseRecordInputStream((short)0x0023, dataFDS));
|
||||||
|
}
|
||||||
|
public void testBasicDeserializeReserialize() {
|
||||||
|
|
||||||
|
ExternalNameRecord enr = createSimpleENR();
|
||||||
|
assertEquals( "FDS", enr.getText());
|
||||||
|
|
||||||
|
try {
|
||||||
|
TestcaseRecordInputStream.confirmRecordEncoding(0x0023, dataFDS, enr.serialize());
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
if(e.getMessage().equals("15")) {
|
||||||
|
throw new AssertionFailedError("Identified bug 44691");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBasicSize() {
|
||||||
|
ExternalNameRecord enr = createSimpleENR();
|
||||||
|
if(enr.getRecordSize() == 13) {
|
||||||
|
throw new AssertionFailedError("Identified bug 44691");
|
||||||
|
}
|
||||||
|
assertEquals(17, enr.getRecordSize());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user