in src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java [1818:1936]
private void sanityCheckFilesInfo(final ByteBuffer header, final ArchiveStatistics stats) throws IOException {
stats.numberOfEntries = assertFitsIntoNonNegativeInt("numFiles", readUint64(header));
int emptyStreams = -1;
while (true) {
final int propertyType = getUnsignedByte(header);
if (propertyType == 0) {
break;
}
final long size = readUint64(header);
switch (propertyType) {
case NID.kEmptyStream: {
emptyStreams = readBits(header, stats.numberOfEntries).cardinality();
break;
}
case NID.kEmptyFile: {
if (emptyStreams == -1) {
throw new IOException("Header format error: kEmptyStream must appear before kEmptyFile");
}
readBits(header, emptyStreams);
break;
}
case NID.kAnti: {
if (emptyStreams == -1) {
throw new IOException("Header format error: kEmptyStream must appear before kAnti");
}
readBits(header, emptyStreams);
break;
}
case NID.kName: {
final int external = getUnsignedByte(header);
if (external != 0) {
throw new IOException("Not implemented");
}
final int namesLength = assertFitsIntoNonNegativeInt("file names length", size - 1);
if ((namesLength & 1) != 0) {
throw new IOException("File names length invalid");
}
int filesSeen = 0;
for (int i = 0; i < namesLength; i += 2) {
final char c = getChar(header);
if (c == 0) {
filesSeen++;
}
}
if (filesSeen != stats.numberOfEntries) {
throw new IOException("Invalid number of file names (" + filesSeen + " instead of " + stats.numberOfEntries + ")");
}
break;
}
case NID.kCTime: {
final int timesDefined = readAllOrBits(header, stats.numberOfEntries).cardinality();
final int external = getUnsignedByte(header);
if (external != 0) {
throw new IOException("Not implemented");
}
if (skipBytesFully(header, 8 * timesDefined) < 8 * timesDefined) {
throw new IOException("invalid creation dates size");
}
break;
}
case NID.kATime: {
final int timesDefined = readAllOrBits(header, stats.numberOfEntries).cardinality();
final int external = getUnsignedByte(header);
if (external != 0) {
throw new IOException("Not implemented");
}
if (skipBytesFully(header, 8 * timesDefined) < 8 * timesDefined) {
throw new IOException("invalid access dates size");
}
break;
}
case NID.kMTime: {
final int timesDefined = readAllOrBits(header, stats.numberOfEntries).cardinality();
final int external = getUnsignedByte(header);
if (external != 0) {
throw new IOException("Not implemented");
}
if (skipBytesFully(header, 8 * timesDefined) < 8 * timesDefined) {
throw new IOException("invalid modification dates size");
}
break;
}
case NID.kWinAttributes: {
final int attributesDefined = readAllOrBits(header, stats.numberOfEntries).cardinality();
final int external = getUnsignedByte(header);
if (external != 0) {
throw new IOException("Not implemented");
}
if (skipBytesFully(header, 4 * attributesDefined) < 4 * attributesDefined) {
throw new IOException("invalid windows attributes size");
}
break;
}
case NID.kStartPos: {
throw new IOException("kStartPos is unsupported, please report");
}
case NID.kDummy: {
// 7z 9.20 asserts the content is all zeros and ignores the property
// Compress up to 1.8.1 would throw an exception, now we ignore it (see COMPRESS-287
if (skipBytesFully(header, size) < size) {
throw new IOException("Incomplete kDummy property");
}
break;
}
default: {
// Compress up to 1.8.1 would throw an exception, now we ignore it (see COMPRESS-287
if (skipBytesFully(header, size) < size) {
throw new IOException("Incomplete property of type " + propertyType);
}
break;
}
}
}
stats.numberOfEntriesWithStream = stats.numberOfEntries - Math.max(emptyStreams, 0);
}