Skip to content

Commit 2465516

Browse files
author
Erik Hetzner
committed
do not read past end of extra fields when reading extra field
1 parent d05415f commit 2465516

5 files changed

Lines changed: 25 additions & 5 deletions

File tree

src/main/java/org/archive/format/gzip/GZIPFExtraRecord.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,17 @@ public void writeTo(OutputStream os) throws IOException {
9898
os.write(value);
9999
}
100100
}
101-
public int read(InputStream is) throws IOException {
101+
public int read(InputStream is, int maxRead) throws IOException {
102102
byte tmpName[] = null;
103103
byte tmpVal[] = null;
104104
int valLen = 0;
105105
tmpName = ByteOp.readNBytes(is, GZIP_FEXTRA_NAME_BYTES);
106106
valLen = ByteOp.readShort(is);
107+
if (valLen > (maxRead - BYTES_IN_SHORT - GZIP_FEXTRA_NAME_BYTES)) {
108+
/* read in what's left, but throw an exception */
109+
tmpVal = ByteOp.readNBytes(is, maxRead - BYTES_IN_SHORT - GZIP_FEXTRA_NAME_BYTES);
110+
throw new GZIPFormatException.GZIPExtraFieldShortException(maxRead);
111+
}
107112
if(valLen > 0) {
108113
tmpVal = ByteOp.readNBytes(is, valLen);
109114
}

src/main/java/org/archive/format/gzip/GZIPFExtraRecords.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,17 @@ public void readRecords(InputStream is)
5353
ArrayList<GZIPFExtraRecord> tmpList = new ArrayList<GZIPFExtraRecord>();
5454
while(bytesRemaining > 0) {
5555
GZIPFExtraRecord tmpRecord = new GZIPFExtraRecord();
56-
int bytesRead = tmpRecord.read(is);
57-
bytesRemaining -= bytesRead;
56+
try {
57+
int bytesRead = tmpRecord.read(is, bytesRemaining);
58+
bytesRemaining -= bytesRead;
59+
tmpList.add(tmpRecord);
60+
} catch (GZIPFormatException.GZIPExtraFieldShortException ex) {
61+
/* not enough bytes for the extra field; move on */
62+
bytesRemaining -= ex.bytesRead;
63+
}
5864
if(bytesRemaining < 0) {
5965
throw new GZIPFormatException("Invalid FExtra length/records");
6066
}
61-
tmpList.add(tmpRecord);
6267
}
6368
this.addAll(tmpList);
6469
}

src/main/java/org/archive/format/gzip/GZIPFormatException.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,11 @@ public GZIPFormatException(Exception e) {
2121
public GZIPFormatException(String message, IOException e) {
2222
super(message,e);
2323
}
24+
public static class GZIPExtraFieldShortException extends GZIPFormatException {
25+
int bytesRead;
26+
public GZIPExtraFieldShortException(int bytesRead) {
27+
super("Extra Field short.");
28+
this.bytesRead = bytesRead;
29+
}
30+
}
2431
}

src/test/java/org/archive/format/gzip/GZIPMemberSeriesTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ public void testAutoSkip() throws IOException {
374374
assertNull(m);
375375
assertTrue(s.gotEOF());
376376
}
377-
378377

378+
public void testWgetProblem() throws IndexOutOfBoundsException, FileNotFoundException, IOException {
379+
InputStream is = getClass().getResourceAsStream("IAH-urls-wget.warc.gz");
380+
new GZIPDecoder().parseHeader(is);
381+
}
379382
}
42.6 KB
Binary file not shown.

0 commit comments

Comments
 (0)