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:
Josh Micich 2008-03-27 20:03:29 +00:00
parent 47d3a87a5c
commit 44c475cd46
3 changed files with 187 additions and 126 deletions

View File

@ -17,7 +17,6 @@
package org.apache.poi.hssf.record;
import java.util.List;
import java.util.Stack;
import org.apache.poi.hssf.record.formula.Ptg;
@ -27,13 +26,12 @@ import org.apache.poi.util.StringUtil;
/**
* EXTERNALNAME<p/>
*
* @author josh micich
* @author Josh Micich
*/
public final class ExternalNameRecord extends Record {
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_AUTOMATIC_LINK = 0x0002;
private static final int OPT_PICTURE_LINK = 0x0004;
@ -47,8 +45,7 @@ public final class ExternalNameRecord extends Record {
private short field_2_index;
private short field_3_not_used;
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) {
super(in);
@ -105,7 +102,9 @@ public final class ExternalNameRecord extends Record {
}
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
*/
public int serialize( int offset, byte[] data ) {
// TODO - junit tests
int dataSize = getDataSize();
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 );
short nameLen = (short) field_4_name.length();
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();
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;
}
private int getNameDefinitionSize() {
int result = 0;
List list = field_5_name_definition;
for (int k = 0; k < list.size(); k++)
{
Ptg ptg = ( Ptg ) list.get(k);
result += ptg.getSize();
for (int i = 0; i < field_5_name_definition.length; i++) {
result += field_5_name_definition[i].getSize();
}
return result;
}
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();
field_4_name = in.readCompressedUnicode(nameLength);
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() {

View File

@ -15,7 +15,6 @@
limitations under the License.
==================================================================== */
package org.apache.poi.hssf.record;
import org.apache.poi.hssf.record.formula.AllFormulaTests;
@ -28,10 +27,10 @@ import junit.framework.TestSuite;
*
* @author Josh Micich
*/
public class AllRecordTests {
public final class AllRecordTests {
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());
@ -56,6 +55,7 @@ public class AllRecordTests {
result.addTestSuite(TestEmbeddedObjectRefSubRecord.class);
result.addTestSuite(TestEndSubRecord.class);
result.addTestSuite(TestEscherAggregate.class);
result.addTestSuite(TestExternalNameRecord.class);
result.addTestSuite(TestFontBasisRecord.class);
result.addTestSuite(TestFontIndexRecord.class);
result.addTestSuite(TestFormulaRecord.class);

View File

@ -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());
}
}