diff --git a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$1.class b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$1.class index 126b7c0..55f87ba 100644 Binary files a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$1.class and b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$1.class differ diff --git a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$Backend.class b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$Backend.class index ff477d8..2c503da 100644 Binary files a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$Backend.class and b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$Backend.class differ diff --git a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ConflictMode.class b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ConflictMode.class index 44ea2ec..6376bb2 100644 Binary files a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ConflictMode.class and b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ConflictMode.class differ diff --git a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ExtractionRequest.class b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ExtractionRequest.class index 9653dc0..627e041 100644 Binary files a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ExtractionRequest.class and b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ExtractionRequest.class differ diff --git a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ProgressTracker.class b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ProgressTracker.class index e9e2f06..025b84d 100644 Binary files a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ProgressTracker.class and b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$ProgressTracker.class differ diff --git a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$SevenZipArchiveContext.class b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$SevenZipArchiveContext.class index 5535b31..4beedba 100644 Binary files a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$SevenZipArchiveContext.class and b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$SevenZipArchiveContext.class differ diff --git a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$SevenZipVolumeCallback.class b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$SevenZipVolumeCallback.class index 43368bf..c97127d 100644 Binary files a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$SevenZipVolumeCallback.class and b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$SevenZipVolumeCallback.class differ diff --git a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$WrongPasswordException.class b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$WrongPasswordException.class index 912a44b..d20b173 100644 Binary files a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$WrongPasswordException.class and b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain$WrongPasswordException.class differ diff --git a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain.class b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain.class index 41b88f1..7b8993e 100644 Binary files a/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain.class and b/resources/extractor-jvm/classes/com/sucukdeluxe/extractor/JBindExtractorMain.class differ diff --git a/resources/extractor-jvm/src/com/sucukdeluxe/extractor/JBindExtractorMain.java b/resources/extractor-jvm/src/com/sucukdeluxe/extractor/JBindExtractorMain.java index c50160d..e179646 100644 --- a/resources/extractor-jvm/src/com/sucukdeluxe/extractor/JBindExtractorMain.java +++ b/resources/extractor-jvm/src/com/sucukdeluxe/extractor/JBindExtractorMain.java @@ -11,6 +11,7 @@ import net.sf.sevenzipjbinding.IInStream; import net.sf.sevenzipjbinding.ISequentialOutStream; import net.sf.sevenzipjbinding.ICryptoGetTextPassword; import net.sf.sevenzipjbinding.PropID; +import net.sf.sevenzipjbinding.ArchiveFormat; import net.sf.sevenzipjbinding.SevenZip; import net.sf.sevenzipjbinding.SevenZipException; import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream; @@ -328,13 +329,9 @@ public final class JBindExtractorMain { String effectivePassword = password == null ? "" : password; SevenZipVolumeCallback callback = new SevenZipVolumeCallback(archiveFile, effectivePassword); - // Multi-volume archives need VolumedArchiveInStream so 7z-JBinding can - // request additional volumes via the IArchiveOpenVolumeCallback. - boolean isMultiVolume = SEVEN_ZIP_SPLIT_RE.matcher(nameLower).matches() - || RAR_MULTIPART_RE.matcher(nameLower).matches() - || hasOldStyleRarSplits(archiveFile); - - if (isMultiVolume) { + // VolumedArchiveInStream is ONLY for .7z.001 split archives. + // It internally checks for the ".7z.001" suffix and rejects everything else. + if (SEVEN_ZIP_SPLIT_RE.matcher(nameLower).matches()) { VolumedArchiveInStream volumed = new VolumedArchiveInStream(archiveFile.getName(), callback); IInArchive archive = SevenZip.openInArchive(null, volumed, callback); return new SevenZipArchiveContext(archive, null, volumed, callback); @@ -342,6 +339,35 @@ public final class JBindExtractorMain { RandomAccessFile raf = new RandomAccessFile(archiveFile, "r"); RandomAccessFileInStream stream = new RandomAccessFileInStream(raf); + + // Multi-part RAR (.part1.rar, .part2.rar or old-style .rar/.r01/.r02): + // Auto-detection with null format can fail for multi-volume RAR because + // 7z-JBinding may not fully recognize the format from a single part. + // Specify the format explicitly (try RAR5 first, then RAR4). + if (RAR_MULTIPART_RE.matcher(nameLower).matches() || hasOldStyleRarSplits(archiveFile)) { + ArchiveFormat[] rarFormats = { ArchiveFormat.RAR5, ArchiveFormat.RAR }; + Exception lastError = null; + for (ArchiveFormat fmt : rarFormats) { + try { + stream.seek(0L, 0); + IInArchive archive = SevenZip.openInArchive(fmt, stream, callback); + return new SevenZipArchiveContext(archive, stream, null, callback); + } catch (Exception e) { + lastError = e; + } + } + // Final attempt with auto-detection + try { + stream.seek(0L, 0); + IInArchive archive = SevenZip.openInArchive(null, stream, callback); + return new SevenZipArchiveContext(archive, stream, null, callback); + } catch (Exception e) { + // Close the RAF since we're about to throw + try { raf.close(); } catch (Throwable ignored) {} + throw lastError != null ? lastError : e; + } + } + IInArchive archive = SevenZip.openInArchive(null, stream, callback); return new SevenZipArchiveContext(archive, stream, null, callback); }