Skip to content

Commit c324d5f

Browse files
committed
PDFBOX-5032: don't access the underlying source of the COSParser in classes which don't subclass COSParser
git-svn-id: https://svn.apache.org/repos/asf/pdfbox/trunk@1938531 13f79535-47bb-0310-9956-ffa450edef68
1 parent 89b0405 commit c324d5f

3 files changed

Lines changed: 112 additions & 82 deletions

File tree

‎pdfbox/src/main/java/org/apache/pdfbox/pdfparser/BaseParser.java‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,18 @@ protected void seek(long position) throws IOException
683683
source.seek(position);
684684
}
685685

686+
/**
687+
* Read a single byte of data.
688+
*
689+
* @return The byte of data that is being read.
690+
*
691+
* @throws IOException If there is an error while reading the data.
692+
*/
693+
protected int read() throws IOException
694+
{
695+
return source.read();
696+
}
697+
686698
/**
687699
* Read a buffer of data.
688700
*
@@ -697,6 +709,18 @@ protected int read(byte[] b, int offset, int length) throws IOException
697709
return source.read(b, offset, length);
698710
}
699711

712+
/**
713+
* This will peek at the next byte.
714+
*
715+
* @return The next byte on the stream, leaving it as available to read.
716+
*
717+
* @throws IOException If there is an error reading the next byte.
718+
*/
719+
protected int peek() throws IOException
720+
{
721+
return source.peek();
722+
}
723+
700724
/**
701725
* The total number of bytes that are available.
702726
*
@@ -709,4 +733,16 @@ protected long length() throws IOException
709733
return source.length();
710734
}
711735

736+
/**
737+
* Returns offset of next byte to be returned by a read method.
738+
*
739+
* @return offset of next byte which will be returned with next {@link #read()} (if no more bytes are left it
740+
* returns a value >= length of source)
741+
*
742+
* @throws IOException If there was an error while getting the current position
743+
*/
744+
protected long getPosition() throws IOException
745+
{
746+
return source.getPosition();
747+
}
712748
}

‎pdfbox/src/main/java/org/apache/pdfbox/pdfparser/BruteForceParser.java‎

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import org.apache.pdfbox.cos.COSObject;
3636
import org.apache.pdfbox.cos.COSObjectKey;
3737
import org.apache.pdfbox.cos.COSStream;
38-
import org.apache.pdfbox.io.RandomAccessRead;
3938
import org.apache.pdfbox.pdfparser.XrefTrailerResolver.XRefType;
4039
import org.apache.pdfbox.pdmodel.encryption.ProtectionPolicy;
4140
import org.apache.pdfbox.pdmodel.encryption.SecurityHandler;
@@ -80,7 +79,6 @@ public class BruteForceParser
8079

8180
private final COSParser parser;
8281
private final COSDocument document;
83-
private final RandomAccessRead source;
8482

8583
/**
8684
* Constructor. Triggers a brute force search for all objects of the document.
@@ -94,7 +92,6 @@ public BruteForceParser(COSDocument cosDocument, COSParser cosParser) throws IOE
9492
{
9593
document = cosDocument;
9694
parser = cosParser;
97-
source = parser.source;
9895
}
9996

10097
/**
@@ -133,7 +130,7 @@ protected Map<COSObjectKey, Long> getBFCOSObjectOffsets() throws IOException
133130
private void bfSearchForObjects() throws IOException
134131
{
135132
long lastEOFMarker = bfSearchForLastEOFMarker();
136-
long originOffset = source.getPosition();
133+
long originOffset = parser.getPosition();
137134
long currentOffset = MINIMUM_SEARCH_OFFSET;
138135
long lastObjectId = Long.MIN_VALUE;
139136
int lastGenID = Integer.MIN_VALUE;
@@ -143,35 +140,35 @@ private void bfSearchForObjects() throws IOException
143140
boolean endOfObjFound = false;
144141
do
145142
{
146-
source.seek(currentOffset);
147-
int nextChar = source.read();
143+
parser.seek(currentOffset);
144+
int nextChar = parser.read();
148145
currentOffset++;
149146
if (BaseParser.isWhitespace(nextChar) && parser.isString(OBJ_MARKER))
150147
{
151148
long tempOffset = currentOffset - 2;
152-
source.seek(tempOffset);
153-
int genID = source.peek();
149+
parser.seek(tempOffset);
150+
int genID = parser.peek();
154151
// is the next char a digit?
155152
if (BaseParser.isDigit(genID))
156153
{
157154
genID -= 48;
158155
tempOffset--;
159-
source.seek(tempOffset);
156+
parser.seek(tempOffset);
160157
if (parser.isWhitespace())
161158
{
162159
while (tempOffset > MINIMUM_SEARCH_OFFSET && parser.isWhitespace())
163160
{
164-
source.seek(--tempOffset);
161+
parser.seek(--tempOffset);
165162
}
166163
boolean objectIDFound = false;
167164
while (tempOffset > MINIMUM_SEARCH_OFFSET && parser.isDigit())
168165
{
169-
source.seek(--tempOffset);
166+
parser.seek(--tempOffset);
170167
objectIDFound = true;
171168
}
172169
if (objectIDFound)
173170
{
174-
source.read();
171+
parser.read();
175172
long objectId = parser.readObjectNumber();
176173
if (lastObjOffset > 0)
177174
{
@@ -194,7 +191,7 @@ private void bfSearchForObjects() throws IOException
194191
else if (nextChar == 'e' && parser.isString(endobjString))
195192
{
196193
currentOffset += endobjString.length;
197-
source.seek(currentOffset);
194+
parser.seek(currentOffset);
198195
if (parser.isEOF())
199196
{
200197
endOfObjFound = true;
@@ -214,7 +211,7 @@ else if (parser.isString(endobjRemainingString))
214211
lastObjOffset);
215212
}
216213
// reestablish origin position
217-
source.seek(originOffset);
214+
parser.seek(originOffset);
218215
}
219216

220217
/**
@@ -304,7 +301,7 @@ private long searchNearestValue(List<Long> values, long offset)
304301
protected void bfSearchForObjStreams(Map<COSObjectKey, Long> xrefTable) throws IOException
305302
{
306303
// save origin offset
307-
long originOffset = source.getPosition();
304+
long originOffset = parser.getPosition();
308305

309306
Map<Long, COSObjectKey> bfSearchForObjStreamOffsets = bfSearchForObjStreamOffsets();
310307
Map<COSObjectKey, Long> bfCOSObjectOffsets = getBFCOSObjectOffsets();
@@ -325,7 +322,7 @@ protected void bfSearchForObjStreams(Map<COSObjectKey, Long> xrefTable) throws I
325322
SecurityHandler<? extends ProtectionPolicy> securityHandler = parser.getSecurityHandler();
326323
for (Long offset : objStreamOffsets)
327324
{
328-
source.seek(offset);
325+
parser.seek(offset);
329326
long stmObjNumber = parser.readObjectNumber();
330327
int stmGenNumber = parser.readGenerationNumber();
331328
parser.readExpectedString(OBJ_MARKER, true);
@@ -371,7 +368,7 @@ protected void bfSearchForObjStreams(Map<COSObjectKey, Long> xrefTable) throws I
371368
}
372369
}
373370
// restore origin offset
374-
source.seek(originOffset);
371+
parser.seek(originOffset);
375372
}
376373

377374
/**
@@ -383,8 +380,8 @@ protected void bfSearchForObjStreams(Map<COSObjectKey, Long> xrefTable) throws I
383380
*/
384381
private boolean bfSearchForTrailer(COSDictionary trailer) throws IOException
385382
{
386-
long originOffset = source.getPosition();
387-
source.seek(MINIMUM_SEARCH_OFFSET);
383+
long originOffset = parser.getPosition();
384+
parser.seek(MINIMUM_SEARCH_OFFSET);
388385
// search for trailer marker
389386
long trailerOffset = findString(TRAILER_MARKER);
390387
while (trailerOffset != -1)
@@ -441,7 +438,7 @@ private boolean bfSearchForTrailer(COSDictionary trailer) throws IOException
441438
}
442439
trailerOffset = findString(TRAILER_MARKER);
443440
}
444-
source.seek(originOffset);
441+
parser.seek(originOffset);
445442
return false;
446443
}
447444

