Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,7 @@ private CpioArchiveEntry readNewEntry(final boolean hasCrc) throws IOException {
}
newEntry.setInode(readAsciiLong(8, 16));
final long mode = readAsciiLong(8, 16);
if (CpioUtil.fileType(mode) != 0) { // mode is initialized to 0
newEntry.setMode(mode);
}
setMode(newEntry, mode);
newEntry.setUID(readAsciiLong(8, 16));
newEntry.setGID(readAsciiLong(8, 16));
newEntry.setNumberOfLinks(readAsciiLong(8, 16));
Expand Down Expand Up @@ -470,9 +468,7 @@ private CpioArchiveEntry readOldAsciiEntry() throws IOException {
ret.setDevice(readAsciiLong(6, 8));
ret.setInode(readAsciiLong(6, 8));
final long mode = readAsciiLong(6, 8);
if (CpioUtil.fileType(mode) != 0) {
ret.setMode(mode);
}
setMode(ret, mode);
ret.setUID(readAsciiLong(6, 8));
ret.setGID(readAsciiLong(6, 8));
ret.setNumberOfLinks(readAsciiLong(6, 8));
Expand Down Expand Up @@ -500,9 +496,7 @@ private CpioArchiveEntry readOldBinaryEntry(final boolean swapHalfWord) throws I
oldEntry.setDevice(readBinaryLong(2, swapHalfWord));
oldEntry.setInode(readBinaryLong(2, swapHalfWord));
final long mode = readBinaryLong(2, swapHalfWord);
if (CpioUtil.fileType(mode) != 0) {
oldEntry.setMode(mode);
}
setMode(oldEntry, mode);
oldEntry.setUID(readBinaryLong(2, swapHalfWord));
oldEntry.setGID(readBinaryLong(2, swapHalfWord));
oldEntry.setNumberOfLinks(readBinaryLong(2, swapHalfWord));
Expand Down Expand Up @@ -538,6 +532,27 @@ private byte[] readRange(final int len) throws IOException {
return b;
}

/**
* Sets the mode of an entry from a header field.
* <p>
* A mode of 0 is left unset because only the trailer may use it; the callers check that by name.
* </p>
*
* @param entry The entry to update.
* @param mode The mode read from the header.
* @throws ArchiveException if the mode names a file type CPIO does not define.
*/
private void setMode(final CpioArchiveEntry entry, final long mode) throws ArchiveException {
if (CpioUtil.fileType(mode) == 0) {
return;
}
try {
entry.setMode(mode);
} catch (final IllegalArgumentException e) {
throw new ArchiveException("Corrupted CPIO archive: Invalid file mode 0%s at byte: %,d", Long.toOctalString(mode), getBytesRead());
}
}
Comment on lines +545 to +554

private int skip(final int length) throws IOException {
// bytes cannot be more than 3 bytes
return length > 0 ? readFully(buffer4, 0, length) : 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,79 @@ void testEndOfFileInEntry_c_namesize_0xFFFFFFFF() throws Exception {
}
}

@Test
void testInvalidFileTypeInMode() throws Exception {
// c_mode declares file type 0170000, which CPIO does not define
// @formatter:off
final String header =
"070701" + // c_magic
"00000001" + // c_ino
"0000F000" + // c_mode
"00000000" + // c_uid
"00000000" + // c_gid
"00000001" + // c_nlink
"00000000" + // c_mtime
"00000000" + // c_filesize
"00000000" + // c_devmajor
"00000000" + // c_devminor
"00000000" + // c_rdevmajor
"00000000" + // c_rdevminor
"00000002" + // c_namesize
"00000000" + // c_check
"a\0";
// @formatter:on
try (CpioArchiveInputStream cpio = CpioArchiveInputStream.builder()
.setByteArray(header.getBytes(StandardCharsets.US_ASCII))
.get()) {
assertThrows(ArchiveException.class, cpio::getNextEntry);
}
Comment on lines +199 to +203
}

@Test
void testInvalidFileTypeInModeMagicOldAscii() throws Exception {
// c_mode declares file type 0170000, which CPIO does not define
// @formatter:off
final String header =
"070707" + // c_magic
"000000" + // c_dev
"000001" + // c_ino
"170000" + // c_mode
"000000" + // c_uid
"000000" + // c_gid
"000001" + // c_nlink
"000000" + // c_rdev
"00000000000" + // c_mtime
"000002" + // c_namesize
"00000000000" + // c_filesize
"a\0";
// @formatter:on
try (CpioArchiveInputStream cpio = CpioArchiveInputStream.builder()
.setByteArray(header.getBytes(StandardCharsets.US_ASCII))
.get()) {
assertThrows(ArchiveException.class, cpio::getNextEntry);
}
}

@Test
void testInvalidFileTypeInModeMagicOldBinary() throws Exception {
// c_mode declares file type 0170000, which CPIO does not define
// c_magic, c_dev, c_ino, c_mode, c_uid, c_gid, c_nlink, c_rdev as little endian half words
final int[] halfWords = { 070707, 0, 1, 0170000, 0, 0, 1, 0 };
final byte[] data = new byte[halfWords.length * 2 + 10 + 2];
int off = 0;
for (final int halfWord : halfWords) {
data[off++] = (byte) halfWord;
data[off++] = (byte) (halfWord >> 8);
}
off += 4; // c_mtime
data[off] = 2; // c_namesize
off += 6; // c_namesize and c_filesize
data[off] = 'a';
try (CpioArchiveInputStream cpio = CpioArchiveInputStream.builder().setByteArray(data).get()) {
assertThrows(ArchiveException.class, cpio::getNextEntry);
}
}

@Test
void testInvalidLongValueInMetadata() throws Exception {
try (CpioArchiveInputStream archive = CpioArchiveInputStream.builder()
Expand Down
Loading