#58718 - Master styles not initialized when running multithreaded
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1719758 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8c491bfb7a
commit
ad89fdcaf5
@ -93,13 +93,13 @@ public class TabStopPropCollection extends TextProp {
|
|||||||
*/
|
*/
|
||||||
public void parseProperty(byte data[], int offset) {
|
public void parseProperty(byte data[], int offset) {
|
||||||
int count = LittleEndian.getUShort(data, offset);
|
int count = LittleEndian.getUShort(data, offset);
|
||||||
offset += LittleEndianConsts.SHORT_SIZE;
|
int off = offset + LittleEndianConsts.SHORT_SIZE;
|
||||||
for (int i=0; i<count; i++) {
|
for (int i=0; i<count; i++) {
|
||||||
int position = LittleEndian.getShort(data, offset);
|
int position = LittleEndian.getShort(data, off);
|
||||||
offset += LittleEndianConsts.SHORT_SIZE;
|
off += LittleEndianConsts.SHORT_SIZE;
|
||||||
int recVal = LittleEndian.getShort(data, offset);
|
int recVal = LittleEndian.getShort(data, off);
|
||||||
TabStopType type = TabStopType.fromRecordVal(recVal);
|
TabStopType type = TabStopType.fromRecordVal(recVal);
|
||||||
offset += LittleEndianConsts.SHORT_SIZE;
|
off += LittleEndianConsts.SHORT_SIZE;
|
||||||
tabStops.add(new TabStop(position, type));
|
tabStops.add(new TabStop(position, type));
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -109,4 +109,15 @@ public class TabStopPropCollection extends TextProp {
|
|||||||
public int getSize() {
|
public int getSize() {
|
||||||
return LittleEndianConsts.SHORT_SIZE + tabStops.size()*LittleEndianConsts.INT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE + tabStops.size()*LittleEndianConsts.INT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TabStopPropCollection clone() {
|
||||||
|
TabStopPropCollection other = (TabStopPropCollection)super.clone();
|
||||||
|
other.tabStops = new ArrayList<TabStop>();
|
||||||
|
for (TabStop ts : tabStops) {
|
||||||
|
TabStop tso = new TabStop(ts.getPosition(), ts.getType());
|
||||||
|
other.tabStops.add(tso);
|
||||||
|
}
|
||||||
|
return other;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ public class TextProp implements Cloneable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
@ -108,6 +109,7 @@ public class TextProp implements Cloneable {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) return true;
|
if (this == obj) return true;
|
||||||
if (obj == null) return false;
|
if (obj == null) return false;
|
||||||
@ -121,4 +123,15 @@ public class TextProp implements Cloneable {
|
|||||||
if (sizeOfDataBlock != other.sizeOfDataBlock) return false;
|
if (sizeOfDataBlock != other.sizeOfDataBlock) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
int len;
|
||||||
|
switch (sizeOfDataBlock) {
|
||||||
|
case 1: len = 4; break;
|
||||||
|
case 2: len = 6; break;
|
||||||
|
default: len = 10; break;
|
||||||
|
}
|
||||||
|
return String.format("%s = %d (%0#"+len+"X mask / %d bytes)", propName, dataValue, maskInHeader, sizeOfDataBlock);
|
||||||
|
}
|
||||||
}
|
}
|
@ -214,13 +214,11 @@ public class TextPropCollection {
|
|||||||
// Bingo, data contains this property
|
// Bingo, data contains this property
|
||||||
TextProp prop = tp.clone();
|
TextProp prop = tp.clone();
|
||||||
int val = 0;
|
int val = 0;
|
||||||
if (prop instanceof TabStopPropCollection) {
|
if (prop.getSize() == 2) {
|
||||||
((TabStopPropCollection)prop).parseProperty(data, dataOffset+bytesPassed);
|
|
||||||
} else if (prop.getSize() == 2) {
|
|
||||||
val = LittleEndian.getShort(data,dataOffset+bytesPassed);
|
val = LittleEndian.getShort(data,dataOffset+bytesPassed);
|
||||||
} else if(prop.getSize() == 4) {
|
} else if(prop.getSize() == 4) {
|
||||||
val = LittleEndian.getInt(data,dataOffset+bytesPassed);
|
val = LittleEndian.getInt(data,dataOffset+bytesPassed);
|
||||||
} else if (prop.getSize() == 0) {
|
} else if (prop.getSize() == 0 && !(prop instanceof TabStopPropCollection)) {
|
||||||
//remember "special" bits.
|
//remember "special" bits.
|
||||||
maskSpecial |= tp.getMask();
|
maskSpecial |= tp.getMask();
|
||||||
continue;
|
continue;
|
||||||
@ -228,6 +226,8 @@ public class TextPropCollection {
|
|||||||
|
|
||||||
if (prop instanceof BitMaskTextProp) {
|
if (prop instanceof BitMaskTextProp) {
|
||||||
((BitMaskTextProp)prop).setValueWithMask(val, containsField);
|
((BitMaskTextProp)prop).setValueWithMask(val, containsField);
|
||||||
|
} else if (prop instanceof TabStopPropCollection) {
|
||||||
|
((TabStopPropCollection)prop).parseProperty(data, dataOffset+bytesPassed);
|
||||||
} else {
|
} else {
|
||||||
prop.setValue(val);
|
prop.setValue(val);
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ public final class TxMasterStyleAtom extends RecordAtom {
|
|||||||
charStyles = new ArrayList<TextPropCollection>(levels);
|
charStyles = new ArrayList<TextPropCollection>(levels);
|
||||||
|
|
||||||
for(short i = 0; i < levels; i++) {
|
for(short i = 0; i < levels; i++) {
|
||||||
TextPropCollection prprops = new TextPropCollection(0, TextPropType.paragraph); // getParagraphProps(type, j)
|
TextPropCollection prprops = new TextPropCollection(0, TextPropType.paragraph);
|
||||||
if (type >= TextHeaderAtom.CENTRE_BODY_TYPE) {
|
if (type >= TextHeaderAtom.CENTRE_BODY_TYPE) {
|
||||||
// Fetch the 2 byte value, that is safe to ignore for some types of text
|
// Fetch the 2 byte value, that is safe to ignore for some types of text
|
||||||
short indentLevel = LittleEndian.getShort(_data, pos);
|
short indentLevel = LittleEndian.getShort(_data, pos);
|
||||||
@ -162,7 +162,7 @@ public final class TxMasterStyleAtom extends RecordAtom {
|
|||||||
|
|
||||||
head = LittleEndian.getInt(_data, pos);
|
head = LittleEndian.getInt(_data, pos);
|
||||||
pos += LittleEndian.INT_SIZE;
|
pos += LittleEndian.INT_SIZE;
|
||||||
TextPropCollection chprops = new TextPropCollection(0, TextPropType.character); // getCharacterProps(type, j)
|
TextPropCollection chprops = new TextPropCollection(0, TextPropType.character);
|
||||||
pos += chprops.buildTextPropList( head, _data, pos);
|
pos += chprops.buildTextPropList( head, _data, pos);
|
||||||
charStyles.add(chprops);
|
charStyles.add(chprops);
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ import org.apache.poi.ddf.EscherColorRef;
|
|||||||
import org.apache.poi.ddf.EscherProperties;
|
import org.apache.poi.ddf.EscherProperties;
|
||||||
import org.apache.poi.hslf.HSLFTestDataSamples;
|
import org.apache.poi.hslf.HSLFTestDataSamples;
|
||||||
import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
|
import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
|
||||||
|
import org.apache.poi.hslf.extractor.PowerPointExtractor;
|
||||||
import org.apache.poi.hslf.model.HeadersFooters;
|
import org.apache.poi.hslf.model.HeadersFooters;
|
||||||
import org.apache.poi.hslf.record.Document;
|
import org.apache.poi.hslf.record.Document;
|
||||||
import org.apache.poi.hslf.record.Record;
|
import org.apache.poi.hslf.record.Record;
|
||||||
@ -757,6 +758,17 @@ public final class TestBugs {
|
|||||||
ppt2.close();
|
ppt2.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bug58718() throws IOException {
|
||||||
|
String files[] = { "bug58718_008524.ppt","bug58718_008558.ppt","bug58718_349008.ppt","bug58718_008495.ppt", };
|
||||||
|
for (String f : files) {
|
||||||
|
File sample = HSLFTestDataSamples.getSampleFile(f);
|
||||||
|
PowerPointExtractor ex = new PowerPointExtractor(sample.getAbsolutePath());
|
||||||
|
assertNotNull(ex.getText());
|
||||||
|
ex.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static HSLFSlideShow open(String fileName) throws IOException {
|
private static HSLFSlideShow open(String fileName) throws IOException {
|
||||||
File sample = HSLFTestDataSamples.getSampleFile(fileName);
|
File sample = HSLFTestDataSamples.getSampleFile(fileName);
|
||||||
return (HSLFSlideShow)SlideShowFactory.create(sample);
|
return (HSLFSlideShow)SlideShowFactory.create(sample);
|
||||||
|
BIN
test-data/slideshow/bug58718_008495.ppt
Normal file
BIN
test-data/slideshow/bug58718_008495.ppt
Normal file
Binary file not shown.
BIN
test-data/slideshow/bug58718_008524.ppt
Normal file
BIN
test-data/slideshow/bug58718_008524.ppt
Normal file
Binary file not shown.
BIN
test-data/slideshow/bug58718_008558.ppt
Normal file
BIN
test-data/slideshow/bug58718_008558.ppt
Normal file
Binary file not shown.
BIN
test-data/slideshow/bug58718_349008.ppt
Normal file
BIN
test-data/slideshow/bug58718_349008.ppt
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user