mirror of https://github.com/apache/poi.git
Fix for bug introduced in r745976. EscherContainerRecord shouldn't hand out it's private 'child records' field.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@746018 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6f1a7911c9
commit
83359062e7
|
@ -34,8 +34,7 @@ import java.io.PrintWriter;
|
||||||
*
|
*
|
||||||
* @author Glen Stampoultzis
|
* @author Glen Stampoultzis
|
||||||
*/
|
*/
|
||||||
public class EscherContainerRecord extends EscherRecord
|
public final class EscherContainerRecord extends EscherRecord {
|
||||||
{
|
|
||||||
public static final short DGG_CONTAINER = (short)0xF000;
|
public static final short DGG_CONTAINER = (short)0xF000;
|
||||||
public static final short BSTORE_CONTAINER = (short)0xF001;
|
public static final short BSTORE_CONTAINER = (short)0xF001;
|
||||||
public static final short DG_CONTAINER = (short)0xF002;
|
public static final short DG_CONTAINER = (short)0xF002;
|
||||||
|
@ -57,7 +56,7 @@ public class EscherContainerRecord extends EscherRecord
|
||||||
bytesWritten += childBytesWritten;
|
bytesWritten += childBytesWritten;
|
||||||
offset += childBytesWritten;
|
offset += childBytesWritten;
|
||||||
bytesRemaining -= childBytesWritten;
|
bytesRemaining -= childBytesWritten;
|
||||||
getChildRecords().add( child );
|
addChildRecord(child);
|
||||||
if (offset >= data.length && bytesRemaining > 0)
|
if (offset >= data.length && bytesRemaining > 0)
|
||||||
{
|
{
|
||||||
System.out.println("WARNING: " + bytesRemaining + " bytes remaining but no space left");
|
System.out.println("WARNING: " + bytesRemaining + " bytes remaining but no space left");
|
||||||
|
@ -73,16 +72,16 @@ public class EscherContainerRecord extends EscherRecord
|
||||||
LittleEndian.putShort(data, offset, getOptions());
|
LittleEndian.putShort(data, offset, getOptions());
|
||||||
LittleEndian.putShort(data, offset+2, getRecordId());
|
LittleEndian.putShort(data, offset+2, getRecordId());
|
||||||
int remainingBytes = 0;
|
int remainingBytes = 0;
|
||||||
for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
|
Iterator<EscherRecord> iterator = _childRecords.iterator();
|
||||||
{
|
while (iterator.hasNext()) {
|
||||||
EscherRecord r = (EscherRecord) iterator.next();
|
EscherRecord r = iterator.next();
|
||||||
remainingBytes += r.getRecordSize();
|
remainingBytes += r.getRecordSize();
|
||||||
}
|
}
|
||||||
LittleEndian.putInt(data, offset+4, remainingBytes);
|
LittleEndian.putInt(data, offset+4, remainingBytes);
|
||||||
int pos = offset+8;
|
int pos = offset+8;
|
||||||
for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
|
iterator = _childRecords.iterator();
|
||||||
{
|
while (iterator.hasNext()) {
|
||||||
EscherRecord r = (EscherRecord) iterator.next();
|
EscherRecord r = iterator.next();
|
||||||
pos += r.serialize(pos, data, listener );
|
pos += r.serialize(pos, data, listener );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,12 +89,11 @@ public class EscherContainerRecord extends EscherRecord
|
||||||
return pos - offset;
|
return pos - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRecordSize()
|
public int getRecordSize() {
|
||||||
{
|
|
||||||
int childRecordsSize = 0;
|
int childRecordsSize = 0;
|
||||||
for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
|
Iterator<EscherRecord> iterator = _childRecords.iterator();
|
||||||
{
|
while (iterator.hasNext()) {
|
||||||
EscherRecord r = (EscherRecord) iterator.next();
|
EscherRecord r = iterator.next();
|
||||||
childRecordsSize += r.getRecordSize();
|
childRecordsSize += r.getRecordSize();
|
||||||
}
|
}
|
||||||
return 8 + childRecordsSize;
|
return 8 + childRecordsSize;
|
||||||
|
@ -106,9 +104,9 @@ public class EscherContainerRecord extends EscherRecord
|
||||||
* given recordId?
|
* given recordId?
|
||||||
*/
|
*/
|
||||||
public boolean hasChildOfType(short recordId) {
|
public boolean hasChildOfType(short recordId) {
|
||||||
for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
|
Iterator<EscherRecord> iterator = _childRecords.iterator();
|
||||||
{
|
while (iterator.hasNext()) {
|
||||||
EscherRecord r = (EscherRecord) iterator.next();
|
EscherRecord r = iterator.next();
|
||||||
if(r.getRecordId() == recordId) {
|
if(r.getRecordId() == recordId) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -117,35 +115,40 @@ public class EscherContainerRecord extends EscherRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all the child (escher) records
|
* @return a copy of the list of all the child records of the container.
|
||||||
* of the container.
|
|
||||||
*/
|
*/
|
||||||
public List<EscherRecord> getChildRecords() {
|
public List<EscherRecord> getChildRecords() {
|
||||||
return _childRecords;
|
return new ArrayList<EscherRecord>(_childRecords);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* replaces the internal child list with the contents of the supplied <tt>childRecords</tt>
|
||||||
|
*/
|
||||||
|
public void setChildRecords(List<EscherRecord> childRecords) {
|
||||||
|
if (childRecords == _childRecords) {
|
||||||
|
throw new IllegalStateException("Child records private data member has escaped");
|
||||||
|
}
|
||||||
|
_childRecords.clear();
|
||||||
|
_childRecords.addAll(childRecords);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all of our children which are also
|
* Returns all of our children which are also
|
||||||
* EscherContainers (may be 0, 1, or vary rarely
|
* EscherContainers (may be 0, 1, or vary rarely
|
||||||
* 2 or 3)
|
* 2 or 3)
|
||||||
*/
|
*/
|
||||||
public List getChildContainers() {
|
public List<EscherContainerRecord> getChildContainers() {
|
||||||
List containers = new ArrayList();
|
List<EscherContainerRecord> containers = new ArrayList<EscherContainerRecord>();
|
||||||
for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
|
Iterator<EscherRecord> iterator = _childRecords.iterator();
|
||||||
{
|
while (iterator.hasNext()) {
|
||||||
EscherRecord r = (EscherRecord) iterator.next();
|
EscherRecord r = iterator.next();
|
||||||
if(r instanceof EscherContainerRecord) {
|
if(r instanceof EscherContainerRecord) {
|
||||||
containers.add(r);
|
containers.add((EscherContainerRecord) r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return containers;
|
return containers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChildRecords(List<EscherRecord> childRecords) {
|
|
||||||
_childRecords.clear();
|
|
||||||
_childRecords.addAll(childRecords);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRecordName() {
|
public String getRecordName() {
|
||||||
switch (getRecordId()) {
|
switch (getRecordId()) {
|
||||||
case DGG_CONTAINER:
|
case DGG_CONTAINER:
|
||||||
|
@ -165,13 +168,12 @@ public class EscherContainerRecord extends EscherRecord
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void display( PrintWriter w, int indent )
|
public void display(PrintWriter w, int indent) {
|
||||||
{
|
super.display(w, indent);
|
||||||
super.display( w, indent );
|
for (Iterator<EscherRecord> iterator = _childRecords.iterator(); iterator.hasNext();)
|
||||||
for (Iterator iterator = _childRecords.iterator(); iterator.hasNext();)
|
|
||||||
{
|
{
|
||||||
EscherRecord escherRecord = (EscherRecord) iterator.next();
|
EscherRecord escherRecord = iterator.next();
|
||||||
escherRecord.display( w, indent + 1 );
|
escherRecord.display(w, indent + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,16 +190,15 @@ public class EscherContainerRecord extends EscherRecord
|
||||||
String nl = System.getProperty( "line.separator" );
|
String nl = System.getProperty( "line.separator" );
|
||||||
|
|
||||||
StringBuffer children = new StringBuffer();
|
StringBuffer children = new StringBuffer();
|
||||||
if ( getChildRecords().size() > 0 )
|
if (_childRecords.size() > 0) {
|
||||||
{
|
|
||||||
children.append( " children: " + nl );
|
children.append( " children: " + nl );
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
|
for ( Iterator<EscherRecord> iterator = _childRecords.iterator(); iterator.hasNext(); )
|
||||||
{
|
{
|
||||||
String newIndent = indent + " ";
|
String newIndent = indent + " ";
|
||||||
|
|
||||||
EscherRecord record = (EscherRecord) iterator.next();
|
EscherRecord record = iterator.next();
|
||||||
children.append(newIndent + "Child " + count + ":" + nl);
|
children.append(newIndent + "Child " + count + ":" + nl);
|
||||||
|
|
||||||
if(record instanceof EscherContainerRecord) {
|
if(record instanceof EscherContainerRecord) {
|
||||||
|
@ -215,18 +216,17 @@ public class EscherContainerRecord extends EscherRecord
|
||||||
indent + " isContainer: " + isContainerRecord() + nl +
|
indent + " isContainer: " + isContainerRecord() + nl +
|
||||||
indent + " options: 0x" + HexDump.toHex( getOptions() ) + nl +
|
indent + " options: 0x" + HexDump.toHex( getOptions() ) + nl +
|
||||||
indent + " recordId: 0x" + HexDump.toHex( getRecordId() ) + nl +
|
indent + " recordId: 0x" + HexDump.toHex( getRecordId() ) + nl +
|
||||||
indent + " numchildren: " + getChildRecords().size() + nl +
|
indent + " numchildren: " + _childRecords.size() + nl +
|
||||||
indent + children.toString();
|
indent + children.toString();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public EscherSpRecord getChildById( short recordId )
|
public EscherSpRecord getChildById(short recordId) {
|
||||||
{
|
Iterator<EscherRecord> iterator = _childRecords.iterator();
|
||||||
for ( Iterator iterator = _childRecords.iterator(); iterator.hasNext(); )
|
while (iterator.hasNext()) {
|
||||||
{
|
EscherRecord r = iterator.next();
|
||||||
EscherRecord escherRecord = (EscherRecord) iterator.next();
|
if (r.getRecordId() == recordId)
|
||||||
if (escherRecord.getRecordId() == recordId)
|
return (EscherSpRecord) r;
|
||||||
return (EscherSpRecord) escherRecord;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -236,15 +236,15 @@ public class EscherContainerRecord extends EscherRecord
|
||||||
*
|
*
|
||||||
* @param out - list to store found records
|
* @param out - list to store found records
|
||||||
*/
|
*/
|
||||||
public void getRecordsById(short recordId, List out){
|
public void getRecordsById(short recordId, List<EscherRecord> out){
|
||||||
for(Iterator it = _childRecords.iterator(); it.hasNext();) {
|
Iterator<EscherRecord> iterator = _childRecords.iterator();
|
||||||
Object er = it.next();
|
while (iterator.hasNext()) {
|
||||||
EscherRecord r = (EscherRecord)er;
|
EscherRecord r = iterator.next();
|
||||||
if(r instanceof EscherContainerRecord) {
|
if(r instanceof EscherContainerRecord) {
|
||||||
EscherContainerRecord c = (EscherContainerRecord)r;
|
EscherContainerRecord c = (EscherContainerRecord)r;
|
||||||
c.getRecordsById(recordId, out );
|
c.getRecordsById(recordId, out );
|
||||||
} else if (r.getRecordId() == recordId){
|
} else if (r.getRecordId() == recordId){
|
||||||
out.add(er);
|
out.add(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ public final class MovieShape extends Picture {
|
||||||
|
|
||||||
EscherClientDataRecord cldata = new EscherClientDataRecord();
|
EscherClientDataRecord cldata = new EscherClientDataRecord();
|
||||||
cldata.setOptions((short)0xF);
|
cldata.setOptions((short)0xF);
|
||||||
_escherContainer.getChildRecords().add(cldata);
|
_escherContainer.addChildRecord(cldata);
|
||||||
|
|
||||||
OEShapeAtom oe = new OEShapeAtom();
|
OEShapeAtom oe = new OEShapeAtom();
|
||||||
InteractiveInfo info = new InteractiveInfo();
|
InteractiveInfo info = new InteractiveInfo();
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -20,14 +19,17 @@ package org.apache.poi.ddf;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import org.apache.poi.util.HexRead;
|
import org.apache.poi.util.HexRead;
|
||||||
import org.apache.poi.util.HexDump;
|
import org.apache.poi.util.HexDump;
|
||||||
import org.apache.poi.util.IOUtils;
|
import org.apache.poi.util.IOUtils;
|
||||||
|
|
||||||
public class TestEscherContainerRecord extends TestCase
|
/**
|
||||||
{
|
* Tests for {@link EscherContainerRecord}
|
||||||
|
*/
|
||||||
|
public final class TestEscherContainerRecord extends TestCase {
|
||||||
private String ESCHER_DATA_PATH;
|
private String ESCHER_DATA_PATH;
|
||||||
|
|
||||||
protected void setUp() {
|
protected void setUp() {
|
||||||
|
@ -130,16 +132,17 @@ public class TestEscherContainerRecord extends TestCase
|
||||||
assertEquals( expected, r.toString() );
|
assertEquals( expected, r.toString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class DummyEscherRecord extends EscherRecord {
|
||||||
|
public DummyEscherRecord() { }
|
||||||
|
public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory ) { return 0; }
|
||||||
|
public int serialize( int offset, byte[] data, EscherSerializationListener listener ) { return 0; }
|
||||||
|
public int getRecordSize() { return 10; }
|
||||||
|
public String getRecordName() { return ""; }
|
||||||
|
}
|
||||||
|
|
||||||
public void testGetRecordSize() {
|
public void testGetRecordSize() {
|
||||||
EscherContainerRecord r = new EscherContainerRecord();
|
EscherContainerRecord r = new EscherContainerRecord();
|
||||||
r.addChildRecord(new EscherRecord()
|
r.addChildRecord(new DummyEscherRecord());
|
||||||
{
|
|
||||||
public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory ) { return 0; }
|
|
||||||
public int serialize( int offset, byte[] data, EscherSerializationListener listener ) { return 0; }
|
|
||||||
public int getRecordSize() { return 10; }
|
|
||||||
public String getRecordName() { return ""; }
|
|
||||||
} );
|
|
||||||
|
|
||||||
assertEquals(18, r.getRecordSize());
|
assertEquals(18, r.getRecordSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,4 +161,36 @@ public class TestEscherContainerRecord extends TestCase
|
||||||
EscherContainerRecord record = new EscherContainerRecord();
|
EscherContainerRecord record = new EscherContainerRecord();
|
||||||
record.fillFields(data, 0, new DefaultEscherRecordFactory());
|
record.fillFields(data, 0, new DefaultEscherRecordFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure {@link EscherContainerRecord} doesn't spill its guts everywhere
|
||||||
|
*/
|
||||||
|
public void testChildren() {
|
||||||
|
EscherContainerRecord ecr = new EscherContainerRecord();
|
||||||
|
List<EscherRecord> children0 = ecr.getChildRecords();
|
||||||
|
assertEquals(0, children0.size());
|
||||||
|
|
||||||
|
EscherRecord chA = new DummyEscherRecord();
|
||||||
|
EscherRecord chB = new DummyEscherRecord();
|
||||||
|
EscherRecord chC = new DummyEscherRecord();
|
||||||
|
|
||||||
|
ecr.addChildRecord(chA);
|
||||||
|
ecr.addChildRecord(chB);
|
||||||
|
children0.add(chC);
|
||||||
|
|
||||||
|
List<EscherRecord> children1 = ecr.getChildRecords();
|
||||||
|
assertTrue(children0 != children1);
|
||||||
|
assertEquals(2, children1.size());
|
||||||
|
assertEquals(chA, children1.get(0));
|
||||||
|
assertEquals(chB, children1.get(1));
|
||||||
|
|
||||||
|
assertEquals(1, children0.size()); // first copy unchanged
|
||||||
|
|
||||||
|
ecr.setChildRecords(children0);
|
||||||
|
ecr.addChildRecord(chA);
|
||||||
|
List<EscherRecord> children2 = ecr.getChildRecords();
|
||||||
|
assertEquals(2, children2.size());
|
||||||
|
assertEquals(chC, children2.get(0));
|
||||||
|
assertEquals(chA, children2.get(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue