Revert previous changes enough to restore the case in the commoncrawl-corpus which is failing now, add a unit-test for this case, enable one disabled unit-test
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1781822 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
142e52dfba
commit
f431473f29
@ -24,7 +24,7 @@ import org.apache.poi.util.HexDump;
|
|||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Escher array properties are the most wierd construction ever invented
|
* Escher array properties are the most weird construction ever invented
|
||||||
* with all sorts of special cases. I'm hopeful I've got them all.
|
* with all sorts of special cases. I'm hopeful I've got them all.
|
||||||
*/
|
*/
|
||||||
public final class EscherArrayProperty extends EscherComplexProperty implements Iterable<byte[]> {
|
public final class EscherArrayProperty extends EscherComplexProperty implements Iterable<byte[]> {
|
||||||
@ -43,7 +43,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||||||
/**
|
/**
|
||||||
* When reading a property from data stream remember if the complex part is empty and set this flag.
|
* When reading a property from data stream remember if the complex part is empty and set this flag.
|
||||||
*/
|
*/
|
||||||
private boolean emptyComplexPart = false;
|
private boolean emptyComplexPart;
|
||||||
|
|
||||||
public EscherArrayProperty(short id, byte[] complexData) {
|
public EscherArrayProperty(short id, byte[] complexData) {
|
||||||
super(id, checkComplexData(complexData));
|
super(id, checkComplexData(complexData));
|
||||||
@ -67,8 +67,12 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setNumberOfElementsInArray(int numberOfElements) {
|
public void setNumberOfElementsInArray(int numberOfElements) {
|
||||||
int expectedArraySize = getArraySizeInBytes(numberOfElements, getSizeOfElements());
|
int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
|
||||||
resizeComplexData(expectedArraySize, getComplexData().length);
|
if (expectedArraySize != getComplexData().length) {
|
||||||
|
byte[] newArray = new byte[expectedArraySize];
|
||||||
|
System.arraycopy(getComplexData(), 0, newArray, 0, getComplexData().length);
|
||||||
|
setComplexData(newArray);
|
||||||
|
}
|
||||||
LittleEndian.putShort(getComplexData(), 0, (short) numberOfElements);
|
LittleEndian.putShort(getComplexData(), 0, (short) numberOfElements);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +81,12 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setNumberOfElementsInMemory(int numberOfElements) {
|
public void setNumberOfElementsInMemory(int numberOfElements) {
|
||||||
int expectedArraySize = getArraySizeInBytes(numberOfElements, getSizeOfElements());
|
int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
|
||||||
resizeComplexData(expectedArraySize, expectedArraySize);
|
if (expectedArraySize != getComplexData().length) {
|
||||||
|
byte[] newArray = new byte[expectedArraySize];
|
||||||
|
System.arraycopy(getComplexData(), 0, newArray, 0, expectedArraySize);
|
||||||
|
setComplexData(newArray);
|
||||||
|
}
|
||||||
LittleEndian.putShort(getComplexData(), 2, (short) numberOfElements);
|
LittleEndian.putShort(getComplexData(), 2, (short) numberOfElements);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,9 +97,13 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||||||
public void setSizeOfElements(int sizeOfElements) {
|
public void setSizeOfElements(int sizeOfElements) {
|
||||||
LittleEndian.putShort( getComplexData(), 4, (short) sizeOfElements );
|
LittleEndian.putShort( getComplexData(), 4, (short) sizeOfElements );
|
||||||
|
|
||||||
int expectedArraySize = getArraySizeInBytes(getNumberOfElementsInArray(), sizeOfElements);
|
int expectedArraySize = getNumberOfElementsInArray() * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
|
||||||
|
if (expectedArraySize != getComplexData().length) {
|
||||||
// Keep just the first 6 bytes. The rest is no good to us anyway.
|
// Keep just the first 6 bytes. The rest is no good to us anyway.
|
||||||
resizeComplexData(expectedArraySize, 6);
|
byte[] newArray = new byte[expectedArraySize];
|
||||||
|
System.arraycopy( getComplexData(), 0, newArray, 0, 6 );
|
||||||
|
setComplexData(newArray);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getElement(int index) {
|
public byte[] getElement(int index) {
|
||||||
@ -108,13 +120,13 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer results = new StringBuffer();
|
StringBuilder results = new StringBuilder();
|
||||||
results.append(" {EscherArrayProperty:" + '\n');
|
results.append(" {EscherArrayProperty:" + '\n');
|
||||||
results.append(" Num Elements: " + getNumberOfElementsInArray() + '\n');
|
results.append(" Num Elements: ").append(getNumberOfElementsInArray()).append('\n');
|
||||||
results.append(" Num Elements In Memory: " + getNumberOfElementsInMemory() + '\n');
|
results.append(" Num Elements In Memory: ").append(getNumberOfElementsInMemory()).append('\n');
|
||||||
results.append(" Size of elements: " + getSizeOfElements() + '\n');
|
results.append(" Size of elements: ").append(getSizeOfElements()).append('\n');
|
||||||
for (int i = 0; i < getNumberOfElementsInArray(); i++) {
|
for (int i = 0; i < getNumberOfElementsInArray(); i++) {
|
||||||
results.append(" Element " + i + ": " + HexDump.toHex(getElement(i)) + '\n');
|
results.append(" Element ").append(i).append(": ").append(HexDump.toHex(getElement(i))).append('\n');
|
||||||
}
|
}
|
||||||
results.append("}" + '\n');
|
results.append("}" + '\n');
|
||||||
|
|
||||||
@ -150,25 +162,23 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||||||
*/
|
*/
|
||||||
public int setArrayData(byte[] data, int offset) {
|
public int setArrayData(byte[] data, int offset) {
|
||||||
if (emptyComplexPart){
|
if (emptyComplexPart){
|
||||||
resizeComplexData(0, 0);
|
setComplexData(new byte[0]);
|
||||||
return 0;
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
short numElements = LittleEndian.getShort(data, offset);
|
short numElements = LittleEndian.getShort(data, offset);
|
||||||
// LittleEndian.getShort(data, offset + 2); // numReserved
|
// LittleEndian.getShort(data, offset + 2); // numReserved
|
||||||
short sizeOfElements = LittleEndian.getShort(data, offset + 4);
|
short sizeOfElements = LittleEndian.getShort(data, offset + 4);
|
||||||
|
|
||||||
// TODO: this part is strange - it doesn't make sense to compare
|
// the code here seems to depend on complexData already being
|
||||||
// the size of the existing data when setting a new data array ...
|
// sized correctly via the constructor
|
||||||
int arraySize = getArraySizeInBytes(numElements, sizeOfElements);
|
int arraySize = getActualSizeOfElements(sizeOfElements) * numElements;
|
||||||
if (arraySize - FIXED_SIZE == getComplexData().length) {
|
if (arraySize == getComplexData().length) {
|
||||||
// The stored data size in the simple block excludes the header size
|
// The stored data size in the simple block excludes the header size
|
||||||
|
setComplexData(new byte[arraySize + 6]);
|
||||||
sizeIncludesHeaderSize = false;
|
sizeIncludesHeaderSize = false;
|
||||||
}
|
}
|
||||||
int cpySize = Math.min(arraySize, data.length-offset);
|
System.arraycopy(data, offset, getComplexData(), 0, getComplexData().length );
|
||||||
resizeComplexData(cpySize, 0);
|
}
|
||||||
System.arraycopy(data, offset, getComplexData(), 0, cpySize);
|
return getComplexData().length;
|
||||||
return cpySize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,15 +209,10 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
|
|||||||
return sizeOfElements;
|
return sizeOfElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getArraySizeInBytes(int numberOfElements, int sizeOfElements) {
|
|
||||||
return numberOfElements * getActualSizeOfElements((short)(sizeOfElements & 0xFFFF)) + FIXED_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<byte[]> iterator() {
|
public Iterator<byte[]> iterator() {
|
||||||
return new Iterator<byte[]>(){
|
return new Iterator<byte[]>(){
|
||||||
private int idx = 0;
|
int idx;
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return (idx < getNumberOfElementsInArray());
|
return (idx < getNumberOfElementsInArray());
|
||||||
|
@ -28,7 +28,6 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
* stored here.
|
* stored here.
|
||||||
*/
|
*/
|
||||||
public class EscherComplexProperty extends EscherProperty {
|
public class EscherComplexProperty extends EscherProperty {
|
||||||
// TODO - make private and final
|
|
||||||
private byte[] _complexData;
|
private byte[] _complexData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,15 +94,9 @@ public class EscherComplexProperty extends EscherProperty {
|
|||||||
return _complexData;
|
return _complexData;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void resizeComplexData(int newSize, int bytesToKeep) {
|
protected void setComplexData(byte[] _complexData) {
|
||||||
if (newSize == _complexData.length) {
|
this._complexData = _complexData;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
byte[] newArray = new byte[newSize];
|
|
||||||
System.arraycopy(_complexData, 0, newArray, 0, Math.min(bytesToKeep, newSize));
|
|
||||||
_complexData = newArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether this property is equal to another property.
|
* Determine whether this property is equal to another property.
|
||||||
|
@ -903,6 +903,7 @@ public class TestBugs{
|
|||||||
assertEquals(section2NumColumns, section.getNumColumns());
|
assertEquals(section2NumColumns, section.getNumColumns());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testRegressionIn315beta2() {
|
public void testRegressionIn315beta2() {
|
||||||
HWPFDocument hwpfDocument = HWPFTestDataSamples.openSampleFile("cap.stanford.edu_profiles_viewbiosketch_facultyid=4009&name=m_maciver.doc");
|
HWPFDocument hwpfDocument = HWPFTestDataSamples.openSampleFile("cap.stanford.edu_profiles_viewbiosketch_facultyid=4009&name=m_maciver.doc");
|
||||||
assertNotNull(hwpfDocument);
|
assertNotNull(hwpfDocument);
|
||||||
@ -929,4 +930,10 @@ public class TestBugs{
|
|||||||
fs.close();
|
fs.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCommonCrawlRegression() throws IOException {
|
||||||
|
HWPFDocument document = HWPFTestDataSamples.openSampleFile("ca.kwsymphony.www_education_School_Concert_Seat_Booking_Form_2011-12.doc");
|
||||||
|
document.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user