private void sanityCheckFilesInfo()

in src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java [1637:1761]


    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);
    }