@@ -520,8 +517,8 @@ private COSObject compareCOSObjects(COSObject newObject, Long newOffset,
520517
private long bfSearchForLastEOFMarker() throws IOException
521518
{
522519
long lastEOFMarker = -1;
523-
long originOffset = source.getPosition();
524-
source.seek(MINIMUM_SEARCH_OFFSET);
520+
long originOffset = parser.getPosition();
521+
parser.seek(MINIMUM_SEARCH_OFFSET);
525522
long tempMarker = findString(EOF_MARKER);
526523
while (tempMarker != -1)
527524
{
@@ -546,7 +543,7 @@ private long bfSearchForLastEOFMarker() throws IOException
546543
}
547544
tempMarker = findString(EOF_MARKER);
548545
}
549-
source.seek(originOffset);
546+
parser.seek(originOffset);
550547
// no EOF marker found
551548
if (lastEOFMarker == -1)
552549
{
@@ -564,7 +561,7 @@ private long bfSearchForLastEOFMarker() throws IOException
564561
private Map<Long, COSObjectKey> bfSearchForObjStreamOffsets() throws IOException
565562
{
566563
HashMap<Long, COSObjectKey> bfSearchObjStreamsOffsets = new HashMap<>();
567-
source.seek(MINIMUM_SEARCH_OFFSET);
564+
parser.seek(MINIMUM_SEARCH_OFFSET);
568565
char[] string = " obj".toCharArray();
569566
// search for object stream marker
570567
long positionObjStream = findString(OBJ_STREAM);
@@ -578,31 +575,31 @@ private Map<Long, COSObjectKey> bfSearchForObjStreamOffsets() throws IOException
578575
long currentOffset = positionObjStream - (i * 10);
579576
if (currentOffset > 0)
580577
{
581-
source.seek(currentOffset);
578+
parser.seek(currentOffset);
582579
for (int j = 0; j < 10; j++)
583580
{
584581
if (parser.isString(string))
585582
{
586583
long tempOffset = currentOffset - 1;
587-
source.seek(tempOffset);
584+
parser.seek(tempOffset);
588585
// is the next char a digit?
589586
if (parser.isDigit())
590587
{
591588
tempOffset--;
592-
source.seek(tempOffset);
589+
parser.seek(tempOffset);
593590
if (parser.isSpace())
594591
{
595592
int length = 0;
596-
source.seek(--tempOffset);
593+
parser.seek(--tempOffset);
597594
while (tempOffset > MINIMUM_SEARCH_OFFSET && parser.isDigit())
598595
{
599-
source.seek(--tempOffset);
596+
parser.seek(--tempOffset);
600597
length++;
601598
}
602599
if (length > 0)
603600
{
604-
source.read();
605-
newOffset = source.getPosition();
601+
parser.read();
602+
newOffset = parser.getPosition();
606603
long objNumber = parser.readObjectNumber();
607604
int genNumber = parser.readGenerationNumber();
608605
COSObjectKey streamObjectKey = new COSObjectKey(objNumber,
@@ -618,12 +615,12 @@ private Map<Long, COSObjectKey> bfSearchForObjStreamOffsets() throws IOException
618615
else
619616
{
620617
currentOffset++;
621-
source.read();
618+
parser.read();
622619
}
623620
}
624621
}
625622
}
626-
source.seek(positionObjStream + OBJ_STREAM.length);
623+
parser.seek(positionObjStream + OBJ_STREAM.length);
627624
positionObjStream = findString(OBJ_STREAM);
628625
}
629626
return bfSearchObjStreamsOffsets;
@@ -638,18 +635,18 @@ private List<Long> bfSearchForXRefTables() throws IOException
638635
{
639636
List<Long> bfSearchXRefTablesOffsets = new ArrayList<>();
640637
// a pdf may contain more than one xref entry
641-
source.seek(MINIMUM_SEARCH_OFFSET);
638+
parser.seek(MINIMUM_SEARCH_OFFSET);
642639
// search for xref tables
643640
long newOffset = findString(XREF_TABLE);
644641
while (newOffset != -1)
645642
{
646-
source.seek(newOffset - 1);
643+
parser.seek(newOffset - 1);
647644
// ensure that we don't read "startxref" instead of "xref"
648645
if (parser.isWhitespace())
649646
{
650647
bfSearchXRefTablesOffsets.add(newOffset);
651648
}
652-
source.seek(newOffset + 4);
649+
parser.seek(newOffset + 4);
653650
newOffset = findString(XREF_TABLE);
654651
}
655652
return bfSearchXRefTablesOffsets;
@@ -664,7 +661,7 @@ private List<Long> bfSearchForXRefStreams() throws IOException
664661
{
665662
List<Long> bfSearchXRefStreamsOffsets = new ArrayList<>();
666663
// a pdf may contain more than one /XRef entry
667-
source.seek(MINIMUM_SEARCH_OFFSET);
664+
parser.seek(MINIMUM_SEARCH_OFFSET);
668665
// search for XRef streams
669666
String objString = " obj";
670667
char[] string = objString.toCharArray();
@@ -679,31 +676,31 @@ private List<Long> bfSearchForXRefStreams() throws IOException
679676
long currentOffset = xrefOffset - (i * 10);
680677
if (currentOffset > 0)
681678
{
682-
source.seek(currentOffset);
679+
parser.seek(currentOffset);
683680
for (int j = 0; j < 10; j++)
684681
{
685682
if (parser.isString(string))
686683
{
687684
long tempOffset = currentOffset - 1;
688-
source.seek(tempOffset);
685+
parser.seek(tempOffset);
689686
// is the next char a digit?
690687
if (parser.isDigit())
691688
{
692689
tempOffset--;
693-
source.seek(tempOffset);
690+
parser.seek(tempOffset);
694691
if (parser.isSpace())
695692
{
696693
int length = 0;
697-
source.seek(--tempOffset);
694+
parser.seek(--tempOffset);
698695
while (tempOffset > MINIMUM_SEARCH_OFFSET && parser.isDigit())
699696
{
700-
source.seek(--tempOffset);
697+
parser.seek(--tempOffset);
701698
length++;
702699
}
703700
if (length > 0)
704701
{
705-
source.read();
706-
newOffset = source.getPosition();
702+
parser.read();
703+
newOffset = parser.getPosition();
707704
}
708705
}
709706
}
@@ -715,7 +712,7 @@ private List<Long> bfSearchForXRefStreams() throws IOException
715712
else
716713
{
717714
currentOffset++;
718-
source.read();
715+
parser.read();
719716
}
720717
}
721718
}
@@ -724,7 +721,7 @@ private List<Long> bfSearchForXRefStreams() throws IOException
724721
{
725722
bfSearchXRefStreamsOffsets.add(newOffset);
726723
}
727-
source.seek(xrefOffset + 5);
724+
parser.seek(xrefOffset + 5);
728725
xrefOffset = findString(XREF_STREAM);
729726
}
730727
return bfSearchXRefStreamsOffsets;
@@ -778,14 +775,14 @@ private long findString(char[] string) throws IOException
778775
long position = -1L;
779776
int stringLength = string.length;
780777
int counter = 0;
781-
int readChar = source.read();
778+
int readChar = parser.read();
782779
while (readChar != -1)
783780
{
784781
if (readChar == string[counter])
785782
{
786783
if (counter == 0)
787784
{
788-
position = source.getPosition() - 1;
785+
position = parser.getPosition() - 1;
789786
}
790787
counter++;
791788
if (counter == stringLength)
@@ -799,7 +796,7 @@ else if (counter > 0)
799796
position = -1L;
800797
continue;
801798
}
802-
readChar = source.read();
799+
readChar = parser.read();
803800
}
804801
return position;
805802
}

0 commit comments

Comments
 (0)