Skip to content

Commit 45da926

Browse files
authored
Upgrade PDFBox API to 2.0.27 (#469)
1 parent 47824b4 commit 45da926

File tree

76 files changed

+3789
-3921
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+3789
-3921
lines changed

library/src/androidTest/java/com/tom_roush/pdfbox/encryption/TestPublicKeyEncryption.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public void setUp() throws Exception
126126
permission1.setCanModify(false);
127127
permission1.setCanModifyAnnotations(false);
128128
permission1.setCanPrint(false);
129-
permission1.setCanPrintDegraded(false);
129+
permission1.setCanPrintFaithful(false);
130130

131131
permission2 = new AccessPermission();
132132
permission2.setCanAssembleDocument(false);
@@ -136,7 +136,7 @@ public void setUp() throws Exception
136136
permission2.setCanModify(false);
137137
permission2.setCanModifyAnnotations(false);
138138
permission2.setCanPrint(true); // it is true now !
139-
permission2.setCanPrintDegraded(false);
139+
permission2.setCanPrintFaithful(false);
140140

141141
recipient1 = getRecipient("test1.der", permission1);
142142
recipient2 = getRecipient("test2.der", permission2);
@@ -228,7 +228,7 @@ public void testProtection() throws Exception
228228
Assert.assertFalse(permission.canModify());
229229
Assert.assertFalse(permission.canModifyAnnotations());
230230
Assert.assertFalse(permission.canPrint());
231-
Assert.assertFalse(permission.canPrintDegraded());
231+
Assert.assertFalse(permission.canPrintFaithful());
232232
}
233233
finally
234234
{
@@ -264,7 +264,7 @@ public void testMultipleRecipients() throws Exception
264264
Assert.assertFalse(permission.canModify());
265265
Assert.assertFalse(permission.canModifyAnnotations());
266266
Assert.assertFalse(permission.canPrint());
267-
Assert.assertFalse(permission.canPrintDegraded());
267+
Assert.assertFalse(permission.canPrintFaithful());
268268
}
269269
finally
270270
{
@@ -283,7 +283,7 @@ public void testMultipleRecipients() throws Exception
283283
Assert.assertFalse(permission.canModify());
284284
Assert.assertFalse(permission.canModifyAnnotations());
285285
Assert.assertTrue(permission.canPrint());
286-
Assert.assertFalse(permission.canPrintDegraded());
286+
Assert.assertFalse(permission.canPrintFaithful());
287287
}
288288
finally
289289
{

library/src/androidTest/java/com/tom_roush/pdfbox/encryption/TestSymmetricKeyEncryption.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public void setUp() throws Exception
110110
permission.setCanModify(false);
111111
permission.setCanModifyAnnotations(false);
112112
permission.setCanPrint(true);
113-
permission.setCanPrintDegraded(false);
113+
permission.setCanPrintFaithful(false);
114114
permission.setReadOnly();
115115
}
116116

@@ -147,7 +147,7 @@ public void testPermissions() throws Exception
147147

148148
restrAP.setCanAssembleDocument(false);
149149
restrAP.setCanExtractForAccessibility(false);
150-
restrAP.setCanPrintDegraded(false);
150+
restrAP.setCanPrintFaithful(false);
151151

152152
inputFileAsByteArray = getFileResourceAsByteArray("PasswordSample-128bit.pdf");
153153
checkPerms(inputFileAsByteArray, "owner", fullAP);
@@ -196,7 +196,7 @@ private void checkPerms(byte[] inputFileAsByteArray, String password,
196196
assertEquals(expectedPermissions.canModify(), currentAccessPermission.canModify());
197197
assertEquals(expectedPermissions.canModifyAnnotations(), currentAccessPermission.canModifyAnnotations());
198198
assertEquals(expectedPermissions.canPrint(), currentAccessPermission.canPrint());
199-
assertEquals(expectedPermissions.canPrintDegraded(), currentAccessPermission.canPrintDegraded());
199+
assertEquals(expectedPermissions.canPrintFaithful(), currentAccessPermission.canPrintFaithful());
200200

201201
new PDFRenderer(doc).renderImage(0);
202202

library/src/androidTest/java/com/tom_roush/pdfbox/pdmodel/font/PDFontTest.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
package com.tom_roush.pdfbox.pdmodel.font;
1919

2020
import android.content.Context;
21+
import android.graphics.Path;
22+
import android.graphics.RectF;
2123
import android.util.Log;
2224

2325
import androidx.test.platform.app.InstrumentationRegistry;
@@ -51,7 +53,6 @@
5153
import com.tom_roush.pdfbox.text.PDFTextStripper;
5254

5355
import org.junit.Assert;
54-
import org.junit.Assume;
5556
import org.junit.Before;
5657
import org.junit.Test;
5758

@@ -228,7 +229,7 @@ public void testFullEmbeddingTTC() throws IOException
228229
break;
229230
}
230231
}
231-
Assume.assumeTrue("testFullEmbeddingTTC skipped, no .ttc files available", ttc != null);
232+
assumeTrue("testFullEmbeddingTTC skipped, no .ttc files available", ttc != null);
232233

