Skip to content

Nested archives are corrput after extraction from RAR5 #75

@Saifytdin

Description

@Saifytdin

Thanks for Library!

Find an issue whith net.sf.sevenzipjbinding ver 16.02-2.01:
If RAR5 archive has nested archive 7z or zip files, they become corrupted after extraction via net.sf.sevenzipjbinding ver 16.02-2.01

Test case scenario:
Gradle deps:
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
implementation 'net.sf.sevenzipjbinding:sevenzipjbinding:16.02-2.01'
implementation 'net.sf.sevenzipjbinding:sevenzipjbinding-all-platforms:16.02-2.01'
}

RarExtractor class:
`import net.sf.sevenzipjbinding.ExtractOperationResult;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * Responsible for unpacking archives with the RAR extension.
 * Support Rar4, Rar4 with password, Rar5, Rar5 with password.
 * Determines the type of archive itself.
 */
public class RarExtractor {

    /**
     * Extracts files from archive. Archive can be encrypted with password
     *
     * @param filePath path to .rar file
     * @param password string password for archive
     * @return map of extracted file with file name
     * @throws IOException
     */
    public Map<InputStream, String> extract(String filePath, String password) throws IOException {
        Map<InputStream, String> extractedMap = new HashMap<>();

        RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "r");
        RandomAccessFileInStream randomAccessFileStream = new RandomAccessFileInStream(randomAccessFile);
        IInArchive inArchive = SevenZip.openInArchive(null, randomAccessFileStream);

        for (ISimpleInArchiveItem item : inArchive.getSimpleInterface().getArchiveItems()) {
            if (!item.isFolder()) {
                ExtractOperationResult result = item.extractSlow(data -> {
                    extractedMap.put(new BufferedInputStream(new ByteArrayInputStream(data)), item.getPath());

                    return data.length;
                }, password);

                if (result != ExtractOperationResult.OK) {
                    throw new RuntimeException(
                            String.format("Error extracting archive. Extracting error: %s", result));
                }
            }
        }

        return extractedMap;
    }
}

Main:

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Map;

public class Main {
    public static void main(String[] args) throws IOException {
        RarExtractor rarExtractor = new RarExtractor();
        //Map<InputStream, String> result = rarExtractor.extract("D:/script_winrar_5_internal_7z.rar", "");
        Map<InputStream, String> result = rarExtractor.extract("D:/script.7z", "");

        for (Map.Entry<InputStream, String> entry: result.entrySet()){
            try (InputStream inputStream = entry.getKey()) {
                Files.copy(inputStream, Paths.get("D:/script.zip"), StandardCopyOption.REPLACE_EXISTING);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Same issue if zip has nested 7z- extracted 7z is corrupt.

But no such issue if:
RAR5 has nested RAR5- after extraction nested RAR5 opens without error and its contents can be extracted.
zip has nested RAR5- ^^
7z has nested RAR5- ^^

Any ideas how to fix this issue?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions