#61881 - handle invalid font names

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1817599 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2017-12-09 11:44:19 +00:00
parent 41981a4ac9
commit 2c2028ede6
3 changed files with 41 additions and 3 deletions

View File

@ -86,16 +86,40 @@ public final class FontEntityAtom extends RecordAtom {
* @return font name * @return font name
*/ */
public String getFontName(){ public String getFontName(){
int maxLen = Math.min(_recdata.length,64); final int maxLen = Math.min(_recdata.length,64);
for(int i = 0; i < maxLen; i+=2){ for(int i = 0; i+1 < maxLen; i+=2){
//loop until find null-terminated end of the font name //loop until find null-terminated end of the font name
if(_recdata[i] == 0 && _recdata[i + 1] == 0) { if(_recdata[i] == 0 && _recdata[i + 1] == 0 && !isFontNamePremature0terminated(i)) {
return StringUtil.getFromUnicodeLE(_recdata, 0, i/2); return StringUtil.getFromUnicodeLE(_recdata, 0, i/2);
} }
} }
return null; return null;
} }
/**
* #61881: there seem to be programs out there, which write the 0-termination also
* at the beginning of the string. Check if the next two bytes contain a valid ascii char
* and correct the _recdata with a '?' char
*/
private boolean isFontNamePremature0terminated(final int index) {
if (index > 0) {
// for now we only check the first char
return false;
}
if (_recdata.length < index+4) {
return false;
}
final int cp = LittleEndian.getShort(_recdata, index+2);
if (!Character.isJavaIdentifierPart(cp)) {
return false;
}
_recdata[index] = '?';
return true;
}
/** /**
* Set the name of the font. * Set the name of the font.
* The length of this string must not exceed 32 characters * The length of this string must not exceed 32 characters

View File

@ -23,9 +23,12 @@ import static org.junit.Assert.assertNull;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.usermodel.HSLFFontInfo; import org.apache.poi.hslf.usermodel.HSLFFontInfo;
import org.apache.poi.hslf.usermodel.HSLFFontInfoPredefined; import org.apache.poi.hslf.usermodel.HSLFFontInfoPredefined;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.poifs.storage.RawDataUtil; import org.apache.poi.poifs.storage.RawDataUtil;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -34,6 +37,8 @@ import org.junit.Test;
* Tests {@code FontCollection} and {@code FontEntityAtom} records * Tests {@code FontCollection} and {@code FontEntityAtom} records
*/ */
public final class TestFontCollection { public final class TestFontCollection {
private static final POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
// From a real file // From a real file
private static byte[] data; private static byte[] data;
@ -87,4 +92,13 @@ public final class TestFontCollection {
byte[] recdata = out.toByteArray(); byte[] recdata = out.toByteArray();
assertArrayEquals(recdata, data); assertArrayEquals(recdata, data);
} }
@Test
public void bug61881() throws IOException {
try (InputStream is = _slTests.openResourceAsStream("bug61881.ppt")) {
try (HSLFSlideShow ppt = new HSLFSlideShow(is)) {
assertEquals("?imes New Roman",ppt.getFont(3).getTypeface());
}
}
}
} }

Binary file not shown.