233234
final List<String> names = new ArrayList<String>();
234235
ttc.processAllFonts(new TrueTypeCollection.TrueTypeFontProcessor()
@@ -431,4 +432,31 @@ public void testSoftHyphen() throws IOException
431432
Assert.assertEquals(text + "\n" + text, extractedText.trim());
432433
doc.close();
433434
}
435+
436+
/**
437+
* Test font with an unusual cmap table combination (0, 3).
438+
*
439+
* @throws IOException
440+
*/
441+
@Test
442+
public void testPDFBox5484() throws IOException
443+
{
444+
File fontFile = TestResourceGenerator.downloadTestResource(IN_DIR, "PDFBOX-5484.ttf", "https://issues.apache.org/jira/secure/attachment/13047577/PDFBOX-5484.ttf");
445+
assumeTrue(fontFile.exists());
446+
447+
TrueTypeFont ttf = new TTFParser().parse(fontFile);
448+
PDDocument doc = new PDDocument();
449+
PDTrueTypeFont tr = PDTrueTypeFont.load(doc, ttf, WinAnsiEncoding.INSTANCE);
450+
Path path1 = tr.getPath("oslash");
451+
Path path2 = tr.getPath(248);
452+
Assert.assertFalse(path2.isEmpty()); // not empty
453+
454+
RectF area1 = new RectF();
455+
path1.computeBounds(area1, true);
456+
RectF area2 = new RectF();
457+
path2.computeBounds(area2, true);
458+
459+
Assert.assertTrue(area1.equals(area2)); // assertEquals does not test equals()
460+
doc.close();
461+
}
434462
}

library/src/main/java/com/tom_roush/fontbox/cff/CFFParser.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,10 @@ private CFFFont parseFont(CFFDataInput input, String name, byte[] topDictIndex)
487487
int charStringsOffset = charStringsEntry.getNumber(0).intValue();
488488
input.setPosition(charStringsOffset);
489489
byte[][] charStringsIndex = readIndexData(input);
490+
if (charStringsIndex == null)
491+
{
492+
throw new IOException("CharStringsIndex is missing");
493+
}
490494

491495
// charset
492496
DictData.Entry charsetEntry = topDict.getEntry("charset");

