Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove SnakeYAML for manual YAML Parser #3191

Merged
merged 8 commits into from
Jul 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion brut.apktool/apktool-cli/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ tasks.register('proguard', ProGuardTask) {
dontwarn 'javax.xml.xpath.**'
dontnote '**'
// between Java 1.8 and 1.9, the signature of `flip()` changed, which trips up proguard.
dontwarn 'org.yaml.snakeyaml.scanner.ScannerImpl'

def outPath = jar.getDestinationDirectory().getAsFile().get().toString()
def extension = jar.archiveExtension.get().toString()
Expand Down
1 change: 0 additions & 1 deletion brut.apktool/apktool-lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ dependencies {

implementation depends.baksmali
implementation depends.smali
implementation depends.snakeyaml
implementation depends.xmlpull
implementation depends.guava
implementation depends.commons_lang
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public ApkInfo decode(File outDir) throws AndrolibException, IOException, Direct

copyRawFiles(outDir);
copyUnknownFiles(apkInfo, outDir);
Collection<String> mUncompressedFiles = new ArrayList<>();
List<String> mUncompressedFiles = new ArrayList<>();
recordUncompressedFiles(apkInfo, resourcesDecoder.getResFileMapping(), mUncompressedFiles);
copyOriginalFiles(outDir);
writeApkInfo(apkInfo, outDir);
Expand Down Expand Up @@ -220,11 +220,7 @@ private boolean hasMultipleSources() throws AndrolibException {
}

private void writeApkInfo(ApkInfo apkInfo, File outDir) throws AndrolibException {
try {
apkInfo.save(new File(outDir, "apktool.yml"));
} catch (IOException ex) {
throw new AndrolibException(ex);
}
apkInfo.save(new File(outDir, "apktool.yml"));
}

private void copyManifestRaw(File outDir)
Expand Down Expand Up @@ -376,7 +372,7 @@ private void copyOriginalFiles(File outDir)

private void recordUncompressedFiles(ApkInfo apkInfo,
Map<String, String> resFileMapping,
Collection<String> uncompressedFilesOrExts)
List<String> uncompressedFilesOrExts)
throws AndrolibException {
try {
Directory unk = mApkFile.getDirectory();
Expand Down
133 changes: 96 additions & 37 deletions brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,14 @@
import brut.androlib.res.data.ResConfigFlags;
import brut.directory.DirectoryException;
import brut.directory.FileDirectory;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.introspector.PropertyUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ApkInfo {
public class ApkInfo implements YamlSerializable {
public String version;

private String apkFileName;
Expand All @@ -45,7 +41,7 @@ public class ApkInfo {
public boolean sharedLibrary;
public boolean sparseResources;
public Map<String, String> unknownFiles;
public Collection<String> doNotCompress;
public List<String> doNotCompress;

/** @deprecated use {@link #resourcesAreCompressed} */
public boolean compressionType;
Expand All @@ -54,26 +50,6 @@ public ApkInfo() {
this.version = ApktoolProperties.getVersion();
}

private static Yaml getYaml() {
DumperOptions dumpOptions = new DumperOptions();
dumpOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);

EscapedStringRepresenter representer = new EscapedStringRepresenter();
PropertyUtils propertyUtils = representer.getPropertyUtils();
propertyUtils.setSkipMissingProperties(true);

LoaderOptions loaderOptions = new LoaderOptions();
loaderOptions.setCodePointLimit(10 * 1024 * 1024); // 10mb

return new Yaml(new ClassSafeConstructor(), representer, dumpOptions, loaderOptions);
}

public void save(Writer output) {
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
getYaml().dump(this, output);
}

public String checkTargetSdkVersionBounds() {
int target = mapSdkShorthandToVersion(getTargetSdkVersion());

Expand Down Expand Up @@ -157,28 +133,111 @@ private int mapSdkShorthandToVersion(String sdkVersion) {
}
}

public void save(File file) throws IOException {
try(
FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
Writer writer = new BufferedWriter(outputStreamWriter)
public void save(File file) throws AndrolibException {
try (
YamlWriter writer = new YamlWriter(new FileOutputStream(file));
) {
save(writer);
write(writer);
} catch (FileNotFoundException e) {
throw new AndrolibException("File not found");
} catch (Exception e) {
throw new AndrolibException(e);
}
}

public static ApkInfo load(InputStream is) {
return getYaml().loadAs(is, ApkInfo.class);
public static ApkInfo load(InputStream is) throws AndrolibException {
// return getYaml().loadAs(is, ApkInfo.class);
YamlReader reader = new YamlReader(is);
ApkInfo apkInfo = new ApkInfo();
reader.readRoot(apkInfo);
return apkInfo;
}

public static ApkInfo load(File appDir)
throws AndrolibException {
try(
InputStream in = new FileDirectory(appDir).getFileInput("apktool.yml")
InputStream in = new FileDirectory(appDir).getFileInput("apktool.yml");
) {
return ApkInfo.load(in);
} catch (DirectoryException | IOException ex) {
throw new AndrolibException(ex);
}
}

@Override
public void readItem(YamlReader reader) throws AndrolibException {
YamlLine line = reader.getLine();
switch (line.getKey()) {
case "version": {
this.version = line.getValue();
break;
}
case "apkFileName": {
this.apkFileName = line.getValue();
break;
}
case "isFrameworkApk": {
this.isFrameworkApk = line.getValueBool();
break;
}
case "usesFramework": {
this.usesFramework = new UsesFramework();
reader.readObject(usesFramework);
break;
}
case "sdkInfo": {
reader.readMap(sdkInfo);
break;
}
case "packageInfo": {
this.packageInfo = new PackageInfo();
reader.readObject(packageInfo);
break;
}
case "versionInfo": {
this.versionInfo = new VersionInfo();
reader.readObject(versionInfo);
break;
}
case "compressionType":
case "resourcesAreCompressed": {
this.resourcesAreCompressed = line.getValueBool();
break;
}
case "sharedLibrary": {
this.sharedLibrary = line.getValueBool();
break;
}
case "sparseResources": {
this.sparseResources = line.getValueBool();
break;
}
case "unknownFiles": {
this.unknownFiles = new LinkedHashMap<>();
reader.readMap(unknownFiles);
break;
}
case "doNotCompress": {
this.doNotCompress = new ArrayList<>();
reader.readStringList(doNotCompress);
break;
}
}
}

@Override
public void write(YamlWriter writer) {
writer.writeString("version", version);
writer.writeString("apkFileName", apkFileName);
writer.writeBool("isFrameworkApk", isFrameworkApk);
writer.writeObject("usesFramework", usesFramework);
writer.writeStringMap("sdkInfo", sdkInfo);
writer.writeObject("packageInfo", packageInfo);
writer.writeObject("versionInfo", versionInfo);
writer.writeBool("resourcesAreCompressed", resourcesAreCompressed);
writer.writeBool("sharedLibrary", sharedLibrary);
writer.writeBool("sparseResources", sparseResources);
writer.writeStringMap("unknownFiles", unknownFiles);
writer.writeList("doNotCompress", doNotCompress);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,31 @@
*/
package brut.androlib.apk;

public class PackageInfo {
import brut.androlib.exceptions.AndrolibException;

public class PackageInfo implements YamlSerializable {
public String forcedPackageId;
public String renameManifestPackage;

@Override
public void readItem(YamlReader reader) throws AndrolibException {
YamlLine line = reader.getLine();
switch (line.getKey()) {
case "forcedPackageId": {
forcedPackageId = line.getValue();
break;
}
case "renameManifestPackage": {
renameManifestPackage = line.getValue();
break;
}
}
}

@Override
public void write(YamlWriter writer) {
writer.writeString("forcedPackageId", forcedPackageId);
writer.writeString("renameManifestPackage", renameManifestPackage);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,34 @@
*/
package brut.androlib.apk;

import brut.androlib.exceptions.AndrolibException;

import java.util.ArrayList;
import java.util.List;

public class UsesFramework {
public class UsesFramework implements YamlSerializable {
public List<Integer> ids;
public String tag;

@Override
public void readItem(YamlReader reader) throws AndrolibException {
YamlLine line = reader.getLine();
switch (line.getKey()) {
case "ids": {
ids = new ArrayList<>();
reader.readIntList(ids);
break;
}
case "tag": {
tag = line.getValue();
break;
}
}
}

@Override
public void write(YamlWriter writer) {
writer.writeList("ids", ids);
writer.writeString("tag", tag);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,30 @@
*/
package brut.androlib.apk;

public class VersionInfo {
import brut.androlib.exceptions.AndrolibException;

public class VersionInfo implements YamlSerializable {
public String versionCode;
public String versionName;

@Override
public void readItem(YamlReader reader) throws AndrolibException {
YamlLine line = reader.getLine();
switch (line.getKey()) {
case "versionCode": {
versionCode = line.getValue();
break;
}
case "versionName": {
versionName = line.getValue();
break;
}
}
}

@Override
public void write(YamlWriter writer) {
writer.writeString("versionCode", versionCode);
writer.writeString("versionName", versionName);
}
}
Loading