-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8304014: Convert test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java to junit #12563
Changes from 4 commits
bffeef4
f5609cb
faf8def
89d2f73
e931869
f2fd897
e6294bf
26e184f
e46fc5b
892e166
01c25e8
f58b57a
51e8883
f8c2cca
e32052f
4847083
3dde45f
c366b65
3b6d857
ac4f2b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,12 +50,75 @@ | |
|
||
public class CorruptedZipFiles { | ||
|
||
// Byte array holding a valid template ZIP | ||
/* | ||
* Byte array holding a valid template ZIP. | ||
* | ||
* This 'good' ZIP file has the following structure: | ||
* | ||
* 0000 LOCAL HEADER #1 04034B50 | ||
* 0004 Extract Zip Spec 14 '2.0' | ||
* 0005 Extract OS 00 'MS-DOS' | ||
* 0006 General Purpose Flag 0808 | ||
* [Bits 1-2] 0 'Normal Compression' | ||
* [Bit 3] 1 'Streamed' | ||
* [Bit 11] 1 'Language Encoding' | ||
* 0008 Compression Method 0008 'Deflated' | ||
* 000A Last Mod Time 567F7D07 'Fri Mar 31 15:40:14 2023' | ||
* 000E CRC 00000000 | ||
* 0012 Compressed Length 00000000 | ||
* 0016 Uncompressed Length 00000000 | ||
* 001A Filename Length 0001 | ||
* 001C Extra Length 0000 | ||
* 001E Filename 'x' | ||
* 001F PAYLOAD ... | ||
* | ||
* 0022 STREAMING DATA HEADER 08074B50 | ||
* 0026 CRC 8CDC1683 | ||
* 002A Compressed Length 00000003 | ||
* 002E Uncompressed Length 00000001 | ||
* | ||
* 0032 CENTRAL HEADER #1 02014B50 | ||
* 0036 Created Zip Spec 14 '2.0' | ||
* 0037 Created OS 00 'MS-DOS' | ||
* 0038 Extract Zip Spec 14 '2.0' | ||
* 0039 Extract OS 00 'MS-DOS' | ||
* 003A General Purpose Flag 0808 | ||
* [Bits 1-2] 0 'Normal Compression' | ||
* [Bit 3] 1 'Streamed' | ||
* [Bit 11] 1 'Language Encoding' | ||
* 003C Compression Method 0008 'Deflated' | ||
* 003E Last Mod Time 567F7D07 'Fri Mar 31 15:40:14 2023' | ||
* 0042 CRC 8CDC1683 | ||
* 0046 Compressed Length 00000003 | ||
* 004A Uncompressed Length 00000001 | ||
* 004E Filename Length 0001 | ||
* 0050 Extra Length 0000 | ||
* 0052 Comment Length 0000 | ||
* 0054 Disk Start 0000 | ||
* 0056 Int File Attributes 0000 | ||
* [Bit 0] 0 'Binary Data' | ||
* 0058 Ext File Attributes 00000000 | ||
* 005C Local Header Offset 00000000 | ||
* 0060 Filename 'x' | ||
* | ||
* 0061 END CENTRAL HEADER 06054B50 | ||
* 0065 Number of this disk 0000 | ||
* 0067 Central Dir Disk no 0000 | ||
* 0069 Entries in this disk 0001 | ||
* 006B Total Entries 0001 | ||
* 006D Size of Central Dir 0000002F | ||
* 0071 Offset to Central Dir 00000032 | ||
* 0075 Comment Length 0000 | ||
* | ||
*/ | ||
private static byte[] template; | ||
|
||
// Copy of the template ZIP for modification by each test | ||
private byte[] copy; | ||
|
||
// Litte-endian ByteBuffer for manipulating the ZIP copy | ||
private ByteBuffer buffer; | ||
|
||
// Some well-known locations in the ZIP | ||
private static int endpos, cenpos, locpos; | ||
|
||
|
@@ -103,6 +166,7 @@ public static void setup() throws IOException { | |
@BeforeEach | ||
public void makeCopy() { | ||
copy = template.clone(); | ||
buffer = ByteBuffer.wrap(copy).order(ByteOrder.LITTLE_ENDIAN); | ||
} | ||
|
||
/* | ||
|
@@ -114,40 +178,39 @@ public void cleanup() throws IOException { | |
} | ||
|
||
/* | ||
* An End of Central Directory header with a CEN size exceeding | ||
* past the offset of the End record itself should be rejected with | ||
* a ZipException. | ||
* Validate that a ZipException is thrown when the 'End of Central Directory' | ||
* (END) header has a CEN size exceeding past the offset of the END record | ||
*/ | ||
@Test | ||
public void excessiveCENSize() throws IOException { | ||
copy[endpos+ENDSIZ]=(byte)0xff; | ||
buffer.putInt(endpos+ENDSIZ, 0xff000000); | ||
assertZipException(".*bad central directory size.*"); | ||
} | ||
|
||
/* | ||
* An End of Central Directory header with a CEN offset incoherent | ||
* with the position calculated by subtracting the CEN size from | ||
* the End position should be rejected with a ZipException. | ||
* Validate that a ZipException is thrown when the 'End of Central Directory' | ||
* (END) header has a CEN offset incoherent with the position calculated | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure incoherent is the best term.
header contains an invalid CEN Directory starting offset..... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I remember my struggles trying to write this one in the first place. The code says: long cenpos = end.endpos - end.cenlen; // position of CEN table
// Get position of first local file (LOC) header, taking into
// account that there may be a stub prefixed to the zip file.
locpos = cenpos - end.cenoff;
if (locpos < 0) {
zerror("invalid END header (bad central directory offset)");
} so I ended up trying to express this equation in words, which is maybe not so successful. I don't see incoherent as the main problem, if it was we could just use inconsistent. Do you have a better concrete suggestion? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would keep it simple and indicate that the offset of start of central directory field within the End Header was given an invalid value |
||
* by subtracting the CEN size from the END offset. | ||
*/ | ||
@Test | ||
public void excessiveCENOffset() throws IOException { | ||
copy[endpos+ENDOFF]=(byte)0xff; | ||
buffer.putInt(endpos+ENDOFF, 0xff000000); | ||
assertZipException(".*bad central directory offset.*"); | ||
} | ||
|
||
/* | ||
* A CEN header with an unexpected signature should be rejected | ||
* with a ZipException. | ||
* Validate that a ZipException is thrown when a A CEN header has an unexpected signature | ||
*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change "a A" to "a" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
@Test | ||
public void invalidCENSignature() throws IOException { | ||
copy[cenpos]++; | ||
int existingSignature = buffer.getInt(cenpos); | ||
buffer.putInt(cenpos, existingSignature +1); | ||
assertZipException(".*bad signature.*"); | ||
} | ||
|
||
/* | ||
* A CEN header where the general purpose bit flag 0 ('encrypted') | ||
* is set should be rejected with a ZipException | ||
* Validate that a ZipException is thrown when a CEN header has the 'general | ||
* purpose bit flag 0' ('encrypted') set. | ||
*/ | ||
@Test | ||
public void encryptedEntry() throws IOException { | ||
|
@@ -156,70 +219,76 @@ public void encryptedEntry() throws IOException { | |
} | ||
|
||
/* | ||
* A File name length which makes the CEN header overflow into the | ||
* End of central directory record should be rejected with a ZipException. | ||
* Validate that a ZipException is thrown when a CEN header has a | ||
* file name length which makes the CEN header overflow into the | ||
* 'End of central directory' record. | ||
*/ | ||
@Test | ||
public void excessiveFileNameLength() throws IOException { | ||
copy[cenpos+CENNAM]++; | ||
short existingNameLength = buffer.getShort(cenpos + CENNAM); | ||
buffer.putShort(cenpos+CENNAM, (short) (existingNameLength + 1)); | ||
assertZipException(".*bad header size.*"); | ||
} | ||
|
||
/* | ||
* A File name length which makes the CEN header overflow into the | ||
* End of central directory record should be rejected with a ZipException. | ||
* Validate that a ZipException is thrown when a CEN header has a | ||
* file name length which makes the CEN header overflow into the | ||
* 'End of central directory' record. | ||
*/ | ||
@Test | ||
public void excessiveFileNameLength2() throws IOException { | ||
copy[cenpos+CENNAM] = (byte)0xfd; | ||
copy[cenpos+CENNAM+1] = (byte)0xfd; | ||
buffer.putShort(cenpos + CENNAM, (short) 0xfdfd); | ||
assertZipException(".*bad header size.*"); | ||
} | ||
|
||
/* | ||
* If the last CEN header is not immediatly followed by the start | ||
* of the End record, this should be rejected with a ZipException. | ||
* Validate that a ZipException is thrown if the last CEN header is | ||
* not immediatly followed by the start of the 'End of central directory' record | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo: immediatly There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, fixed. |
||
*/ | ||
@Test | ||
public void insufficientFilenameLength() throws IOException { | ||
copy[cenpos+CENNAM]--; | ||
short existingNameLength = buffer.getShort(cenpos + CENNAM); | ||
buffer.putShort(cenpos+CENNAM, (short) (existingNameLength - 1)); | ||
assertZipException(".*bad header size.*"); | ||
} | ||
|
||
/* | ||
* An Extra field length which makes the CEN header overflow into the | ||
* End of central directory record should be rejected with a ZipException. | ||
* Validate that a ZipException is thrown if a CEN header has an | ||
* extra field length which makes the CEN header overflow into the | ||
* End of central directory record. | ||
*/ | ||
@Test | ||
public void excessiveExtraFieldLength() throws IOException { | ||
copy[cenpos+CENEXT]++; | ||
short existingExtraLength = buffer.getShort(cenpos + CENEXT); | ||
buffer.putShort(cenpos+CENEXT, (short) (existingExtraLength + 1)); | ||
assertZipException(".*bad header size.*"); | ||
} | ||
|
||
/* | ||
* An Extra field length which makes the CEN header overflow into the | ||
* End of central directory record should be rejected with a ZipException. | ||
* Validate that a ZipException is thrown if a CEN header has an | ||
* extra field length which makes the CEN header overflow into the | ||
* End of central directory record. | ||
*/ | ||
@Test | ||
public void excessiveExtraFieldLength2() throws IOException { | ||
copy[cenpos+CENEXT] = (byte)0xfd; | ||
copy[cenpos+CENEXT+1] = (byte)0xfd; | ||
buffer.putShort(cenpos+CENEXT, (short) 0xfdfd); | ||
assertZipException(".*bad header size.*"); | ||
} | ||
|
||
/* | ||
* A File comment length which makes the CEN header overflow into the | ||
* End of central directory record should be rejected with a ZipException. | ||
* Validate that a ZipException is thrown when a CEN header has a comment length | ||
* which overflows into the 'End of central directory' record | ||
*/ | ||
@Test | ||
public void excessiveCommentLength() throws IOException { | ||
copy[cenpos+CENCOM]++; | ||
short existingCommentLength = buffer.getShort(cenpos + CENCOM); | ||
buffer.putShort(cenpos+CENCOM, (short) (existingCommentLength + 1)); | ||
assertZipException(".*bad header size.*"); | ||
} | ||
|
||
/* | ||
* A CEN header with an unsupported compression method should be rejected | ||
* with a ZipException. | ||
* Validate that a ZipException is thrown when a CEN header has a | ||
* compression method field which is unsupported by the implementation | ||
*/ | ||
@Test | ||
public void unsupportedCompressionMethod() throws IOException { | ||
|
@@ -228,12 +297,12 @@ public void unsupportedCompressionMethod() throws IOException { | |
} | ||
|
||
/* | ||
* A LOC header with an unexpected signature should be rejected | ||
* with a ZipException. | ||
* Validate that a ZipException is thrown when a LOC header has an unexpected signature | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would leave off "Validate that" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, updated all test comments to strip this shared prefix. |
||
*/ | ||
@Test | ||
public void invalidLOCSignature() throws IOException { | ||
copy[locpos]++; | ||
int existingSignatur = buffer.getInt(locpos); | ||
buffer.putInt(locpos, existingSignatur +1); | ||
assertZipException(".*bad signature.*"); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change this -> the
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.