library/src/main/java/com/tom_roush/fontbox/cmap/CMapParser.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,10 @@ private void parseBegincodespacerange(Number cosCount, PushbackInputStream cmapS
275275
checkExpectedOperator((Operator) nextToken, "endcodespacerange", "codespacerange");
276276
break;
277277
}
278+
if (!(nextToken instanceof byte[]))
279+
{
280+
throw new IOException("start range missing");
281+
}
278282
byte[] startRange = (byte[]) nextToken;
279283
byte[] endRange = (byte[]) parseNextToken(cmapStream);
280284
try
@@ -298,6 +302,10 @@ private void parseBeginbfchar(Number cosCount, PushbackInputStream cmapStream, C
298302
checkExpectedOperator((Operator) nextToken, "endbfchar", "bfchar");
299303
break;
300304
}
305+
if (!(nextToken instanceof byte[]))
306+
{
307+
throw new IOException("input code missing");
308+
}
301309
byte[] inputCode = (byte[]) nextToken;
302310
nextToken = parseNextToken(cmapStream);
303311
if (nextToken instanceof byte[])
@@ -328,6 +336,10 @@ private void parseBegincidrange(int numberOfLines, PushbackInputStream cmapStrea
328336
checkExpectedOperator((Operator) nextToken, "endcidrange", "cidrange");
329337
break;
330338
}
339+
if (!(nextToken instanceof byte[]))
340+
{
341+
throw new IOException("start range missing");
342+
}
331343
byte[] startCode = (byte[]) nextToken;
332344
int start = createIntFromBytes(startCode);
333345
byte[] endCode = (byte[]) parseNextToken(cmapStream);
@@ -369,6 +381,10 @@ private void parseBegincidchar(Number cosCount, PushbackInputStream cmapStream,
369381
checkExpectedOperator((Operator) nextToken, "endcidchar", "cidchar");
370382
break;
371383
}
384+
if (!(nextToken instanceof byte[]))
385+
{
386+
throw new IOException("start code missing");
387+
}
372388
byte[] inputCode = (byte[]) nextToken;
373389
int mappedCode = (Integer) parseNextToken(cmapStream);
374390
int mappedCID = createIntFromBytes(inputCode);
@@ -381,26 +397,26 @@ private void parseBeginbfrange(Number cosCount, PushbackInputStream cmapStream,
381397
for (int j = 0; j < cosCount.intValue(); j++)
382398
{
383399
Object nextToken = parseNextToken(cmapStream);
384-
if (nextToken == null)
385-
{
386-
throw new IOException("start code missing");
387-
}
388400
if (nextToken instanceof Operator)
389401
{
390402
checkExpectedOperator((Operator) nextToken, "endbfrange", "bfrange");
391403
break;
392404
}
393-
byte[] startCode = (byte[]) nextToken;
394-
nextToken = parseNextToken(cmapStream);
395-
if (nextToken == null)
405+
if (!(nextToken instanceof byte[]))
396406
{
397-
throw new IOException("end code missing");
407+
throw new IOException("start code missing");
398408
}
409+
byte[] startCode = (byte[]) nextToken;
410+
nextToken = parseNextToken(cmapStream);
399411
if (nextToken instanceof Operator)
400412
{
401413
checkExpectedOperator((Operator) nextToken, "endbfrange", "bfrange");
402414
break;
403415
}
416+
if (!(nextToken instanceof byte[]))
417+
{
418+
throw new IOException("end code missing");
419+
}
404420
byte[] endCode = (byte[]) nextToken;
405421
int start = CMap.toInt(startCode, startCode.length);
406422
int end = CMap.toInt(endCode, endCode.length);

library/src/main/java/com/tom_roush/fontbox/pfb/PfbParser.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ private void parsePfb(final byte[] pfb) throws IOException
167167
}
168168
if (size > pfbdata.length - pointer)
169169
{
170-
throw new IOException("PFB record size (" + size +
171-
") doesn't fit in buffer, position: " + pointer +
172-
", total length: " + pfbdata.length);
170+
throw new EOFException("attempted to read " + size + " bytes at position " + pointer +
171+
" into array of size " + pfbdata.length + ", but only space for " +
172+
(pfbdata.length - pointer) + " bytes left");
173173
}
174174
int got = in.read(pfbdata, pointer, size);
175175
if (got < 0)

library/src/main/java/com/tom_roush/fontbox/ttf/CmapSubtable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ public Integer getCharacterCode(int gid)
663663

664664
private int getCharCode(int gid)
665665
{
666-
if (gid < 0 || gid >= glyphIdToCharacterCode.length)
666+
if (gid < 0 || glyphIdToCharacterCode == null || gid >= glyphIdToCharacterCode.length)
667667
{
668668
return -1;
669669
}

library/src/main/java/com/tom_roush/fontbox/ttf/GlyphTable.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public class GlyphTable extends TTFTable
3939

4040
private int cached = 0;
4141

42+
private HorizontalMetricsTable hmt = null;
43+
4244
/**
4345
* Don't even bother to cache huge fonts.
4446
*/
@@ -75,6 +77,12 @@ void read(TrueTypeFont ttf, TTFDataStream data) throws IOException
7577

7678
// we don't actually read the complete table here because it can contain tens of thousands of glyphs
7779
this.data = data;
80+
81+
// PDFBOX-5460: read hmtx table early to avoid deadlock if getGlyph() locks "data"
82+
// and then locks TrueTypeFont to read this table, while another thread
83+
// locks TrueTypeFont and then tries to lock "data"
84+
hmt = font.getHorizontalMetrics();
85+
7886
initialized = true;
7987
}
8088

@@ -207,7 +215,6 @@ public GlyphData getGlyph(int gid) throws IOException
207215
private GlyphData getGlyphData(int gid) throws IOException
208216
{
209217
GlyphData glyph = new GlyphData();
210-
HorizontalMetricsTable hmt = font.getHorizontalMetrics();
211218
int leftSideBearing = hmt == null ? 0 : hmt.getLeftSideBearing(gid);
212219
glyph.initData(this, data, leftSideBearing);
213220
// resolve composite glyph

library/src/main/java/com/tom_roush/fontbox/type1/Type1Parser.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,11 @@ private void readSubrs(int lenIV) throws IOException
744744

745745
// RD
746746
Token charstring = read(Token.CHARSTRING);
747-
font.subrs.set(index.intValue(), decrypt(charstring.getData(), CHARSTRING_KEY, lenIV));
747+
int j = index.intValue();
748+
if (j < font.subrs.size())
749+
{
750+
font.subrs.set(j, decrypt(charstring.getData(), CHARSTRING_KEY, lenIV));
751+
}
748752
readPut();
749753
}
750754
readDef();

library/src/main/java/com/tom_roush/pdfbox/contentstream/PDFStreamEngine.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -682,12 +682,12 @@ else if(obj instanceof COSString)
682682
}
683683
else if (obj instanceof COSArray)
684684
{
685-
Log.e("PdfBox-Android", "Nested arrays are not allowed in an array for TJ operation:" + obj);
685+
Log.e("PdfBox-Android", "Nested arrays are not allowed in an array for TJ operation: " + obj);
686686
}
687687
else
688688
{
689-
throw new IOException("Unknown type " + obj.getClass().getSimpleName()
690-
+ " in array for TJ operation:" + obj);
689+
Log.e("PdfBox-Android", "Unknown type " + obj.getClass().getSimpleName()
690+
+ " in array for TJ operation: " + obj);
691691
}
692692
}
693693
}

0 commit comments

Comments
 (0)