Skip to content

Commit

Permalink
Support JvmZipReader toggle for skipping 'duplicate' entries
Browse files Browse the repository at this point in the history
  • Loading branch information
Col-E committed Sep 21, 2023
1 parent 0d1f64d commit f12a1c5
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 9 deletions.
2 changes: 1 addition & 1 deletion dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ project.ext {
junit_engine = "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
junit_params = "org.junit.jupiter:junit-jupiter-params:$junitVersion"

llzip = 'software.coley:lljzip:2.2.0'
llzip = 'software.coley:lljzip:2.3.0'

logging_impl = 'ch.qos.logback:logback-classic:1.2.10' // newer releases break in jar releases

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ private WorkspaceFileResource handleZip(WorkspaceResourceBuilder builder, ZipFil

// Read ZIP entries
boolean isAndroid = zipInfo.getName().toLowerCase().endsWith(".apk");
ZipArchive archive = config.getZipStrategy().getValue().mapping().apply(source.readAll());
ZipArchive archive = config.mapping().apply(source.readAll());
archive.getLocalFiles().forEach(header -> {
LocalFileHeaderSource headerSource = new LocalFileHeaderSource(header, isAndroid);
String entryName = header.getFileNameAsString();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package software.coley.recaf.workspace.io;

import jakarta.annotation.Nonnull;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import software.coley.lljzip.ZipIO;
import software.coley.lljzip.format.model.CentralDirectoryFileHeader;
import software.coley.lljzip.format.model.LocalFileHeader;
import software.coley.lljzip.format.model.ZipArchive;
import software.coley.lljzip.format.read.JvmZipReader;
import software.coley.observables.ObservableBoolean;
import software.coley.observables.ObservableObject;
import software.coley.recaf.config.BasicConfigContainer;
import software.coley.recaf.config.BasicConfigValue;
Expand All @@ -19,33 +24,56 @@
@ApplicationScoped
public class ResourceImporterConfig extends BasicConfigContainer implements ServiceConfig {
private final ObservableObject<ZipStrategy> zipStrategy = new ObservableObject<>(ZipStrategy.JVM);
private final ObservableBoolean skipRevisitedCenToLocalLinks = new ObservableBoolean(true);

@Inject
public ResourceImporterConfig() {
super(ConfigGroups.SERVICE_IO, ResourceImporter.SERVICE_ID + CONFIG_SUFFIX);

addValue(new BasicConfigValue<>("zip-strategy", ZipStrategy.class, zipStrategy));
addValue(new BasicConfigValue<>("skip-revisited-cen-to-local-links", boolean.class, skipRevisitedCenToLocalLinks));
}

/**
* @return ZIP strategy.
*/
@Nonnull
public ObservableObject<ZipStrategy> getZipStrategy() {
return zipStrategy;
}

/**
* When the {@link #getZipStrategy() ZIP strategy} is {@link ZipStrategy#JVM} this allows toggling
* skipping <i>"duplicate"</i> entries where multiple {@link CentralDirectoryFileHeader} can point to the
* same offset <i>({@link LocalFileHeader})</i>. Skipping is {@code true} by default.
*
* @return {@code true} when skipping N-to-1 mapping of
* {@link CentralDirectoryFileHeader} to {@link LocalFileHeader} for {@link ZipStrategy#JVM}.
*/
@Nonnull
public ObservableBoolean getSkipRevisitedCenToLocalLinks() {
return skipRevisitedCenToLocalLinks;
}

/**
* @return Mapping of input bytes to a ZIP archive model.
*/
@Nonnull
public UncheckedFunction<byte[], ZipArchive> mapping() {
ZipStrategy strategy = zipStrategy.getValue();
if (strategy == ZipStrategy.JVM)
return input -> ZipIO.read(input, new JvmZipReader(skipRevisitedCenToLocalLinks.getValue()));
if (strategy == ZipStrategy.STANDARD)
return ZipIO::readStandard;
return ZipIO::readNaive;
}

/**
* Mirrors strategies available in {@link ZipIO}.
*/
public enum ZipStrategy {
JVM,
STANDARD,
NAIVE;

public UncheckedFunction<byte[], ZipArchive> mapping() {
if (this == JVM) return ZipIO::readJvm;
else if (this == STANDARD) return ZipIO::readStandard;
else return ZipIO::readNaive;
}
NAIVE
}
}
1 change: 1 addition & 0 deletions recaf-ui/src/main/resources/translations/en_US.lang
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ service.io.recent-workspaces-config.max-recent-workspaces=Maximum record of rece
service.io.recent-workspaces-config.recent-workspaces=Recent workspace
service.io.resource-importer-config=Archive importing
service.io.resource-importer-config.zip-strategy=ZIP parsing strategy
service.io.resource-importer-config.skip-revisited-cen-to-local-links=Skip duplicate CEN-to-LOC entries with JVM strategy
service.mapping=Mapping
service.mapping.mapping-aggregator-config=Mapping aggregation
service.mapping.mapping-formats-config=Mapping formats
Expand Down

0 comments on commit f12a1c5

Please sign in to comment.