diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-cli/build.gradle apktool-2.6.1+dfsg.1/brut.apktool/apktool-cli/build.gradle --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-cli/build.gradle 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-cli/build.gradle 2022-04-11 21:08:20.000000000 +0000 @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import proguard.gradle.ProGuardTask + apply plugin: 'com.github.johnrengelman.shadow' dependencies { @@ -23,7 +25,6 @@ buildscript { repositories { mavenCentral() - jcenter() } dependencies { @@ -35,7 +36,7 @@ jar { manifest { - attributes 'Main-Class' : 'brut.apktool.Main' + attributes 'Main-Class': 'brut.apktool.Main' } } @@ -43,7 +44,7 @@ delete fileTree(dir: jar.getDestinationDirectory().getAsFile(), exclude: "apktool-cli-all.jar") } -task proguard(type: proguard.gradle.ProGuardTask, dependsOn: shadowJar) { +task proguard(type: ProGuardTask, dependsOn: shadowJar) { injars shadowJar.getArchiveFile() // Java 9 and prior uses merged package for runtime, later uses split jmod files. @@ -57,6 +58,7 @@ libraryjars "${System.properties['java.home']}/jmods/java.xml.jmod", jarfilter: '!**.jar', filter: '!module-info.class' libraryjars "${System.properties['java.home']}/jmods/java.desktop.jmod", jarfilter: '!**.jar', filter: '!module-info.class' libraryjars "${System.properties['java.home']}/jmods/java.sql.jmod", jarfilter: '!**.jar', filter: '!module-info.class' + libraryjars "${System.properties['java.home']}/jmods/java.scripting.jmod", jarfilter: '!**.jar', filter: '!module-info.class' libraryjars "${System.properties['java.home']}/jmods/jdk.unsupported.jmod", jarfilter: '!**.jar', filter: '!module-info.class' } @@ -71,6 +73,8 @@ dontwarn 'com.google.common.util.**' 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() @@ -79,4 +83,4 @@ } proguard.dependsOn cleanOutputDirectory -tasks.getByPath(':release').dependsOn(proguard) \ No newline at end of file +tasks.getByPath(':release').dependsOn(proguard) diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,6 +20,7 @@ import brut.androlib.err.CantFindFrameworkResException; import brut.androlib.err.InFileNotFoundException; import brut.androlib.err.OutDirExistsException; +import brut.androlib.options.BuildOptions; import brut.common.BrutException; import brut.directory.DirectoryException; import brut.util.AaptManager; @@ -30,12 +31,8 @@ import java.io.IOException; import java.util.logging.*; -/** - * @author Ryszard Wiśniewski - * @author Connor Tumbleson - */ public class Main { - public static void main(String[] args) throws IOException, InterruptedException, BrutException { + public static void main(String[] args) throws BrutException { // headless System.setProperty("java.awt.headless", "true"); @@ -54,7 +51,7 @@ commandLine = parser.parse(allOptions, args, false); if (! OSDetection.is64Bit()) { - System.err.println("32 bit support is deprecated. Apktool will not support 32bit on v2.6.0."); + System.err.println("32 bit support is deprecated. Apktool will not support 32bit on v3.0.0."); } } catch (ParseException ex) { System.err.println(ex.getMessage()); @@ -153,14 +150,13 @@ decoder.setFrameworkDir(cli.getOptionValue("p")); } if (cli.hasOption("m") || cli.hasOption("match-original")) { - decoder.setAnalysisMode(true, false); + decoder.setAnalysisMode(true); } if (cli.hasOption("api") || cli.hasOption("api-level")) { - decoder.setApi(Integer.parseInt(cli.getOptionValue("api"))); + decoder.setApiLevel(Integer.parseInt(cli.getOptionValue("api"))); } if (cli.hasOption("o") || cli.hasOption("output")) { outDir = new File(cli.getOptionValue("o")); - decoder.setOutDir(outDir); } else { // make out folder manually using name of apk String outName = apkName; @@ -170,9 +166,9 @@ // make file from path outName = new File(outName).getName(); outDir = new File(outName); - decoder.setOutDir(outDir); } + decoder.setOutDir(outDir); decoder.setApkFile(new File(apkName)); try { @@ -190,7 +186,7 @@ } catch (CantFindFrameworkResException ex) { System.err .println("Can't find framework resources for package of id: " - + String.valueOf(ex.getPkgId()) + + ex.getPkgId() + ". You must install proper " + "framework files, see project website for more info."); System.exit(1); @@ -207,43 +203,43 @@ } } - private static void cmdBuild(CommandLine cli) throws BrutException { + private static void cmdBuild(CommandLine cli) { String[] args = cli.getArgs(); String appDirName = args.length < 2 ? "." : args[1]; File outFile; - ApkOptions apkOptions = new ApkOptions(); + BuildOptions buildOptions = new BuildOptions(); // check for build options if (cli.hasOption("f") || cli.hasOption("force-all")) { - apkOptions.forceBuildAll = true; + buildOptions.forceBuildAll = true; } if (cli.hasOption("d") || cli.hasOption("debug")) { - apkOptions.debugMode = true; + buildOptions.debugMode = true; } if (cli.hasOption("v") || cli.hasOption("verbose")) { - apkOptions.verbose = true; + buildOptions.verbose = true; } if (cli.hasOption("a") || cli.hasOption("aapt")) { - apkOptions.aaptPath = cli.getOptionValue("a"); + buildOptions.aaptPath = cli.getOptionValue("a"); } if (cli.hasOption("c") || cli.hasOption("copy-original")) { - System.err.println("-c/--copy-original has been deprecated. Removal planned for v2.6.0 (#2129)"); - apkOptions.copyOriginalFiles = true; + System.err.println("-c/--copy-original has been deprecated. Removal planned for v3.0.0 (#2129)"); + buildOptions.copyOriginalFiles = true; } if (cli.hasOption("p") || cli.hasOption("frame-path")) { - apkOptions.frameworkFolderLocation = cli.getOptionValue("p"); + buildOptions.frameworkFolderLocation = cli.getOptionValue("p"); } if (cli.hasOption("nc") || cli.hasOption("no-crunch")) { - apkOptions.noCrunch = true; + buildOptions.noCrunch = true; } - // Temporary flag to enable the use of aapt2. This will tranform in time to a use-aapt1 flag, which will be + // Temporary flag to enable the use of aapt2. This will transform in time to a use-aapt1 flag, which will be // legacy and eventually removed. if (cli.hasOption("use-aapt2")) { - apkOptions.useAapt2 = true; + buildOptions.useAapt2 = true; } if (cli.hasOption("api") || cli.hasOption("api-level")) { - apkOptions.forceApi = Integer.parseInt(cli.getOptionValue("api")); + buildOptions.forceApi = Integer.parseInt(cli.getOptionValue("api")); } if (cli.hasOption("o") || cli.hasOption("output")) { outFile = new File(cli.getOptionValue("o")); @@ -254,9 +250,9 @@ // try and build apk try { if (cli.hasOption("a") || cli.hasOption("aapt")) { - apkOptions.aaptVersion = AaptManager.getAaptVersion(cli.getOptionValue("a")); + buildOptions.aaptVersion = AaptManager.getAaptVersion(cli.getOptionValue("a")); } - new Androlib(apkOptions).build(new File(appDirName), outFile); + new Androlib(buildOptions).build(new File(appDirName), outFile); } catch (BrutException ex) { System.err.println(ex.getMessage()); System.exit(1); @@ -267,23 +263,23 @@ int paraCount = cli.getArgList().size(); String apkName = cli.getArgList().get(paraCount - 1); - ApkOptions apkOptions = new ApkOptions(); + brut.androlib.options.BuildOptions buildOptions = new BuildOptions(); if (cli.hasOption("p") || cli.hasOption("frame-path")) { - apkOptions.frameworkFolderLocation = cli.getOptionValue("p"); + buildOptions.frameworkFolderLocation = cli.getOptionValue("p"); } if (cli.hasOption("t") || cli.hasOption("tag")) { - apkOptions.frameworkTag = cli.getOptionValue("t"); + buildOptions.frameworkTag = cli.getOptionValue("t"); } - new Androlib(apkOptions).installFramework(new File(apkName)); + new Androlib(buildOptions).installFramework(new File(apkName)); } private static void cmdListFrameworks(CommandLine cli) throws AndrolibException { - ApkOptions apkOptions = new ApkOptions(); + brut.androlib.options.BuildOptions buildOptions = new BuildOptions(); if (cli.hasOption("p") || cli.hasOption("frame-path")) { - apkOptions.frameworkFolderLocation = cli.getOptionValue("p"); + buildOptions.frameworkFolderLocation = cli.getOptionValue("p"); } - new Androlib(apkOptions).listFrameworks(); + new Androlib(buildOptions).listFrameworks(); } private static void cmdPublicizeResources(CommandLine cli) throws AndrolibException { @@ -294,23 +290,22 @@ } private static void cmdEmptyFrameworkDirectory(CommandLine cli) throws AndrolibException { - ApkOptions apkOptions = new ApkOptions(); + brut.androlib.options.BuildOptions buildOptions = new BuildOptions(); if (cli.hasOption("f") || cli.hasOption("force")) { - apkOptions.forceDeleteFramework = true; + buildOptions.forceDeleteFramework = true; } if (cli.hasOption("p") || cli.hasOption("frame-path")) { - apkOptions.frameworkFolderLocation = cli.getOptionValue("p"); + buildOptions.frameworkFolderLocation = cli.getOptionValue("p"); } - new Androlib(apkOptions).emptyFrameworkDirectory(); + new Androlib(buildOptions).emptyFrameworkDirectory(); } private static void _version() { System.out.println(Androlib.getVersion()); } - @SuppressWarnings("static-access") private static void _Options() { // create options @@ -468,20 +463,20 @@ // check for advance mode if (isAdvanceMode()) { - DecodeOptions.addOption(noDbgOption); - DecodeOptions.addOption(keepResOption); - DecodeOptions.addOption(analysisOption); - DecodeOptions.addOption(onlyMainClassesOption); - DecodeOptions.addOption(apiLevelOption); - DecodeOptions.addOption(noAssetOption); - DecodeOptions.addOption(forceManOption); - - BuildOptions.addOption(apiLevelOption); - BuildOptions.addOption(debugBuiOption); - BuildOptions.addOption(aaptOption); - BuildOptions.addOption(originalOption); - BuildOptions.addOption(aapt2Option); - BuildOptions.addOption(noCrunchOption); + decodeOptions.addOption(noDbgOption); + decodeOptions.addOption(keepResOption); + decodeOptions.addOption(analysisOption); + decodeOptions.addOption(onlyMainClassesOption); + decodeOptions.addOption(apiLevelOption); + decodeOptions.addOption(noAssetOption); + decodeOptions.addOption(forceManOption); + + buildOptions.addOption(apiLevelOption); + buildOptions.addOption(debugBuiOption); + buildOptions.addOption(aaptOption); + buildOptions.addOption(originalOption); + buildOptions.addOption(aapt2Option); + buildOptions.addOption(noCrunchOption); } // add global options @@ -489,17 +484,17 @@ normalOptions.addOption(advanceOption); // add basic decode options - DecodeOptions.addOption(frameTagOption); - DecodeOptions.addOption(outputDecOption); - DecodeOptions.addOption(frameDirOption); - DecodeOptions.addOption(forceDecOption); - DecodeOptions.addOption(noSrcOption); - DecodeOptions.addOption(noResOption); + decodeOptions.addOption(frameTagOption); + decodeOptions.addOption(outputDecOption); + decodeOptions.addOption(frameDirOption); + decodeOptions.addOption(forceDecOption); + decodeOptions.addOption(noSrcOption); + decodeOptions.addOption(noResOption); // add basic build options - BuildOptions.addOption(outputBuiOption); - BuildOptions.addOption(frameDirOption); - BuildOptions.addOption(forceBuiOption); + buildOptions.addOption(outputBuiOption); + buildOptions.addOption(frameDirOption); + buildOptions.addOption(forceBuiOption); // add basic framework options frameOptions.addOption(tagOption); @@ -513,17 +508,17 @@ listFrameworkOptions.addOption(frameIfDirOption); // add all, loop existing cats then manually add advance - for (Object op : normalOptions.getOptions()) { - allOptions.addOption((Option)op); + for (Option op : normalOptions.getOptions()) { + allOptions.addOption(op); } - for (Object op : DecodeOptions.getOptions()) { - allOptions.addOption((Option)op); + for (Option op : decodeOptions.getOptions()) { + allOptions.addOption(op); } - for (Object op : BuildOptions.getOptions()) { - allOptions.addOption((Option)op); + for (Option op : buildOptions.getOptions()) { + allOptions.addOption(op); } - for (Object op : frameOptions.getOptions()) { - allOptions.addOption((Option)op); + for (Option op : frameOptions.getOptions()) { + allOptions.addOption(op); } allOptions.addOption(apiLevelOption); allOptions.addOption(analysisOption); @@ -565,22 +560,20 @@ if (isAdvanceMode()) { System.out.println("Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0)\n"); }else { - System.out.println(""); + System.out.println(); } // 4 usage outputs (general, frameworks, decode, build) formatter.printHelp("apktool " + verbosityHelp(), normalOptions); formatter.printHelp("apktool " + verbosityHelp() + "if|install-framework [options] ", frameOptions); - formatter.printHelp("apktool " + verbosityHelp() + "d[ecode] [options] ", DecodeOptions); - formatter.printHelp("apktool " + verbosityHelp() + "b[uild] [options] ", BuildOptions); + formatter.printHelp("apktool " + verbosityHelp() + "d[ecode] [options] ", decodeOptions); + formatter.printHelp("apktool " + verbosityHelp() + "b[uild] [options] ", buildOptions); if (isAdvanceMode()) { formatter.printHelp("apktool " + verbosityHelp() + "publicize-resources ", emptyOptions); formatter.printHelp("apktool " + verbosityHelp() + "empty-framework-dir [options]", emptyFrameworkOptions); formatter.printHelp("apktool " + verbosityHelp() + "list-frameworks [options]", listFrameworkOptions); - System.out.println(""); - } else { - System.out.println(""); } + System.out.println(); // print out more information System.out.println( @@ -661,8 +654,8 @@ private static boolean advanceMode = false; private final static Options normalOptions; - private final static Options DecodeOptions; - private final static Options BuildOptions; + private final static Options decodeOptions; + private final static Options buildOptions; private final static Options frameOptions; private final static Options allOptions; private final static Options emptyOptions; @@ -672,8 +665,8 @@ static { //normal and advance usage output normalOptions = new Options(); - BuildOptions = new Options(); - DecodeOptions = new Options(); + buildOptions = new Options(); + decodeOptions = new Options(); frameOptions = new Options(); allOptions = new Options(); emptyOptions = new Options(); diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/build.gradle apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/build.gradle --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/build.gradle 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/build.gradle 2022-04-11 21:08:20.000000000 +0000 @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -22,18 +22,18 @@ include '**/*.properties' into 'properties' filter(ReplaceTokens, tokens: [version: project.apktool_version, gitrev: project.hash] ) + duplicatesStrategy = DuplicatesStrategy.INCLUDE } from('src/main/resources/') { include '**/*.jar' + duplicatesStrategy = DuplicatesStrategy.INCLUDE } - + includeEmptyDirs = false } dependencies { - testImplementation("junit:junit:4.10") { - exclude(module: 'hamcrest-core') - } + testImplementation depends.junit api project(':brut.j.dir'), project(':brut.j.util'), @@ -45,7 +45,8 @@ depends.xmlpull, depends.guava, depends.commons_lang, - depends.commons_io + depends.commons_io, + depends.commons_text testImplementation depends.xmlunit -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/content/res/XmlResourceParser.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/content/res/XmlResourceParser.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/content/res/XmlResourceParser.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/content/res/XmlResourceParser.java 2022-04-11 21:08:20.000000000 +0000 @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -15,9 +15,8 @@ */ package android.content.res; -import org.xmlpull.v1.XmlPullParser; - import android.util.AttributeSet; +import org.xmlpull.v1.XmlPullParser; /** * The XML parsing interface returned for an XML resource. This is a standard @@ -26,9 +25,9 @@ * it is done reading the resource. */ public interface XmlResourceParser extends XmlPullParser, AttributeSet { - /** - * Close this interface to the resource. Calls on the interface are no - * longer value after this call. - */ - public void close(); + /** + * Close this interface to the resource. Calls on the interface are no + * longer value after this call. + */ + void close(); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/util/AttributeSet.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/util/AttributeSet.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/util/AttributeSet.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/util/AttributeSet.java 2022-04-11 21:08:20.000000000 +0000 @@ -1,11 +1,11 @@ /* - * Copyright 2008 Android4ME + * Copyright 2008 Android4ME / Dmitry Skiba * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -15,63 +15,53 @@ */ package android.util; -/** - * @author Dmitry Skiba - * - */ public interface AttributeSet { - int getAttributeCount(); + int getAttributeCount(); - String getAttributeName(int index); + String getAttributeName(int index); - String getAttributeValue(int index); + String getAttributeValue(int index); - String getPositionDescription(); + String getPositionDescription(); - int getAttributeNameResource(int index); + int getAttributeNameResource(int index); - int getAttributeListValue(int index, String options[], int defaultValue); + int getAttributeListValue(int index, String[] options, int defaultValue); - boolean getAttributeBooleanValue(int index, boolean defaultValue); + boolean getAttributeBooleanValue(int index, boolean defaultValue); - int getAttributeResourceValue(int index, int defaultValue); + int getAttributeResourceValue(int index, int defaultValue); - int getAttributeIntValue(int index, int defaultValue); + int getAttributeIntValue(int index, int defaultValue); - int getAttributeUnsignedIntValue(int index, int defaultValue); + int getAttributeUnsignedIntValue(int index, int defaultValue); - float getAttributeFloatValue(int index, float defaultValue); + float getAttributeFloatValue(int index, float defaultValue); - String getIdAttribute(); + String getIdAttribute(); - String getClassAttribute(); + String getClassAttribute(); - int getIdAttributeResourceValue(int index); + int getIdAttributeResourceValue(int index); - int getStyleAttribute(); + int getStyleAttribute(); - String getAttributeValue(String namespace, String attribute); + String getAttributeValue(String namespace, String attribute); - int getAttributeListValue(String namespace, String attribute, - String options[], int defaultValue); + int getAttributeListValue(String namespace, String attribute, String[] options, int defaultValue); - boolean getAttributeBooleanValue(String namespace, String attribute, - boolean defaultValue); + boolean getAttributeBooleanValue(String namespace, String attribute, boolean defaultValue); - int getAttributeResourceValue(String namespace, String attribute, - int defaultValue); + int getAttributeResourceValue(String namespace, String attribute, int defaultValue); - int getAttributeIntValue(String namespace, String attribute, - int defaultValue); + int getAttributeIntValue(String namespace, String attribute, int defaultValue); - int getAttributeUnsignedIntValue(String namespace, String attribute, - int defaultValue); + int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue); - float getAttributeFloatValue(String namespace, String attribute, - float defaultValue); + float getAttributeFloatValue(String namespace, String attribute, float defaultValue); - // TODO: remove - int getAttributeValueType(int index); + // TODO: remove + int getAttributeValueType(int index); - int getAttributeValueData(int index); + int getAttributeValueData(int index); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/util/TypedValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/util/TypedValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/util/TypedValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/android/util/TypedValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,7 +17,7 @@ /** * Container for a dynamically typed data value. Primarily used with - * {@link android.content.res.Resources} for holding resource values. + * Resources for holding resource values. */ public class TypedValue { /** The value contains no data. */ @@ -196,14 +196,13 @@ /* ------------------------------------------------------------ */ /** - * If {@link #density} is equal to this value, then the density should be + * If density is equal to this value, then the density should be * treated as the system's default density value: - * {@link DisplayMetrics#DENSITY_DEFAULT}. */ public static final int DENSITY_DEFAULT = 0; /** - * If {@link #density} is equal to this value, then there is no density + * If density is equal to this value, then there is no density * associated with the resource and it should not be scaled. */ public static final int DENSITY_NONE = 0xffff; @@ -218,7 +217,7 @@ private static final float MANTISSA_MULT = 1.0f / (1 << TypedValue.COMPLEX_MANTISSA_SHIFT); private static final float[] RADIX_MULTS = new float[] { - 1.0f * MANTISSA_MULT, 1.0f / (1 << 7) * MANTISSA_MULT, + MANTISSA_MULT, 1.0f / (1 << 7) * MANTISSA_MULT, 1.0f / (1 << 15) * MANTISSA_MULT, 1.0f / (1 << 23) * MANTISSA_MULT }; /** @@ -243,18 +242,16 @@ private static final String[] FRACTION_UNIT_STRS = new String[] { "%", "%p" }; /** - * Perform type conversion as per {@link #coerceToString()} on an explicitly + * Perform type conversion as per coerceToString on an explicitly * supplied type and data. * - * @param type - * The data type identifier. - * @param data - * The data value. + * @param type The data type identifier. + * @param data The data value. * * @return String The coerced string value. If the value is null or the type * is not known, null is returned. */ - public static final String coerceToString(int type, int data) { + public static String coerceToString(int type, int data) { switch (type) { case TYPE_NULL: return null; @@ -265,11 +262,11 @@ case TYPE_FLOAT: return Float.toString(Float.intBitsToFloat(data)); case TYPE_DIMENSION: - return Float.toString(complexToFloat(data)) + return complexToFloat(data) + DIMENSION_UNIT_STRS[(data >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK]; case TYPE_FRACTION: - return Float.toString(complexToFloat(data) * 100) + return complexToFloat(data) * 100 + FRACTION_UNIT_STRS[(data >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK]; case TYPE_INT_HEX: @@ -289,22 +286,19 @@ res = res.substring(2); break; case TYPE_INT_COLOR_ARGB4:// #AARRGGBB->#ARGB - res = new StringBuffer().append(vals[0]).append(vals[2]) - .append(vals[4]).append(vals[6]).toString(); + res = String.valueOf(vals[0]) + vals[2] + + vals[4] + vals[6]; break; case TYPE_INT_COLOR_RGB4:// #FFRRGGBB->#RGB - res = new StringBuffer().append(vals[2]).append(vals[4]) - .append(vals[6]).toString(); + res = String.valueOf(vals[2]) + vals[4] + + vals[6]; break; } return "#" + res; } else if (type >= TYPE_FIRST_INT && type <= TYPE_LAST_INT) { - String res; - switch (type) { - default: - case TYPE_INT_DEC: - res = Integer.toString(data); - break; + String res = null; + if (type == TYPE_INT_DEC) { + res = Integer.toString(data); } return res; } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/AndrolibException.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/AndrolibException.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/AndrolibException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/AndrolibException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,9 +18,6 @@ import brut.common.BrutException; -/** - * @author Ryszard Wiśniewski - */ public class AndrolibException extends BrutException { public AndrolibException() { } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,18 +18,24 @@ import brut.androlib.meta.MetaInfo; import brut.androlib.meta.UsesFramework; +import brut.androlib.options.BuildOptions; import brut.androlib.res.AndrolibResources; import brut.androlib.res.data.ResPackage; import brut.androlib.res.data.ResTable; import brut.androlib.res.data.ResUnknownFiles; -import brut.directory.ExtFile; +import brut.common.InvalidUnknownFileException; +import brut.common.RootUnknownFileException; +import brut.common.TraversalUnknownFileException; import brut.androlib.res.xml.ResXmlPatcher; import brut.androlib.src.SmaliBuilder; import brut.androlib.src.SmaliDecoder; import brut.common.BrutException; import brut.directory.*; -import brut.util.BrutIO; -import brut.util.OS; +import brut.util.*; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.jf.dexlib2.iface.DexFile; + import java.io.*; import java.util.*; import java.util.logging.Logger; @@ -39,26 +45,19 @@ import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.FilenameUtils; - -/** - * @author Ryszard Wiśniewski - */ public class Androlib { private final AndrolibResources mAndRes = new AndrolibResources(); protected final ResUnknownFiles mResUnknownFiles = new ResUnknownFiles(); - public ApkOptions apkOptions; + public final BuildOptions buildOptions; private int mMinSdkVersion = 0; - public Androlib(ApkOptions apkOptions) { - this.apkOptions = apkOptions; - mAndRes.apkOptions = apkOptions; + public Androlib() { + this(new BuildOptions()); } - public Androlib() { - this.apkOptions = new ApkOptions(); - mAndRes.apkOptions = this.apkOptions; + public Androlib(BuildOptions buildOptions) { + this.buildOptions = buildOptions; + mAndRes.buildOptions = buildOptions; } public ResTable getResTable(ExtFile apkFile) @@ -71,6 +70,10 @@ return mAndRes.getResTable(apkFile, loadMainPkg); } + public int getMinSdkVersion() { + return mMinSdkVersion; + } + public void decodeSourcesRaw(ExtFile apkFile, File outDir, String filename) throws AndrolibException { try { @@ -81,7 +84,7 @@ } } - public void decodeSourcesSmali(File apkFile, File outDir, String filename, boolean bakdeb, int api) + public void decodeSourcesSmali(File apkFile, File outDir, String filename, boolean bakDeb, int apiLevel) throws AndrolibException { try { File smaliDir; @@ -93,7 +96,11 @@ OS.rmdir(smaliDir); smaliDir.mkdirs(); LOGGER.info("Baksmaling " + filename + "..."); - SmaliDecoder.decode(apkFile, smaliDir, filename, bakdeb, api); + DexFile dexFile = SmaliDecoder.decode(apkFile, smaliDir, filename, bakDeb, apiLevel); + int minSdkVersion = dexFile.getOpcodes().api; + if (mMinSdkVersion == 0 || mMinSdkVersion > minSdkVersion) { + mMinSdkVersion = minSdkVersion; + } } catch (BrutException ex) { throw new AndrolibException(ex); } @@ -193,7 +200,7 @@ return false; } - public void decodeUnknownFiles(ExtFile apkFile, File outDir, ResTable resTable) + public void decodeUnknownFiles(ExtFile apkFile, File outDir) throws AndrolibException { LOGGER.info("Copying unknown files..."); File unknownOut = new File(outDir, UNK_DIRNAME); @@ -230,6 +237,9 @@ if (in.containsFile("AndroidManifest.xml")) { in.copyToDir(originalDir, "AndroidManifest.xml"); } + if (in.containsFile("stamp-cert-sha256")) { + in.copyToDir(originalDir, "stamp-cert-sha256"); + } if (in.containsDir("META-INF")) { in.copyToDir(originalDir, "META-INF"); @@ -275,9 +285,9 @@ LOGGER.info("Using Apktool " + Androlib.getVersion()); MetaInfo meta = readMetaFile(appDir); - apkOptions.isFramework = meta.isFrameworkApk; - apkOptions.resourcesAreCompressed = meta.compressionType; - apkOptions.doNotCompress = meta.doNotCompress; + buildOptions.isFramework = meta.isFrameworkApk; + buildOptions.resourcesAreCompressed = meta.compressionType; + buildOptions.doNotCompress = meta.doNotCompress; mAndRes.setSdkInfo(meta.sdkInfo); mAndRes.setPackageId(meta.packageInfo); @@ -392,7 +402,7 @@ return false; } File stored = new File(appDir, APK_DIRNAME + "/" + filename); - if (apkOptions.forceBuildAll || isModified(working, stored)) { + if (buildOptions.forceBuildAll || isModified(working, stored)) { LOGGER.info("Copying " + appDir.toString() + " " + filename + " file..."); try { BrutIO.copyAndClose(new FileInputStream(working), new FileOutputStream(stored)); @@ -411,13 +421,13 @@ return false; } File dex = new File(appDir, APK_DIRNAME + "/" + filename); - if (! apkOptions.forceBuildAll) { + if (! buildOptions.forceBuildAll) { LOGGER.info("Checking whether sources has changed..."); } - if (apkOptions.forceBuildAll || isModified(smaliDir, dex)) { + if (buildOptions.forceBuildAll || isModified(smaliDir, dex)) { LOGGER.info("Smaling " + folder + " folder into " + filename + "..."); dex.delete(); - SmaliBuilder.build(smaliDir, dex, apkOptions.forceApi > 0 ? apkOptions.forceApi : mMinSdkVersion); + SmaliBuilder.build(smaliDir, dex, buildOptions.forceApi > 0 ? buildOptions.forceApi : mMinSdkVersion); } return true; } @@ -437,10 +447,10 @@ return false; } File apkDir = new File(appDir, APK_DIRNAME); - if (! apkOptions.forceBuildAll) { + if (! buildOptions.forceBuildAll) { LOGGER.info("Checking whether resources has changed..."); } - if (apkOptions.forceBuildAll || isModified(newFiles(APK_RESOURCES_FILENAMES, appDir), + if (buildOptions.forceBuildAll || isModified(newFiles(APK_RESOURCES_FILENAMES, appDir), newFiles(APK_RESOURCES_FILENAMES, apkDir))) { LOGGER.info("Copying raw resources..."); appDir.getDirectory().copyToDir(apkDir, APK_RESOURCES_FILENAMES); @@ -457,18 +467,18 @@ if (!new File(appDir, "res").exists()) { return false; } - if (! apkOptions.forceBuildAll) { + if (! buildOptions.forceBuildAll) { LOGGER.info("Checking whether resources has changed..."); } File apkDir = new File(appDir, APK_DIRNAME); File resourceFile = new File(apkDir.getParent(), "resources.zip"); - if (apkOptions.forceBuildAll || isModified(newFiles(APP_RESOURCES_FILENAMES, appDir), - newFiles(APK_RESOURCES_FILENAMES, apkDir)) || (apkOptions.isAapt2() && !isFile(resourceFile))) { + if (buildOptions.forceBuildAll || isModified(newFiles(APP_RESOURCES_FILENAMES, appDir), + newFiles(APK_RESOURCES_FILENAMES, apkDir)) || (buildOptions.isAapt2() && !isFile(resourceFile))) { LOGGER.info("Building resources..."); - if (apkOptions.debugMode) { - if (apkOptions.isAapt2()) { + if (buildOptions.debugMode) { + if (buildOptions.isAapt2()) { LOGGER.info("Using aapt2 - setting 'debuggable' attribute to 'true' in AndroidManifest.xml"); ResXmlPatcher.setApplicationDebugTagTrue(new File(appDir, "AndroidManifest.xml")); } else { @@ -488,7 +498,8 @@ "AndroidManifest.xml"), new File(appDir, "res"), ninePatch, null, parseUsesFramework(usesFramework)); - Directory tmpDir = new ExtFile(apkFile).getDirectory(); + ExtFile tmpExtFile = new ExtFile(apkFile); + Directory tmpDir = tmpExtFile.getDirectory(); // Sometimes an application is built with a resources.arsc file with no resources, // Apktool assumes it will have a rebuilt arsc file, when it doesn't. So if we @@ -499,6 +510,8 @@ : APK_RESOURCES_WITHOUT_RES_FILENAMES); } catch (DirectoryException ex) { LOGGER.warning(ex.getMessage()); + } finally { + tmpExtFile.close(); } // delete tmpDir @@ -528,13 +541,13 @@ if (!new File(appDir, "AndroidManifest.xml").exists()) { return false; } - if (! apkOptions.forceBuildAll) { + if (! buildOptions.forceBuildAll) { LOGGER.info("Checking whether resources has changed..."); } File apkDir = new File(appDir, APK_DIRNAME); - if (apkOptions.forceBuildAll || isModified(newFiles(APK_MANIFEST_FILENAMES, appDir), + if (buildOptions.forceBuildAll || isModified(newFiles(APK_MANIFEST_FILENAMES, appDir), newFiles(APK_MANIFEST_FILENAMES, apkDir))) { LOGGER.info("Building AndroidManifest.xml..."); @@ -552,6 +565,8 @@ Directory tmpDir = new ExtFile(apkFile).getDirectory(); tmpDir.copyToDir(apkDir, APK_MANIFEST_FILENAMES); + + apkFile.delete(); } return true; } catch (IOException | DirectoryException ex) { @@ -577,7 +592,7 @@ } File stored = new File(appDir, APK_DIRNAME + "/" + folder); - if (apkOptions.forceBuildAll || isModified(working, stored)) { + if (buildOptions.forceBuildAll || isModified(working, stored)) { LOGGER.info("Copying libs... (/" + folder + ")"); try { OS.rmdir(stored); @@ -590,7 +605,7 @@ public void buildCopyOriginalFiles(File appDir) throws AndrolibException { - if (apkOptions.copyOriginalFiles) { + if (buildOptions.copyOriginalFiles) { File originalDir = new File(appDir, "original"); if (originalDir.exists()) { try { @@ -600,6 +615,10 @@ LOGGER.info("Copy AndroidManifest.xml..."); in.copyToDir(new File(appDir, APK_DIRNAME), "AndroidManifest.xml"); } + if (in.containsFile("stamp-cert-sha256")) { + LOGGER.info("Copy stamp-cert-sha256..."); + in.copyToDir(new File(appDir, APK_DIRNAME), "stamp-cert-sha256"); + } if (in.containsDir("META-INF")) { LOGGER.info("Copy META-INF..."); in.copyToDir(new File(appDir, APK_DIRNAME), "META-INF"); @@ -663,7 +682,15 @@ // loop through unknown files for (Map.Entry unknownFileInfo : files.entrySet()) { - File inputFile = new File(unknownFileDir, BrutIO.sanitizeUnknownFile(unknownFileDir, unknownFileInfo.getKey())); + File inputFile; + + try { + inputFile = new File(unknownFileDir, BrutIO.sanitizeUnknownFile(unknownFileDir, unknownFileInfo.getKey())); + } catch (RootUnknownFileException | InvalidUnknownFileException | TraversalUnknownFileException exception) { + LOGGER.warning(String.format("Skipping file %s (%s)", unknownFileInfo.getKey(), exception.getMessage())); + continue; + } + if (inputFile.isDirectory()) { continue; } @@ -764,8 +791,8 @@ } private boolean isModified(File[] working, File[] stored) { - for (int i = 0; i < stored.length; i++) { - if (!stored[i].exists()) { + for (File file : stored) { + if (!file.exists()) { return true; } } @@ -802,5 +829,5 @@ "lib", "libs", "assets", "META-INF", "kotlin" }; private final static Pattern NO_COMPRESS_PATTERN = Pattern.compile("(" + "jpg|jpeg|png|gif|wav|mp2|mp3|ogg|aac|mpg|mpeg|mid|midi|smf|jet|rtttl|imy|xmf|mp4|" + - "m4a|m4v|3gp|3gpp|3g2|3gpp2|amr|awb|wma|wmv|webm|mkv)$"); + "m4a|m4v|3gp|3gpp|3g2|3gpp2|amr|awb|wma|wmv|webm|webp|mkv)$"); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -38,9 +38,6 @@ import java.util.*; import java.util.logging.Logger; -/** - * @author Ryszard Wiśniewski - */ public class ApkDecoder { public ApkDecoder() { this(new Androlib()); @@ -70,14 +67,10 @@ mResTable = null; } - public void setOutDir(File outDir) throws AndrolibException { + public void setOutDir(File outDir) { mOutDir = outDir; } - public void setApi(int api) { - mApi = api; - } - public void decode() throws AndrolibException, IOException, DirectoryException { try { File outDir = getOutDir(); @@ -105,9 +98,6 @@ case DECODE_RESOURCES_NONE: mAndrolib.decodeResourcesRaw(mApkFile, outDir); if (mForceDecodeManifest == FORCE_DECODE_MANIFEST_FULL) { - setTargetSdkVersion(); - setAnalysisMode(mAnalysisMode, true); - // done after raw decoding of resources because copyToDir overwrites dest files if (hasManifest()) { mAndrolib.decodeManifestWithResources(mApkFile, outDir, getResTable()); @@ -115,9 +105,6 @@ } break; case DECODE_RESOURCES_FULL: - setTargetSdkVersion(); - setAnalysisMode(mAnalysisMode, true); - if (hasManifest()) { mAndrolib.decodeManifestWithResources(mApkFile, outDir, getResTable()); } @@ -145,7 +132,7 @@ break; case DECODE_SOURCES_SMALI: case DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES: - mAndrolib.decodeSourcesSmali(mApkFile, outDir, "classes.dex", mBakDeb, mApi); + mAndrolib.decodeSourcesSmali(mApkFile, outDir, "classes.dex", mBakDeb, mApiLevel); break; } } @@ -161,11 +148,11 @@ mAndrolib.decodeSourcesRaw(mApkFile, outDir, file); break; case DECODE_SOURCES_SMALI: - mAndrolib.decodeSourcesSmali(mApkFile, outDir, file, mBakDeb, mApi); + mAndrolib.decodeSourcesSmali(mApkFile, outDir, file, mBakDeb, mApiLevel); break; case DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES: if (file.startsWith("classes") && file.endsWith(".dex")) { - mAndrolib.decodeSourcesSmali(mApkFile, outDir, file, mBakDeb, mApi); + mAndrolib.decodeSourcesSmali(mApkFile, outDir, file, mBakDeb, mApiLevel); } else { mAndrolib.decodeSourcesRaw(mApkFile, outDir, file); } @@ -177,13 +164,11 @@ } mAndrolib.decodeRawFiles(mApkFile, outDir, mDecodeAssets); - mAndrolib.decodeUnknownFiles(mApkFile, outDir, mResTable); - mUncompressedFiles = new ArrayList(); + mAndrolib.decodeUnknownFiles(mApkFile, outDir); + mUncompressedFiles = new ArrayList<>(); mAndrolib.recordUncompressedFiles(mApkFile, mUncompressedFiles); mAndrolib.writeOriginalFiles(mApkFile, outDir); writeMetaFile(); - } catch (Exception ex) { - throw ex; } finally { try { mApkFile.close(); @@ -219,39 +204,28 @@ mDecodeAssets = mode; } - public void setAnalysisMode(boolean mode, boolean pass) throws AndrolibException{ + public void setAnalysisMode(boolean mode) { mAnalysisMode = mode; - // only set mResTable, once it exists - if (pass) { - if (mResTable == null) { - mResTable = getResTable(); - } + if (mResTable != null) { mResTable.setAnalysisMode(mode); } } - public void setTargetSdkVersion() throws AndrolibException, IOException { - if (mResTable == null) { - mResTable = mAndrolib.getResTable(mApkFile); - } - - Map sdkInfo = mResTable.getSdkInfo(); - if (sdkInfo.get("targetSdkVersion") != null) { - mApi = Integer.parseInt(sdkInfo.get("targetSdkVersion")); - } + public void setApiLevel(int apiLevel) { + mApiLevel = apiLevel; } - public void setBaksmaliDebugMode(boolean bakdeb) { - mBakDeb = bakdeb; + public void setBaksmaliDebugMode(boolean bakDeb) { + mBakDeb = bakDeb; } public void setForceDelete(boolean forceDelete) { mForceDelete = forceDelete; } - public void setFrameworkTag(String tag) throws AndrolibException { - mAndrolib.apkOptions.frameworkTag = tag; + public void setFrameworkTag(String tag) { + mAndrolib.buildOptions.frameworkTag = tag; } public void setKeepBrokenResources(boolean keepBrokenResources) { @@ -259,7 +233,7 @@ } public void setFrameworkDir(String dir) { - mAndrolib.apkOptions.frameworkFolderLocation = dir; + mAndrolib.buildOptions.frameworkFolderLocation = dir; } public ResTable getResTable() throws AndrolibException { @@ -271,6 +245,7 @@ "Apk doesn't contain either AndroidManifest.xml file or resources.arsc file"); } mResTable = mAndrolib.getResTable(mApkFile, hasResources); + mResTable.setAnalysisMode(mAnalysisMode); } return mResTable; } @@ -347,14 +322,16 @@ meta.version = Androlib.getVersion(); meta.apkFileName = mApkFile.getName(); - if (mDecodeResources != DECODE_RESOURCES_NONE && (hasManifest() || hasResources())) { - meta.isFrameworkApk = mAndrolib.isFrameworkApk(getResTable()); + if (mResTable != null) { + meta.isFrameworkApk = mAndrolib.isFrameworkApk(mResTable); putUsesFramework(meta); putSdkInfo(meta); putPackageInfo(meta); putVersionInfo(meta); putSharedLibraryInfo(meta); putSparseResourcesInfo(meta); + } else { + putMinSdkInfo(meta); } putUnknownInfo(meta); putFileCompressionInfo(meta); @@ -362,8 +339,8 @@ mAndrolib.writeMetaFile(mOutDir, meta); } - private void putUsesFramework(MetaInfo meta) throws AndrolibException { - Set pkgs = getResTable().listFramePackages(); + private void putUsesFramework(MetaInfo meta) { + Set pkgs = mResTable.listFramePackages(); if (pkgs.isEmpty()) { return; } @@ -378,13 +355,13 @@ meta.usesFramework = new UsesFramework(); meta.usesFramework.ids = Arrays.asList(ids); - if (mAndrolib.apkOptions.frameworkTag != null) { - meta.usesFramework.tag = mAndrolib.apkOptions.frameworkTag; + if (mAndrolib.buildOptions.frameworkTag != null) { + meta.usesFramework.tag = mAndrolib.buildOptions.frameworkTag; } } - private void putSdkInfo(MetaInfo meta) throws AndrolibException { - Map info = getResTable().getSdkInfo(); + private void putSdkInfo(MetaInfo meta) { + Map info = mResTable.getSdkInfo(); if (info.size() > 0) { String refValue; if (info.get("minSdkVersion") != null) { @@ -409,13 +386,22 @@ } } + private void putMinSdkInfo(MetaInfo meta) { + int minSdkVersion = mAndrolib.getMinSdkVersion(); + if (minSdkVersion > 0) { + Map sdkInfo = new LinkedHashMap<>(); + sdkInfo.put("minSdkVersion", Integer.toString(minSdkVersion)); + meta.sdkInfo = sdkInfo; + } + } + private void putPackageInfo(MetaInfo meta) throws AndrolibException { - String renamed = getResTable().getPackageRenamed(); - String original = getResTable().getPackageOriginal(); + String renamed = mResTable.getPackageRenamed(); + String original = mResTable.getPackageOriginal(); - int id = getResTable().getPackageId(); + int id = mResTable.getPackageId(); try { - id = getResTable().getPackage(renamed).getId(); + id = mResTable.getPackage(renamed).getId(); } catch (UndefinedResObjectException ignored) {} if (Strings.isNullOrEmpty(original)) { @@ -431,8 +417,8 @@ meta.packageInfo.forcedPackageId = String.valueOf(id); } - private void putVersionInfo(MetaInfo meta) throws AndrolibException { - VersionInfo info = getResTable().getVersionInfo(); + private void putVersionInfo(MetaInfo meta) { + VersionInfo info = mResTable.getVersionInfo(); String refValue = ResXmlPatcher.pullValueFromStrings(mOutDir, info.versionName); if (refValue != null) { info.versionName = refValue; @@ -440,22 +426,22 @@ meta.versionInfo = info; } - private void putUnknownInfo(MetaInfo meta) throws AndrolibException { - meta.unknownFiles = mAndrolib.mResUnknownFiles.getUnknownFiles(); + private void putSharedLibraryInfo(MetaInfo meta) { + meta.sharedLibrary = mResTable.getSharedLibrary(); } - private void putFileCompressionInfo(MetaInfo meta) throws AndrolibException { - if (mUncompressedFiles != null && !mUncompressedFiles.isEmpty()) { - meta.doNotCompress = mUncompressedFiles; - } + private void putSparseResourcesInfo(MetaInfo meta) { + meta.sparseResources = mResTable.getSparseResources(); } - private void putSparseResourcesInfo(MetaInfo meta) throws AndrolibException { - meta.sparseResources = mResTable.getSparseResources(); + private void putUnknownInfo(MetaInfo meta) { + meta.unknownFiles = mAndrolib.mResUnknownFiles.getUnknownFiles(); } - private void putSharedLibraryInfo(MetaInfo meta) throws AndrolibException { - meta.sharedLibrary = mResTable.getSharedLibrary(); + private void putFileCompressionInfo(MetaInfo meta) { + if (mUncompressedFiles != null && !mUncompressedFiles.isEmpty()) { + meta.doNotCompress = mUncompressedFiles; + } } private final Androlib mAndrolib; @@ -474,5 +460,5 @@ private boolean mBakDeb = true; private Collection mUncompressedFiles; private boolean mAnalysisMode = false; - private int mApi = 15; + private int mApiLevel = 0; } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2010 Ryszard Wiśniewski - * Copyright (C) 2010 Connor Tumbleson - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package brut.androlib; - -import java.util.Collection; - -public class ApkOptions { - public boolean forceBuildAll = false; - public boolean forceDeleteFramework = false; - public boolean debugMode = false; - public boolean verbose = false; - public boolean copyOriginalFiles = false; - public boolean updateFiles = false; - public boolean isFramework = false; - public boolean resourcesAreCompressed = false; - public boolean useAapt2 = false; - public boolean noCrunch = false; - public int forceApi = 0; - public Collection doNotCompress; - - public String frameworkFolderLocation = null; - public String frameworkTag = null; - public String aaptPath = ""; - - public int aaptVersion = 1; // default to v1 - - public boolean isAapt2() { - return this.useAapt2 || this.aaptVersion == 2; - } -} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApktoolProperties.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApktoolProperties.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApktoolProperties.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApktoolProperties.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,9 +21,6 @@ import java.util.Properties; import java.util.logging.Logger; -/** - * @author Ryszard Wiśniewski - */ public class ApktoolProperties { public static String get(String key) { return get().getProperty(key); @@ -86,4 +83,4 @@ private static Properties sProps; private static final Logger LOGGER = Logger.getLogger(ApktoolProperties.class.getName()); -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/AXmlDecodingException.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/AXmlDecodingException.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/AXmlDecodingException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/AXmlDecodingException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -22,4 +22,4 @@ public AXmlDecodingException(String message, Throwable cause) { super(message, cause); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/CantFind9PatchChunkException.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/CantFind9PatchChunkException.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/CantFind9PatchChunkException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/CantFind9PatchChunkException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,9 +18,6 @@ import brut.androlib.AndrolibException; -/** - * @author Ryszard Wiśniewski - */ public class CantFind9PatchChunkException extends AndrolibException { public CantFind9PatchChunkException(String message, Throwable cause) { super(message, cause); diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/CantFindFrameworkResException.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/CantFindFrameworkResException.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/CantFindFrameworkResException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/CantFindFrameworkResException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,9 +18,6 @@ import brut.androlib.AndrolibException; -/** - * @author Ryszard Wiśniewski - */ public class CantFindFrameworkResException extends AndrolibException { public CantFindFrameworkResException(int id) { mPkgId = id; @@ -30,5 +27,10 @@ return mPkgId; } + @Override + public String getMessage() { + return String.format("Can't find framework resources for package of id: %d", this.getPkgId()); + } + private final int mPkgId; } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/InFileNotFoundException.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/InFileNotFoundException.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/InFileNotFoundException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/InFileNotFoundException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,9 +18,6 @@ import brut.androlib.AndrolibException; -/** - * @author Ryszard Wiśniewski - */ public class InFileNotFoundException extends AndrolibException { public InFileNotFoundException() { } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/OutDirExistsException.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/OutDirExistsException.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/OutDirExistsException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/OutDirExistsException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,9 +18,6 @@ import brut.androlib.AndrolibException; -/** - * @author Ryszard Wiśniewski - */ public class OutDirExistsException extends AndrolibException { public OutDirExistsException() { } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/RawXmlEncounteredException.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/RawXmlEncounteredException.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/RawXmlEncounteredException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/RawXmlEncounteredException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/UndefinedResObjectException.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/UndefinedResObjectException.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/UndefinedResObjectException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/err/UndefinedResObjectException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,9 +18,6 @@ import brut.androlib.AndrolibException; -/** - * @author Ryszard Wiśniewski - */ public class UndefinedResObjectException extends AndrolibException { public UndefinedResObjectException(String message) { super(message); diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/ClassSafeConstructor.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/ClassSafeConstructor.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/ClassSafeConstructor.java 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/ClassSafeConstructor.java 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package brut.androlib.meta; + +import org.yaml.snakeyaml.constructor.AbstractConstruct; +import org.yaml.snakeyaml.constructor.Constructor; +import org.yaml.snakeyaml.error.YAMLException; +import org.yaml.snakeyaml.nodes.Node; +import org.yaml.snakeyaml.nodes.ScalarNode; +import org.yaml.snakeyaml.nodes.Tag; +import java.util.ArrayList; +import java.util.List; + +public class ClassSafeConstructor extends Constructor { + protected final List> allowableClasses = new ArrayList<>(); + + public ClassSafeConstructor() { + this.yamlConstructors.put(Tag.STR, new ConstructStringEx()); + + this.allowableClasses.add(MetaInfo.class); + this.allowableClasses.add(PackageInfo.class); + this.allowableClasses.add(UsesFramework.class); + this.allowableClasses.add(VersionInfo.class); + } + + protected Object newInstance(Node node) { + if (this.yamlConstructors.containsKey(node.getTag()) || this.allowableClasses.contains(node.getType())) { + return super.newInstance(node); + } + throw new YAMLException("Invalid Class attempting to be constructed: " + node.getTag()); + } + + protected Object finalizeConstruction(Node node, Object data) { + if (this.yamlConstructors.containsKey(node.getTag()) || this.allowableClasses.contains(node.getType())) { + return super.finalizeConstruction(node, data); + } + + return this.newInstance(node); + } + + private class ConstructStringEx extends AbstractConstruct { + public Object construct(Node node) { + String val = constructScalar((ScalarNode) node); + return YamlStringEscapeUtils.unescapeString(val); + } + } +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/EscapedStringRepresenter.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/EscapedStringRepresenter.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/EscapedStringRepresenter.java 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/EscapedStringRepresenter.java 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package brut.androlib.meta; + +import org.yaml.snakeyaml.nodes.Node; +import org.yaml.snakeyaml.representer.Representer; + +public class EscapedStringRepresenter extends Representer { + public EscapedStringRepresenter() { + RepresentStringEx representStringEx = new RepresentStringEx(); + multiRepresenters.put(String.class, representStringEx); + representers.put(String.class, representStringEx); + } + + private class RepresentStringEx extends RepresentString { + + @Override + public Node representData(Object data) { + return super.representData(YamlStringEscapeUtils.escapeString(data.toString())); + } + } +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/MetaInfo.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/MetaInfo.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/MetaInfo.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/MetaInfo.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -43,11 +43,11 @@ DumperOptions options = new DumperOptions(); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - StringExRepresent representer = new StringExRepresent(); + EscapedStringRepresenter representer = new EscapedStringRepresenter(); PropertyUtils propertyUtils = representer.getPropertyUtils(); propertyUtils.setSkipMissingProperties(true); - return new Yaml(new StringExConstructor(), representer, options); + return new Yaml(new ClassSafeConstructor(), representer, options); } public void save(Writer output) { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/PackageInfo.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/PackageInfo.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/PackageInfo.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/PackageInfo.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExConstructor.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExConstructor.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExConstructor.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExConstructor.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010 Ryszard Wiśniewski - * Copyright (C) 2010 Connor Tumbleson - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package brut.androlib.meta; - -import org.yaml.snakeyaml.constructor.AbstractConstruct; -import org.yaml.snakeyaml.constructor.Constructor; -import org.yaml.snakeyaml.nodes.Node; -import org.yaml.snakeyaml.nodes.ScalarNode; -import org.yaml.snakeyaml.nodes.Tag; - -public class StringExConstructor extends Constructor { - public StringExConstructor() { - this.yamlConstructors.put(Tag.STR, new ConstructStringEx()); - } - - private class ConstructStringEx extends AbstractConstruct { - public Object construct(Node node) { - String val = (String) constructScalar((ScalarNode) node); - return YamlStringEscapeUtils.unescapeString(val); - } - } -} \ No newline at end of file diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExRepresent.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExRepresent.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExRepresent.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExRepresent.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010 Ryszard Wiśniewski - * Copyright (C) 2010 Connor Tumbleson - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package brut.androlib.meta; - -import org.yaml.snakeyaml.nodes.Node; -import org.yaml.snakeyaml.representer.Representer; - -public class StringExRepresent extends Representer { - public StringExRepresent() { - RepresentStringEx representStringEx = new RepresentStringEx(); - multiRepresenters.put(String.class, representStringEx); - representers.put(String.class, representStringEx); - } - - private class RepresentStringEx extends RepresentString { - - @Override - public Node representData(Object data) { - return super.representData(YamlStringEscapeUtils.escapeString(data.toString())); - } - } -} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/UsesFramework.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/UsesFramework.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/UsesFramework.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/UsesFramework.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/VersionInfo.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/VersionInfo.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/VersionInfo.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/VersionInfo.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/YamlStringEscapeUtils.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/YamlStringEscapeUtils.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/YamlStringEscapeUtils.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/YamlStringEscapeUtils.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,8 +16,8 @@ */ package brut.androlib.meta; -import org.apache.commons.lang3.StringEscapeUtils; -import org.apache.commons.lang3.text.translate.CharSequenceTranslator; +import org.apache.commons.text.StringEscapeUtils; +import org.apache.commons.text.translate.CharSequenceTranslator; import java.io.IOException; import java.io.StringWriter; @@ -140,4 +140,4 @@ public static String unescapeString(String str) { return StringEscapeUtils.unescapeJava(str); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/mod/SmaliMod.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/mod/SmaliMod.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/mod/SmaliMod.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/mod/SmaliMod.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,42 +16,20 @@ */ package brut.androlib.mod; -import java.io.*; -import java.nio.charset.StandardCharsets; - -import org.antlr.runtime.*; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.Token; import org.antlr.runtime.tree.CommonTree; import org.antlr.runtime.tree.CommonTreeNodeStream; -import org.apache.commons.io.IOUtils; import org.jf.dexlib2.writer.builder.DexBuilder; -import org.jf.smali.*; - -/** - * @author Ryszard Wiśniewski - */ -public class SmaliMod { - - public static boolean assembleSmaliFile(String smali, DexBuilder dexBuilder, int apiLevel, boolean verboseErrors, - boolean printTokens, File smaliFile) throws IOException, RuntimeException, RecognitionException { +import org.jf.smali.smaliFlexLexer; +import org.jf.smali.smaliParser; +import org.jf.smali.smaliTreeWalker; - InputStream is = new ByteArrayInputStream(smali.getBytes()); - return assembleSmaliFile(is, dexBuilder, apiLevel, verboseErrors, printTokens, smaliFile); - } - - public static boolean assembleSmaliFile(InputStream is,DexBuilder dexBuilder, int apiLevel, boolean verboseErrors, - boolean printTokens, File smaliFile) throws IOException, RecognitionException { - - // copy our filestream into a tmp file, so we don't overwrite - File tmp = File.createTempFile("BRUT",".bak"); - tmp.deleteOnExit(); - - OutputStream os = new FileOutputStream(tmp); - IOUtils.copy(is, os); - os.close(); - - return assembleSmaliFile(tmp,dexBuilder, apiLevel, verboseErrors, printTokens); - } +import java.io.*; +import java.nio.charset.StandardCharsets; +public class SmaliMod { public static boolean assembleSmaliFile(File smaliFile,DexBuilder dexBuilder, int apiLevel, boolean verboseErrors, boolean printTokens) throws IOException, RecognitionException { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/options/BuildOptions.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/options/BuildOptions.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/options/BuildOptions.java 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/options/BuildOptions.java 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package brut.androlib.options; + +import java.util.Collection; + +public class BuildOptions { + public boolean forceBuildAll = false; + public boolean forceDeleteFramework = false; + public boolean debugMode = false; + public boolean verbose = false; + public boolean copyOriginalFiles = false; + public final boolean updateFiles = false; + public boolean isFramework = false; + public boolean resourcesAreCompressed = false; + public boolean useAapt2 = false; + public boolean noCrunch = false; + public int forceApi = 0; + public Collection doNotCompress; + + public String frameworkFolderLocation = null; + public String frameworkTag = null; + public String aaptPath = ""; + + public int aaptVersion = 1; // default to v1 + + public boolean isAapt2() { + return this.useAapt2 || this.aaptVersion == 2; + } +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,7 +17,7 @@ package brut.androlib.res; import brut.androlib.AndrolibException; -import brut.androlib.ApkOptions; +import brut.androlib.options.BuildOptions; import brut.androlib.err.CantFindFrameworkResException; import brut.androlib.meta.MetaInfo; import brut.androlib.meta.PackageInfo; @@ -26,12 +26,12 @@ import brut.androlib.res.decoder.*; import brut.androlib.res.decoder.ARSCDecoder.ARSCData; import brut.androlib.res.decoder.ARSCDecoder.FlagsOffset; -import brut.directory.*; import brut.androlib.res.util.ExtMXSerializer; import brut.androlib.res.util.ExtXmlSerializer; import brut.androlib.res.xml.ResValuesXmlSerializable; import brut.androlib.res.xml.ResXmlPatcher; import brut.common.BrutException; +import brut.directory.*; import brut.util.*; import org.apache.commons.io.IOUtils; import org.xmlpull.v1.XmlSerializer; @@ -44,9 +44,6 @@ import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; -/** - * @author Ryszard Wiśniewski - */ final public class AndrolibResources { public ResTable getResTable(ExtFile apkFile) throws AndrolibException { return getResTable(apkFile, true); @@ -65,23 +62,16 @@ throws AndrolibException { LOGGER.info("Loading resource table..."); ResPackage[] pkgs = getResPackagesFromApk(apkFile, resTable, sKeepBroken); - ResPackage pkg = null; + ResPackage pkg; switch (pkgs.length) { case 1: pkg = pkgs[0]; break; case 2: - if (pkgs[0].getName().equals("android")) { - LOGGER.warning("Skipping \"android\" package group"); - pkg = pkgs[1]; - break; - } else if (pkgs[0].getName().equals("com.htc")) { - LOGGER.warning("Skipping \"htc\" package group"); - pkg = pkgs[1]; - break; - } - + LOGGER.warning("Skipping package group: " + pkgs[0].getName()); + pkg = pkgs[1]; + break; default: pkg = selectPkgWithMostResSpecs(pkgs); break; @@ -95,8 +85,7 @@ return pkg; } - public ResPackage selectPkgWithMostResSpecs(ResPackage[] pkgs) - throws AndrolibException { + public ResPackage selectPkgWithMostResSpecs(ResPackage[] pkgs) { int id = 0; int value = 0; int index = 0; @@ -132,7 +121,7 @@ } if (pkg.getId() != id) { - throw new AndrolibException("Expected pkg of id: " + String.valueOf(id) + ", got: " + pkg.getId()); + throw new AndrolibException("Expected pkg of id: " + id + ", got: " + pkg.getId()); } resTable.addPackage(pkg, false); @@ -142,7 +131,7 @@ public void decodeManifest(ResTable resTable, ExtFile apkFile, File outDir) throws AndrolibException { - Duo duo = getManifestFileDecoder(); + Duo duo = getManifestFileDecoder(false); ResFileDecoder fileDecoder = duo.m1; // Set ResAttrDecoder @@ -189,7 +178,7 @@ public void decodeManifestWithResources(ResTable resTable, ExtFile apkFile, File outDir) throws AndrolibException { - Duo duo = getResFileDecoder(); + Duo duo = getManifestFileDecoder(true); ResFileDecoder fileDecoder = duo.m1; ResAttrDecoder attrDecoder = duo.m2.getAttrDecoder(); @@ -317,8 +306,8 @@ return Integer.toString(target); } - private File createDoNotCompressExtensionsFile(ApkOptions apkOptions) throws AndrolibException { - if (apkOptions.doNotCompress == null || apkOptions.doNotCompress.isEmpty()) { + private File createDoNotCompressExtensionsFile(BuildOptions buildOptions) throws AndrolibException { + if (buildOptions.doNotCompress == null || buildOptions.doNotCompress.isEmpty()) { return null; } @@ -328,7 +317,7 @@ doNotCompressFile.deleteOnExit(); BufferedWriter fileWriter = new BufferedWriter(new FileWriter(doNotCompressFile)); - for (String extension : apkOptions.doNotCompress) { + for (String extension : buildOptions.doNotCompress) { fileWriter.write(extension); fileWriter.newLine(); } @@ -369,11 +358,11 @@ cmd.add("-o"); cmd.add(resourcesZip.getAbsolutePath()); - if (apkOptions.verbose) { + if (buildOptions.verbose) { cmd.add("-v"); } - if (apkOptions.noCrunch) { + if (buildOptions.noCrunch) { cmd.add("--no-crunch"); } @@ -444,24 +433,24 @@ cmd.add("--enable-sparse-encoding"); } - if (apkOptions.isFramework) { + if (buildOptions.isFramework) { cmd.add("-x"); } - if (apkOptions.doNotCompress != null && !customAapt) { + if (buildOptions.doNotCompress != null && !customAapt) { // Use custom -e option to avoid limits on commandline length. // Can only be used when custom aapt binary is not used. - String extensionsFilePath = createDoNotCompressExtensionsFile(apkOptions).getAbsolutePath(); + String extensionsFilePath = createDoNotCompressExtensionsFile(buildOptions).getAbsolutePath(); cmd.add("-e"); cmd.add(extensionsFilePath); - } else if (apkOptions.doNotCompress != null) { - for (String file : apkOptions.doNotCompress) { + } else if (buildOptions.doNotCompress != null) { + for (String file : buildOptions.doNotCompress) { cmd.add("-0"); cmd.add(file); } } - if (!apkOptions.resourcesAreCompressed) { + if (!buildOptions.resourcesAreCompressed) { cmd.add("-0"); cmd.add("arsc"); } @@ -486,7 +475,7 @@ cmd.add(rawDir.getAbsolutePath()); } - if (apkOptions.verbose) { + if (buildOptions.verbose) { cmd.add("-v"); } @@ -509,16 +498,16 @@ cmd.add("p"); - if (apkOptions.verbose) { // output aapt verbose + if (buildOptions.verbose) { // output aapt verbose cmd.add("-v"); } - if (apkOptions.updateFiles) { + if (buildOptions.updateFiles) { cmd.add("-u"); } - if (apkOptions.debugMode) { // inject debuggable="true" into manifest + if (buildOptions.debugMode) { // inject debuggable="true" into manifest cmd.add("--debug-mode"); } - if (apkOptions.noCrunch) { + if (buildOptions.noCrunch) { cmd.add("--no-crunch"); } // force package id so that some frameworks build with correct id @@ -566,24 +555,24 @@ cmd.add("-F"); cmd.add(apkFile.getAbsolutePath()); - if (apkOptions.isFramework) { + if (buildOptions.isFramework) { cmd.add("-x"); } - if (apkOptions.doNotCompress != null && !customAapt) { + if (buildOptions.doNotCompress != null && !customAapt) { // Use custom -e option to avoid limits on commandline length. // Can only be used when custom aapt binary is not used. - String extensionsFilePath = createDoNotCompressExtensionsFile(apkOptions).getAbsolutePath(); + String extensionsFilePath = createDoNotCompressExtensionsFile(buildOptions).getAbsolutePath(); cmd.add("-e"); cmd.add(extensionsFilePath); - } else if (apkOptions.doNotCompress != null) { - for (String file : apkOptions.doNotCompress) { + } else if (buildOptions.doNotCompress != null) { + for (String file : buildOptions.doNotCompress) { cmd.add("-0"); cmd.add(file); } } - if (!apkOptions.resourcesAreCompressed) { + if (!buildOptions.resourcesAreCompressed) { cmd.add("-0"); cmd.add("arsc"); } @@ -621,9 +610,9 @@ public void aaptPackage(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include) throws AndrolibException { - String aaptPath = apkOptions.aaptPath; + String aaptPath = buildOptions.aaptPath; boolean customAapt = !aaptPath.isEmpty(); - List cmd = new ArrayList(); + List cmd = new ArrayList<>(); try { String aaptCommand = AaptManager.getAaptExecutionCommand(aaptPath, getAaptBinaryFile()); @@ -633,7 +622,7 @@ cmd.add(AaptManager.getAaptBinaryName(getAaptVersion())); } - if (apkOptions.isAapt2()) { + if (buildOptions.isAapt2()) { aapt2Package(apkFile, manifest, resDir, rawDir, assetDir, include, cmd, customAapt); return; } @@ -644,7 +633,7 @@ throws AndrolibException { try { - ZipUtils.zipFolders(rawDir, apkFile, assetDir, apkOptions.doNotCompress); + ZipUtils.zipFolders(rawDir, apkFile, assetDir, buildOptions.doNotCompress); } catch (IOException | BrutException ex) { throw new AndrolibException(ex); } @@ -675,6 +664,9 @@ return ResConfigFlags.SDK_R; case "S": return ResConfigFlags.SDK_S; + case "T": + case "Tiramisu": + return ResConfigFlags.SDK_DEVELOPMENT; default: return Integer.parseInt(sdkVersion); } @@ -709,17 +701,19 @@ axmlParser.setAttrDecoder(new ResAttrDecoder()); decoders.setDecoder("xml", new XmlPullStreamDecoder(axmlParser, getResXmlSerializer())); - return new Duo(new ResFileDecoder(decoders), axmlParser); + return new Duo<>(new ResFileDecoder(decoders), axmlParser); } - public Duo getManifestFileDecoder() { + public Duo getManifestFileDecoder(boolean withResources) { ResStreamDecoderContainer decoders = new ResStreamDecoderContainer(); - AXmlResourceParser axmlParser = new AXmlResourceParser(); - + AXmlResourceParser axmlParser = new AndroidManifestResourceParser(); + if (withResources) { + axmlParser.setAttrDecoder(new ResAttrDecoder()); + } decoders.setDecoder("xml", new XmlPullStreamDecoder(axmlParser,getResXmlSerializer())); - return new Duo(new ResFileDecoder(decoders), axmlParser); + return new Duo<>(new ResFileDecoder(decoders), axmlParser); } public ExtMXSerializer getResXmlSerializer() { @@ -785,15 +779,10 @@ throws AndrolibException { try { Directory dir = apkFile.getDirectory(); - BufferedInputStream bfi = new BufferedInputStream(dir.getFileInput("resources.arsc")); - try { + try (BufferedInputStream bfi = new BufferedInputStream(dir.getFileInput("resources.arsc"))) { return ARSCDecoder.decode(bfi, false, keepBroken, resTable).getPackages(); - } finally { - try { - bfi.close(); - } catch (IOException ignored) {} } - } catch (DirectoryException ex) { + } catch (DirectoryException | IOException ex) { throw new AndrolibException("Could not load resources.arsc from file: " + apkFile, ex); } } @@ -810,13 +799,13 @@ } } - apk = new File(dir, String.valueOf(id) + ".apk"); + apk = new File(dir, id + ".apk"); if (apk.exists()) { return apk; } if (id == 1) { - try (InputStream in = AndrolibResources.class.getResourceAsStream("/brut/androlib/android-framework.jar"); + try (InputStream in = getAndroidFrameworkResourcesAsStream(); OutputStream out = new FileOutputStream(apk)) { IOUtils.copy(in, out); return apk; @@ -838,7 +827,7 @@ LOGGER.warning("Can't empty framework directory, no file found at: " + apk.getAbsolutePath()); } else { try { - if (apk.exists() && dir.listFiles().length > 1 && ! apkOptions.forceDeleteFramework) { + if (apk.exists() && dir.listFiles().length > 1 && ! buildOptions.forceDeleteFramework) { LOGGER.warning("More than default framework detected. Please run command with `--force` parameter to wipe framework directory."); } else { for (File file : dir.listFiles()) { @@ -869,7 +858,7 @@ } public void installFramework(File frameFile) throws AndrolibException { - installFramework(frameFile, apkOptions.frameworkTag); + installFramework(frameFile, buildOptions.frameworkTag); } public void installFramework(File frameFile, String tag) @@ -890,8 +879,8 @@ ARSCData arsc = ARSCDecoder.decode(new ByteArrayInputStream(data), true, true); publicizeResources(data, arsc.getFlagsOffsets()); - File outFile = new File(getFrameworkDir(), String.valueOf(arsc - .getOnePackage().getId()) + File outFile = new File(getFrameworkDir(), arsc + .getOnePackage().getId() + (tag == null ? "" : '-' + tag) + ".apk"); @@ -906,7 +895,7 @@ out.putNextEntry(entry); out.write(data); out.closeEntry(); - + //Write fake AndroidManifest.xml file to support original aapt entry = zip.getEntry("AndroidManifest.xml"); if (entry != null) { @@ -949,8 +938,7 @@ publicizeResources(arsc, ARSCDecoder.decode(new ByteArrayInputStream(arsc), true, true).getFlagsOffsets()); } - public void publicizeResources(byte[] arsc, FlagsOffset[] flagsOffsets) - throws AndrolibException { + public void publicizeResources(byte[] arsc, FlagsOffset[] flagsOffsets) { for (FlagsOffset flags : flagsOffsets) { int offset = flags.offset + 3; int end = offset + 4 * flags.count; @@ -969,8 +957,8 @@ String path; // if a framework path was specified on the command line, use it - if (apkOptions.frameworkFolderLocation != null) { - path = apkOptions.frameworkFolderLocation; + if (buildOptions.frameworkFolderLocation != null) { + path = buildOptions.frameworkFolderLocation; } else { File parentPath = new File(System.getProperty("user.home")); @@ -995,7 +983,7 @@ if (! dir.exists()) { if (! dir.mkdirs()) { - if (apkOptions.frameworkFolderLocation != null) { + if (buildOptions.frameworkFolderLocation != null) { LOGGER.severe("Can't create Framework directory: " + dir); } throw new AndrolibException(String.format( @@ -1004,7 +992,7 @@ } } - if (apkOptions.frameworkFolderLocation == null) { + if (buildOptions.frameworkFolderLocation == null) { if (! dir.canWrite()) { LOGGER.severe(String.format("WARNING: Could not write to (%1$s), using %2$s instead...", dir.getAbsolutePath(), System.getProperty("java.io.tmpdir"))); @@ -1022,24 +1010,20 @@ private File getAaptBinaryFile() throws AndrolibException { try { if (getAaptVersion() == 2) { - return AaptManager.getAppt2(); + return AaptManager.getAapt2(); } - return AaptManager.getAppt1(); + return AaptManager.getAapt1(); } catch (BrutException ex) { throw new AndrolibException(ex); } } private int getAaptVersion() { - return apkOptions.isAapt2() ? 2 : 1; + return buildOptions.isAapt2() ? 2 : 1; } - public File getAndroidResourcesFile() throws AndrolibException { - try { - return Jar.getResourceAsFile("/brut/androlib/android-framework.jar"); - } catch (BrutException ex) { - throw new AndrolibException(ex); - } + public InputStream getAndroidFrameworkResourcesAsStream() { + return Jar.class.getResourceAsStream("/brut/androlib/android-framework.jar"); } public void close() throws IOException { @@ -1048,7 +1032,7 @@ } } - public ApkOptions apkOptions; + public BuildOptions buildOptions; // TODO: dirty static hack. I have to refactor decoding mechanisms. public static boolean sKeepBroken = false; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfigFlags.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfigFlags.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfigFlags.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfigFlags.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,9 +18,6 @@ import java.util.logging.Logger; -/** - * @author Ryszard Wiśniewski - */ public class ResConfigFlags { public final short mcc; public final short mnc; @@ -539,10 +536,12 @@ public final static byte SDK_P = 28; public final static byte SDK_Q = 29; public final static byte SDK_R = 30; + public final static byte SDK_S = 31; + public final static byte SDK_T = 32; // AOSP has this as 10,000 for dev purposes. // platform_frameworks_base/commit/c7a1109a1fe0771d4c9b572dcf178e2779fc4f2d - public final static int SDK_S = 10000; + public final static int SDK_DEVELOPMENT = 10000; public final static byte ORIENTATION_ANY = 0; public final static byte ORIENTATION_PORT = 1; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,6 @@ */ package brut.androlib.res.data; -/** - * @author Ryszard Wiśniewski - */ public class ResID { public final int package_; public final int type; @@ -62,9 +59,6 @@ return false; } final ResID other = (ResID) obj; - if (this.id != other.id) { - return false; - } - return true; + return this.id == other.id; } } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResPackage.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResPackage.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResPackage.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResPackage.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -25,17 +25,14 @@ import java.util.*; import java.util.logging.Logger; -/** - * @author Ryszard Wiśniewski - */ public class ResPackage { private final ResTable mResTable; private final int mId; private final String mName; - private final Map mResSpecs = new LinkedHashMap(); - private final Map mConfigs = new LinkedHashMap(); - private final Map mTypes = new LinkedHashMap(); - private final Set mSynthesizedRes = new HashSet(); + private final Map mResSpecs = new LinkedHashMap<>(); + private final Map mConfigs = new LinkedHashMap<>(); + private final Map mTypes = new LinkedHashMap<>(); + private final Set mSynthesizedRes = new HashSet<>(); private ResValueFactory mValueFactory; @@ -46,7 +43,7 @@ } public List listResSpecs() { - return new ArrayList(mResSpecs.values()); + return new ArrayList<>(mResSpecs.values()); } public boolean hasResSpec(ResID resID) { @@ -61,27 +58,11 @@ return spec; } - public List getConfigs() { - return new ArrayList(mConfigs.values()); - } - - public boolean hasConfig(ResConfigFlags flags) { - return mConfigs.containsKey(flags); - } - - public ResType getConfig(ResConfigFlags flags) throws AndrolibException { - ResType config = mConfigs.get(flags); - if (config == null) { - throw new UndefinedResObjectException("config: " + flags); - } - return config; - } - public int getResSpecCount() { return mResSpecs.size(); } - public ResType getOrCreateConfig(ResConfigFlags flags) throws AndrolibException { + public ResType getOrCreateConfig(ResConfigFlags flags) { ResType config = mConfigs.get(flags); if (config == null) { config = new ResType(flags); @@ -90,14 +71,6 @@ return config; } - public List listTypes() { - return new ArrayList(mTypes.values()); - } - - public boolean hasType(String typeName) { - return mTypes.containsKey(typeName); - } - public ResTypeSpec getType(String typeName) throws AndrolibException { ResTypeSpec type = mTypes.get(typeName); if (type == null) { @@ -107,7 +80,7 @@ } public Set listFiles() { - Set ret = new HashSet(); + Set ret = new HashSet<>(); for (ResResSpec spec : mResSpecs.values()) { for (ResResource res : spec.listResources()) { if (res.getValue() instanceof ResFileValue) { @@ -119,13 +92,13 @@ } public Collection listValuesFiles() { - Map, ResValuesFile> ret = new HashMap, ResValuesFile>(); + Map, ResValuesFile> ret = new HashMap<>(); for (ResResSpec spec : mResSpecs.values()) { for (ResResource res : spec.listResources()) { if (res.getValue() instanceof ResValuesXmlSerializable) { ResTypeSpec type = res.getResSpec().getType(); ResType config = res.getConfig(); - Duo key = new Duo(type, config); + Duo key = new Duo<>(type, config); ResValuesFile values = ret.get(key); if (values == null) { values = new ResValuesFile(this, type, config); @@ -154,7 +127,7 @@ return mSynthesizedRes.contains(resId); } - public void removeResSpec(ResResSpec spec) throws AndrolibException { + public void removeResSpec(ResResSpec spec) { mResSpecs.remove(spec.getId()); } @@ -164,13 +137,7 @@ } } - public void addConfig(ResType config) throws AndrolibException { - if (mConfigs.put(config.getFlags(), config) != null) { - throw new AndrolibException("Multiple configs: " + config); - } - } - - public void addType(ResTypeSpec type) throws AndrolibException { + public void addType(ResTypeSpec type) { if (mTypes.containsKey(type.getName())) { LOGGER.warning("Multiple types detected! " + type + " ignored!"); } else { @@ -178,12 +145,6 @@ } } - public void addResource(ResResource res) { - } - - public void removeResource(ResResource res) { - } - public void addSynthesizedRes(int resId) { mSynthesizedRes.add(new ResID(resId)); } @@ -202,13 +163,10 @@ return false; } final ResPackage other = (ResPackage) obj; - if (this.mResTable != other.mResTable && (this.mResTable == null || !this.mResTable.equals(other.mResTable))) { - return false; - } - if (this.mId != other.mId) { + if (!Objects.equals(this.mResTable, other.mResTable)) { return false; } - return true; + return this.mId == other.mId; } @Override diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResource.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResource.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResource.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResource.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,9 +19,6 @@ import brut.androlib.AndrolibException; import brut.androlib.res.data.value.ResValue; -/** - * @author Ryszard Wiśniewski - */ public class ResResource { private final ResType mConfig; private final ResResSpec mResSpec; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,37 +18,41 @@ import brut.androlib.AndrolibException; import brut.androlib.err.UndefinedResObjectException; -import java.util.*; +import brut.androlib.res.decoder.ARSCDecoder; import org.apache.commons.lang3.StringUtils; -/** - * @author Ryszard Wiśniewski - */ +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + public class ResResSpec { private final ResID mId; private final String mName; + private final int mFlags; private final ResPackage mPackage; private final ResTypeSpec mType; - private final Map mResources = new LinkedHashMap(); + private final Map mResources = new LinkedHashMap<>(); - public ResResSpec(ResID id, String name, ResPackage pkg, ResTypeSpec type) { + public ResResSpec(ResID id, String name, int flags, ResPackage pkg, ResTypeSpec type) { + this.mFlags = flags; this.mId = id; String cleanName; ResResSpec resResSpec = type.getResSpecUnsafe(name); if (resResSpec != null) { - cleanName = name + "_APKTOOL_DUPLICATENAME_" + id.toString(); + cleanName = String.format("APKTOOL_DUPLICATE_%s_%s", type, id.toString()); } else { cleanName = ((name == null || name.isEmpty()) ? ("APKTOOL_DUMMYVAL_" + id.toString()) : name); } - + this.mName = cleanName; this.mPackage = pkg; this.mType = type; } public Set listResources() { - return new LinkedHashSet(mResources.values()); + return new LinkedHashSet<>(mResources.values()); } public ResResource getResource(ResType config) throws AndrolibException { @@ -63,14 +67,6 @@ return res; } - public boolean hasResource(ResType config) { - return hasResource(config.getFlags()); - } - - private boolean hasResource(ResConfigFlags flags) { - return mResources.containsKey(flags); - } - public ResResource getDefaultResource() throws AndrolibException { return getResource(new ResConfigFlags()); } @@ -79,8 +75,8 @@ return mResources.containsKey(new ResConfigFlags()); } - public String getFullName() { - return getFullName(false, false); + public boolean isPublicResource() { + return (getFlags() & ARSCDecoder.ENTRY_FLAG_PUBLIC) != 0; } public String getFullName(ResPackage relativeToPackage, boolean excludeType) { @@ -88,8 +84,10 @@ } public String getFullName(boolean excludePackage, boolean excludeType) { - return (excludePackage ? "" : getPackage().getName() + ":") - + (excludeType ? "" : getType().getName() + "/") + getName(); + String privateSuffix = isPublicResource() ? "" : "*"; + String packageName = excludePackage ? "" : getPackage().getName() + ":"; + return (packageName.isEmpty() ? "" : privateSuffix + packageName) + + (excludeType ? "" : getType().getName() + "/") + getName(); } public ResID getId() { @@ -108,6 +106,10 @@ return mType; } + public int getFlags() { + return mFlags; + } + public boolean isDummyResSpec() { return getName().startsWith("APKTOOL_DUMMY_"); } @@ -123,11 +125,6 @@ } } - public void removeResource(ResResource res) throws AndrolibException { - ResConfigFlags flags = res.getConfig().getFlags(); - mResources.remove(flags); - } - @Override public String toString() { return mId.toString() + " " + mType.toString() + "/" + mName; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -23,16 +23,13 @@ import brut.androlib.res.data.value.ResValue; import java.util.*; -/** - * @author Ryszard Wiśniewski - */ public class ResTable { private final AndrolibResources mAndRes; - private final Map mPackagesById = new HashMap(); - private final Map mPackagesByName = new HashMap(); - private final Set mMainPackages = new LinkedHashSet(); - private final Set mFramePackages = new LinkedHashSet(); + private final Map mPackagesById = new HashMap<>(); + private final Map mPackagesByName = new HashMap<>(); + private final Set mMainPackages = new LinkedHashSet<>(); + private final Set mFramePackages = new LinkedHashSet<>(); private String mPackageRenamed; private String mPackageOriginal; @@ -41,8 +38,8 @@ private boolean mSharedLibrary = false; private boolean mSparseResources = false; - private Map mSdkInfo = new LinkedHashMap<>(); - private VersionInfo mVersionInfo = new VersionInfo(); + private final Map mSdkInfo = new LinkedHashMap<>(); + private final VersionInfo mVersionInfo = new VersionInfo(); public ResTable() { mAndRes = null; @@ -81,7 +78,7 @@ return pkg; } if (mAndRes != null) { - return mAndRes.loadFrameworkPkg(this, id, mAndRes.apkOptions.frameworkTag); + return mAndRes.loadFrameworkPkg(this, id, mAndRes.buildOptions.frameworkTag); } throw new UndefinedResObjectException(String.format("package: id=%d", id)); } @@ -120,14 +117,6 @@ return pkg; } - public boolean hasPackage(int id) { - return mPackagesById.containsKey(id); - } - - public boolean hasPackage(String name) { - return mPackagesByName.containsKey(name); - } - public ResValue getValue(String package_, String type, String name) throws AndrolibException { return getPackage(package_).getType(type).getResSpec(name).getDefaultResource().getValue(); } @@ -135,7 +124,7 @@ public void addPackage(ResPackage pkg, boolean main) throws AndrolibException { Integer id = pkg.getId(); if (mPackagesById.containsKey(id)) { - throw new AndrolibException("Multiple packages: id=" + id.toString()); + throw new AndrolibException("Multiple packages: id=" + id); } String name = pkg.getName(); if (mPackagesByName.containsKey(name)) { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResType.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResType.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResType.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResType.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,21 +20,14 @@ import brut.androlib.err.UndefinedResObjectException; import java.util.*; -/** - * @author Ryszard Wiśniewski - */ public class ResType { private final ResConfigFlags mFlags; - private final Map mResources = new LinkedHashMap(); + private final Map mResources = new LinkedHashMap<>(); public ResType(ResConfigFlags flags) { this.mFlags = flags; } - public Set listResources() { - return new LinkedHashSet(mResources.values()); - } - public ResResource getResource(ResResSpec spec) throws AndrolibException { ResResource res = mResources.get(spec); if (res == null) { @@ -43,10 +36,6 @@ return res; } - public Set listResSpecs() { - return mResources.keySet(); - } - public ResConfigFlags getFlags() { return mFlags; } @@ -55,11 +44,6 @@ addResource(res, false); } - public void removeResource(ResResource res) throws AndrolibException { - ResResSpec spec = res.getResSpec(); - mResources.remove(spec); - } - public void addResource(ResResource res, boolean overwrite) throws AndrolibException { ResResSpec spec = res.getResSpec(); if (mResources.put(spec, res) != null && !overwrite) { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,9 +20,6 @@ import brut.androlib.err.UndefinedResObjectException; import java.util.*; -/** - * @author Ryszard Wiśniewski - */ public final class ResTypeSpec { public static final String RES_TYPE_NAME_ARRAY = "array"; @@ -31,7 +28,7 @@ public static final String RES_TYPE_NAME_ATTR = "attr"; private final String mName; - private final Map mResSpecs = new LinkedHashMap(); + private final Map mResSpecs = new LinkedHashMap<>(); private final ResTable mResTable; private final ResPackage mPackage; @@ -55,18 +52,10 @@ return mId; } - public int getEntryCount() { - return mEntryCount; - } - public boolean isString() { return mName.equalsIgnoreCase("string"); } - public Set listResSpecs() { - return new LinkedHashSet(mResSpecs.values()); - } - public ResResSpec getResSpec(String name) throws AndrolibException { ResResSpec spec = getResSpecUnsafe(name); if (spec == null) { @@ -79,7 +68,7 @@ return mResSpecs.get(name); } - public void removeResSpec(ResResSpec spec) throws AndrolibException { + public void removeResSpec(ResResSpec spec) { mResSpecs.remove(spec.getName()); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResUnknownFiles.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResUnknownFiles.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResUnknownFiles.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResUnknownFiles.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,9 +19,6 @@ import java.util.LinkedHashMap; import java.util.Map; -/** - * @author Connor Tumbleson - */ public class ResUnknownFiles { private final Map mUnknownFiles = new LinkedHashMap<>(); diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResValuesFile.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResValuesFile.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResValuesFile.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResValuesFile.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,16 +17,14 @@ package brut.androlib.res.data; import java.util.LinkedHashSet; +import java.util.Objects; import java.util.Set; -/** - * @author Ryszard Wiśniewski - */ public class ResValuesFile { private final ResPackage mPackage; private final ResTypeSpec mType; private final ResType mConfig; - private final Set mResources = new LinkedHashSet(); + private final Set mResources = new LinkedHashSet<>(); public ResValuesFile(ResPackage pkg, ResTypeSpec type, ResType config) { this.mPackage = pkg; @@ -48,10 +46,6 @@ return mType; } - public ResType getConfig() { - return mConfig; - } - public boolean isSynthesized(ResResource res) { return mPackage.isSynthesized(res.getResSpec().getId()); } @@ -69,13 +63,10 @@ return false; } final ResValuesFile other = (ResValuesFile) obj; - if (this.mType != other.mType && (this.mType == null || !this.mType.equals(other.mType))) { - return false; - } - if (this.mConfig != other.mConfig && (this.mConfig == null || !this.mConfig.equals(other.mConfig))) { + if (!Objects.equals(this.mType, other.mType)) { return false; } - return true; + return Objects.equals(this.mConfig, other.mConfig); } @Override diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResArrayValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResArrayValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResArrayValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResArrayValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,14 +20,11 @@ import brut.androlib.res.data.ResResource; import brut.androlib.res.xml.ResValuesXmlSerializable; import brut.util.Duo; +import org.xmlpull.v1.XmlSerializer; + import java.io.IOException; import java.util.Arrays; -import org.xmlpull.v1.XmlSerializer; - -/** - * @author Ryszard Wiśniewski - */ public class ResArrayValue extends ResBagValue implements ResValuesXmlSerializable { @@ -54,17 +51,17 @@ serializer.attribute(null, "name", res.getResSpec().getName()); // lets check if we need to add formatted="false" to this array - for (int i = 0; i < mItems.length; i++) { - if (mItems[i].hasMultipleNonPositionalSubstitutions()) { + for (ResScalarValue item : mItems) { + if (item.hasMultipleNonPositionalSubstitutions()) { serializer.attribute(null, "formatted", "false"); break; } } // add 's - for (int i = 0; i < mItems.length; i++) { + for (ResScalarValue mItem : mItems) { serializer.startTag(null, "item"); - serializer.text(mItems[i].encodeAsResXmlNonEscapedItemValue()); + serializer.text(mItem.encodeAsResXmlNonEscapedItemValue()); serializer.endTag(null, "item"); } serializer.endTag(null, type); @@ -75,16 +72,16 @@ return null; } String type = mItems[0].getType(); - for (int i = 0; i < mItems.length; i++) { - if (mItems[i].encodeAsResXmlItemValue().startsWith("@string")) { + for (ResScalarValue mItem : mItems) { + if (mItem.encodeAsResXmlItemValue().startsWith("@string")) { return "string"; - } else if (mItems[i].encodeAsResXmlItemValue().startsWith("@drawable")) { + } else if (mItem.encodeAsResXmlItemValue().startsWith("@drawable")) { return null; - } else if (mItems[i].encodeAsResXmlItemValue().startsWith("@integer")) { + } else if (mItem.encodeAsResXmlItemValue().startsWith("@integer")) { return "integer"; } else if (!"string".equals(type) && !"integer".equals(type)) { return null; - } else if (!type.equals(mItems[i].getType())) { + } else if (!type.equals(mItem.getType())) { return null; } } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResAttr.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResAttr.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResAttr.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResAttr.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,12 +21,10 @@ import brut.androlib.res.data.ResResource; import brut.androlib.res.xml.ResValuesXmlSerializable; import brut.util.Duo; -import java.io.IOException; import org.xmlpull.v1.XmlSerializer; -/** - * @author Ryszard Wiśniewski - */ +import java.io.IOException; + public class ResAttr extends ResBagValue implements ResValuesXmlSerializable { ResAttr(ResReferenceValue parentVal, int type, Integer min, Integer max, Boolean l10n) { @@ -37,14 +35,13 @@ mL10n = l10n; } - public String convertToResXmlFormat(ResScalarValue value) - throws AndrolibException { + public String convertToResXmlFormat(ResScalarValue value) throws AndrolibException { return null; } @Override - public void serializeToResValuesXml(XmlSerializer serializer, - ResResource res) throws IOException, AndrolibException { + public void serializeToResValuesXml(XmlSerializer serializer, ResResource res) + throws IOException, AndrolibException { String type = getTypeAsString(); serializer.startTag(null, "attr"); @@ -92,30 +89,24 @@ if (i == items.length) { return new ResAttr(parent, scalarType, min, max, l10n); } - Duo[] attrItems = new Duo[items.length - - i]; + Duo[] attrItems = new Duo[items.length - i]; int j = 0; for (; i < items.length; i++) { int resId = items[i].m1; pkg.addSynthesizedRes(resId); - attrItems[j++] = new Duo( - factory.newReference(resId, null), - (ResIntValue) items[i].m2); + attrItems[j++] = new Duo<>(factory.newReference(resId, null), (ResIntValue) items[i].m2); } switch (type & 0xff0000) { case TYPE_ENUM: - return new ResEnumAttr(parent, scalarType, min, max, l10n, - attrItems); + return new ResEnumAttr(parent, scalarType, min, max, l10n, attrItems); case TYPE_FLAGS: - return new ResFlagsAttr(parent, scalarType, min, max, l10n, - attrItems); + return new ResFlagsAttr(parent, scalarType, min, max, l10n, attrItems); } throw new AndrolibException("Could not decode attr value"); } - protected void serializeBody(XmlSerializer serializer, ResResource res) - throws AndrolibException, IOException { + protected void serializeBody(XmlSerializer serializer, ResResource res) throws AndrolibException, IOException { } protected String getTypeAsString() { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBagValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBagValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBagValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBagValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,12 +20,10 @@ import brut.androlib.res.data.ResResource; import brut.androlib.res.xml.ResValuesXmlSerializable; import brut.util.Duo; -import java.io.IOException; import org.xmlpull.v1.XmlSerializer; -/** - * @author Ryszard Wiśniewski - */ +import java.io.IOException; + public class ResBagValue extends ResValue implements ResValuesXmlSerializable { protected final ResReferenceValue mParent; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBoolValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBoolValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBoolValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResBoolValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,6 @@ */ package brut.androlib.res.data.value; -/** - * @author Ryszard Wiśniewski - */ public class ResBoolValue extends ResScalarValue { private final boolean mValue; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResColorValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResColorValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResColorValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResColorValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,6 @@ */ package brut.androlib.res.data.value; -/** - * @author Ryszard Wiśniewski - */ public class ResColorValue extends ResIntValue { public ResColorValue(int value, String rawValue) { super(value, rawValue, "color"); @@ -28,4 +25,4 @@ protected String encodeAsResXml() { return String.format("#%08x", mValue); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResDimenValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResDimenValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResDimenValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResDimenValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,9 +19,6 @@ import android.util.TypedValue; import brut.androlib.AndrolibException; -/** - * @author Ryszard Wiśniewski - */ public class ResDimenValue extends ResIntValue { public ResDimenValue(int value, String rawValue) { super(value, rawValue, "dimen"); diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEmptyValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEmptyValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEmptyValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEmptyValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -42,4 +42,4 @@ protected String encodeAsResXml() throws AndrolibException { return "@empty"; } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,14 +20,12 @@ import brut.androlib.res.data.ResResSpec; import brut.androlib.res.data.ResResource; import brut.util.Duo; +import org.xmlpull.v1.XmlSerializer; + import java.io.IOException; import java.util.HashMap; import java.util.Map; -import org.xmlpull.v1.XmlSerializer; -/** - * @author Ryszard Wiśniewski - */ public class ResEnumAttr extends ResAttr { ResEnumAttr(ResReferenceValue parent, int type, Integer min, Integer max, Boolean l10n, Duo[] items) { @@ -82,5 +80,5 @@ } private final Duo[] mItems; - private final Map mItemsCache = new HashMap(); + private final Map mItemsCache = new HashMap<>(); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFileValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFileValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFileValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFileValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,9 +18,6 @@ import brut.androlib.AndrolibException; -/** - * @author Ryszard Wiśniewski - */ public class ResFileValue extends ResIntBasedValue { private final String mPath; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFlagsAttr.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFlagsAttr.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFlagsAttr.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFlagsAttr.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,14 +19,11 @@ import brut.androlib.AndrolibException; import brut.androlib.res.data.ResResource; import brut.util.Duo; +import org.xmlpull.v1.XmlSerializer; + import java.io.IOException; import java.util.Arrays; -import java.util.Comparator; -import org.xmlpull.v1.XmlSerializer; -/** - * @author Ryszard Wiśniewski - */ public class ResFlagsAttr extends ResAttr { ResFlagsAttr(ResReferenceValue parent, int type, Integer min, Integer max, Boolean l10n, Duo[] items) { @@ -57,8 +54,7 @@ FlagItem[] flagItems = new FlagItem[mFlags.length]; int[] flags = new int[mFlags.length]; int flagsCount = 0; - for (int i = 0; i < mFlags.length; i++) { - FlagItem flagItem = mFlags[i]; + for (FlagItem flagItem : mFlags) { int flag = flagItem.flag; if ((intVal & flag) != flag) { @@ -76,20 +72,18 @@ @Override protected void serializeBody(XmlSerializer serializer, ResResource res) throws AndrolibException, IOException { - for (int i = 0; i < mItems.length; i++) { - FlagItem item = mItems[i]; - + for (FlagItem item : mItems) { serializer.startTag(null, "flag"); serializer.attribute(null, "name", item.getValue()); serializer.attribute(null, "value", - String.format("0x%08x", item.flag)); + String.format("0x%08x", item.flag)); serializer.endTag(null, "flag"); } } private boolean isSubpartOf(int flag, int[] flags) { - for (int i = 0; i < flags.length; i++) { - if ((flags[i] & flag) == flag) { + for (int j : flags) { + if ((j & flag) == flag) { return true; } } @@ -97,12 +91,12 @@ } private String renderFlags(FlagItem[] flags) throws AndrolibException { - String ret = ""; - for (int i = 0; i < flags.length; i++) { - ret += "|" + flags[i].getValue(); + StringBuilder ret = new StringBuilder(); + for (FlagItem flag : flags) { + ret.append("|").append(flag.getValue()); } - if (ret.isEmpty()) { - return ret; + if (ret.length() == 0) { + return ret.toString(); } return ret.substring(1); } @@ -117,8 +111,7 @@ FlagItem[] flags = new FlagItem[mItems.length]; int flagsCount = 0; - for (int i = 0; i < mItems.length; i++) { - FlagItem item = mItems[i]; + for (FlagItem item : mItems) { if (item.flag == 0) { zeroFlags[zeroFlagsCount++] = item; } else { @@ -129,13 +122,7 @@ mZeroFlags = Arrays.copyOf(zeroFlags, zeroFlagsCount); mFlags = Arrays.copyOf(flags, flagsCount); - Arrays.sort(mFlags, new Comparator() { - @Override - public int compare(FlagItem o1, FlagItem o2) { - return Integer.valueOf(Integer.bitCount(o2.flag)).compareTo( - Integer.bitCount(o1.flag)); - } - }); + Arrays.sort(mFlags, (o1, o2) -> Integer.compare(Integer.bitCount(o2.flag), Integer.bitCount(o1.flag))); } private final FlagItem[] mItems; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFloatValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFloatValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFloatValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFloatValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,6 @@ */ package brut.androlib.res.data.value; -/** - * @author Ryszard Wiśniewski - */ public class ResFloatValue extends ResScalarValue { private final float mValue; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFractionValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFractionValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFractionValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResFractionValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,9 +19,6 @@ import android.util.TypedValue; import brut.androlib.AndrolibException; -/** - * @author Ryszard Wiśniewski - */ public class ResFractionValue extends ResIntValue { public ResFractionValue(int value, String rawValue) { super(value, rawValue, "fraction"); diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIdValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIdValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIdValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIdValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,22 +16,17 @@ */ package brut.androlib.res.data.value; -import brut.androlib.AndrolibException; import brut.androlib.res.data.ResResource; import brut.androlib.res.xml.ResValuesXmlSerializable; -import java.io.IOException; import org.xmlpull.v1.XmlSerializer; -/** - * @author Ryszard Wiśniewski - */ +import java.io.IOException; + public class ResIdValue extends ResValue implements ResValuesXmlSerializable { @Override - public void serializeToResValuesXml(XmlSerializer serializer, - ResResource res) throws IOException, AndrolibException { + public void serializeToResValuesXml(XmlSerializer serializer, ResResource res) throws IOException { serializer.startTag(null, "item"); - serializer - .attribute(null, "type", res.getResSpec().getType().getName()); + serializer.attribute(null, "type", res.getResSpec().getType().getName()); serializer.attribute(null, "name", res.getResSpec().getName()); serializer.endTag(null, "item"); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntBasedValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntBasedValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntBasedValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntBasedValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,6 @@ */ package brut.androlib.res.data.value; -/** - * @author Matt Mastracci - */ public class ResIntBasedValue extends ResValue { private final int mRawIntValue; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResIntValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,9 +19,6 @@ import android.util.TypedValue; import brut.androlib.AndrolibException; -/** - * @author Ryszard Wiśniewski - */ public class ResIntValue extends ResScalarValue { protected final int mValue; private int type; @@ -44,4 +41,4 @@ protected String encodeAsResXml() throws AndrolibException { return TypedValue.coerceToString(type, mValue); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResPluralsValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResPluralsValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResPluralsValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResPluralsValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,12 +21,10 @@ import brut.androlib.res.xml.ResValuesXmlSerializable; import brut.androlib.res.xml.ResXmlEncoders; import brut.util.Duo; -import java.io.IOException; import org.xmlpull.v1.XmlSerializer; -/** - * @author Ryszard Wiśniewski - */ +import java.io.IOException; + public class ResPluralsValue extends ResBagValue implements ResValuesXmlSerializable { ResPluralsValue(ResReferenceValue parent, @@ -34,8 +32,8 @@ super(parent); mItems = new ResScalarValue[6]; - for (int i = 0; i < items.length; i++) { - mItems[items[i].m1 - BAG_KEY_PLURALS_START] = items[i].m2; + for (Duo item : items) { + mItems[item.m1 - BAG_KEY_PLURALS_START] = item.m2; } } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResReferenceValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResReferenceValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResReferenceValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResReferenceValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,9 +21,6 @@ import brut.androlib.res.data.ResPackage; import brut.androlib.res.data.ResResSpec; -/** - * @author Ryszard Wiśniewski - */ public class ResReferenceValue extends ResIntValue { private final ResPackage mPackage; private final boolean mTheme; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResScalarValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,12 +21,10 @@ import brut.androlib.res.xml.ResValuesXmlSerializable; import brut.androlib.res.xml.ResXmlEncodable; import brut.androlib.res.xml.ResXmlEncoders; -import java.io.IOException; import org.xmlpull.v1.XmlSerializer; -/** - * @author Ryszard Wiśniewski - */ +import java.io.IOException; + public abstract class ResScalarValue extends ResIntBasedValue implements ResXmlEncodable, ResValuesXmlSerializable { protected final String mType; @@ -62,7 +60,7 @@ return encodeAsResXmlValue().replace("&", "&").replace("<","<"); } - public boolean hasMultipleNonPositionalSubstitutions() throws AndrolibException { + public boolean hasMultipleNonPositionalSubstitutions() { return ResXmlEncoders.hasMultipleNonPositionalSubstitutions(mRawValue); } @@ -83,6 +81,11 @@ } } + // Dummy attributes should be with type attribute + if (res.getResSpec().isDummyResSpec()) { + item = true; + } + // Android does not allow values (false) for ids.xml anymore // https://issuetracker.google.com/issues/80475496 // But it decodes as a ResBoolean, which makes no sense. So force it to empty diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStringValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStringValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStringValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStringValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,14 +19,11 @@ import brut.androlib.AndrolibException; import brut.androlib.res.data.ResResource; import brut.androlib.res.xml.ResXmlEncoders; +import org.xmlpull.v1.XmlSerializer; + import java.io.IOException; import java.util.regex.Pattern; -import org.xmlpull.v1.XmlSerializer; - -/** - * @author Ryszard Wiśniewski - */ public class ResStringValue extends ResScalarValue { public ResStringValue(String value, int rawValue) { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResStyleValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,13 +21,11 @@ import brut.androlib.res.data.ResResource; import brut.androlib.res.xml.ResValuesXmlSerializable; import brut.util.Duo; -import java.io.IOException; import org.xmlpull.v1.XmlSerializer; + +import java.io.IOException; import java.util.logging.Logger; -/** - * @author Ryszard Wiśniewski - */ public class ResStyleValue extends ResBagValue implements ResValuesXmlSerializable { ResStyleValue(ResReferenceValue parent, @@ -36,8 +34,8 @@ mItems = new Duo[items.length]; for (int i = 0; i < items.length; i++) { - mItems[i] = new Duo( - factory.newReference(items[i].m1, null), items[i].m2); + mItems[i] = new Duo<>( + factory.newReference(items[i].m1, null), items[i].m2); } } @@ -51,16 +49,16 @@ } else if (res.getResSpec().getName().indexOf('.') != -1) { serializer.attribute(null, "parent", ""); } - for (int i = 0; i < mItems.length; i++) { - ResResSpec spec = mItems[i].m1.getReferent(); + for (Duo mItem : mItems) { + ResResSpec spec = mItem.m1.getReferent(); if (spec == null) { LOGGER.fine(String.format("null reference: m1=0x%08x(%s), m2=0x%08x(%s)", - mItems[i].m1.getRawIntValue(), mItems[i].m1.getType(), mItems[i].m2.getRawIntValue(), mItems[i].m2.getType())); + mItem.m1.getRawIntValue(), mItem.m1.getType(), mItem.m2.getRawIntValue(), mItem.m2.getType())); continue; } - String name = null; + String name; String value = null; ResValue resource = spec.getDefaultResource().getValue(); @@ -68,14 +66,14 @@ continue; } else if (resource instanceof ResAttr) { ResAttr attr = (ResAttr) resource; - value = attr.convertToResXmlFormat(mItems[i].m2); + value = attr.convertToResXmlFormat(mItem.m2); name = spec.getFullName(res.getResSpec().getPackage(), true); } else { name = "@" + spec.getFullName(res.getResSpec().getPackage(), false); } if (value == null) { - value = mItems[i].m2.encodeAsResXmlValue(); + value = mItem.m2.encodeAsResXmlValue(); } if (value == null) { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -22,9 +22,6 @@ import brut.androlib.res.data.ResTypeSpec; import brut.util.Duo; -/** - * @author Ryszard Wiśniewski - */ public class ResValueFactory { private final ResPackage mPackage; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValue.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValue.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValue.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValue.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,6 @@ */ package brut.androlib.res.data.value; -/** - * @author Ryszard Wiśniewski - */ public class ResValue { } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AndroidManifestResourceParser.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AndroidManifestResourceParser.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AndroidManifestResourceParser.java 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AndroidManifestResourceParser.java 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package brut.androlib.res.decoder; + +import android.util.TypedValue; + +import java.util.regex.Pattern; + +/** + * AXmlResourceParser specifically for parsing encoded AndroidManifest.xml. + */ +public class AndroidManifestResourceParser extends AXmlResourceParser { + + /** + * Pattern for matching numeric string meta-data values. aapt automatically infers the + * type for a manifest meta-data value based on the string in the unencoded XML. However, + * some apps intentionally coerce integers to be strings by prepending an escaped space. + * For details/discussion, see https://stackoverflow.com/questions/2154945/how-to-force-a-meta-data-value-to-type-string + * With aapt1, the escaped space is dropped when encoded. For aapt2, the escaped space is preserved. + */ + private static final Pattern PATTERN_NUMERIC_STRING = Pattern.compile("\\s?\\d+"); + + @Override + public String getAttributeValue(int index) { + String value = super.getAttributeValue(index); + + if (!isNumericStringMetadataAttributeValue(index, value)) { + return value; + } + + // Patch the numeric string value by prefixing it with an escaped space. + // Otherwise, when the decoded app is rebuilt, aapt will incorrectly encode + // the value as an int or float (depending on aapt version), breaking the original + // app functionality. + return "\\ " + super.getAttributeValue(index).trim(); + } + + private boolean isNumericStringMetadataAttributeValue(int index, String value) { + return "meta-data".equalsIgnoreCase(super.getName()) + && "value".equalsIgnoreCase(super.getAttributeName(index)) + && super.getAttributeValueType(index) == TypedValue.TYPE_STRING + && PATTERN_NUMERIC_STRING.matcher(value).matches(); + } +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,23 +17,25 @@ package brut.androlib.res.decoder; import android.util.TypedValue; -import brut.androlib.Androlib; import brut.androlib.AndrolibException; import brut.androlib.res.data.*; import brut.androlib.res.data.value.*; import brut.util.Duo; -import brut.androlib.res.data.ResTable; import brut.util.ExtDataInput; import com.google.common.io.LittleEndianDataInputStream; -import java.io.*; +import org.apache.commons.io.input.CountingInputStream; + +import java.io.DataInput; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; import java.math.BigInteger; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; import java.util.logging.Logger; -import org.apache.commons.io.input.CountingInputStream; -/** - * @author Ryszard Wiśniewski - */ public class ARSCDecoder { public static ARSCData decode(InputStream arscStream, boolean findFlagsOffsets, boolean keepBroken) throws AndrolibException { @@ -57,7 +59,7 @@ private ARSCDecoder(InputStream arscStream, ResTable resTable, boolean storeFlagsOffsets, boolean keepBroken) { arscStream = mCountIn = new CountingInputStream(arscStream); if (storeFlagsOffsets) { - mFlagsOffsets = new ArrayList(); + mFlagsOffsets = new ArrayList<>(); } else { mFlagsOffsets = null; } @@ -123,12 +125,19 @@ mPkg = new ResPackage(mResTable, id, name); nextChunk(); - while (mHeader.type == Header.TYPE_LIBRARY) { - readLibraryType(); - } - - while (mHeader.type == Header.TYPE_SPEC_TYPE) { - readTableTypeSpec(); + boolean flag = true; + while (flag) { + switch (mHeader.type) { + case Header.TYPE_LIBRARY: + readLibraryType(); + break; + case Header.TYPE_SPEC_TYPE: + readTableTypeSpec(); + break; + default: + flag = false; + break; + } } return mPkg; @@ -242,7 +251,7 @@ } mType = flags.isInvalid && !mKeepBroken ? null : mPkg.getOrCreateConfig(flags); - HashMap offsetsToEntryData = new HashMap(); + HashMap offsetsToEntryData = new HashMap<>(); for (int offset : entryOffsets) { if (offset == -1 || offsetsToEntryData.containsKey(offset)) { @@ -300,12 +309,12 @@ if (spec.isDummyResSpec()) { removeResSpec(spec); - spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), mPkg, mTypeSpec); + spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), entryData.mFlags, mPkg, mTypeSpec); mPkg.addResSpec(spec); mTypeSpec.addResSpec(spec); } } else { - spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), mPkg, mTypeSpec); + spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), entryData.mFlags, mPkg, mTypeSpec); mPkg.addResSpec(spec); mTypeSpec.addResSpec(spec); } @@ -318,12 +327,11 @@ if (mKeepBroken) { mType.addResource(res, true); spec.addResource(res, true); - LOGGER.warning(String.format("Duplicate Resource Detected. Ignoring duplicate: %s", res.toString())); + LOGGER.warning(String.format("Duplicate Resource Detected. Ignoring duplicate: %s", res)); } else { throw ex; } } - mPkg.addResource(res); } private ResBagValue readComplexEntry() throws IOException, AndrolibException { @@ -339,12 +347,10 @@ resId = mIn.readInt(); resValue = readValue(); - if (resValue instanceof ResScalarValue) { - items[i] = new Duo(resId, (ResScalarValue) resValue); - } else { + if (!(resValue instanceof ResScalarValue)) { resValue = new ResStringValue(resValue.toString(), resValue.getRawIntValue()); - items[i] = new Duo(resId, (ResScalarValue) resValue); } + items[i] = new Duo<>(resId, (ResScalarValue) resValue); } return factory.bagFactory(parent, items, mTypeSpec); @@ -464,7 +470,7 @@ colorMode, isInvalid, size); } - private char[] unpackLanguageOrRegion(byte in0, byte in1, char base) throws AndrolibException { + private char[] unpackLanguageOrRegion(byte in0, byte in1, char base) { // check high bit, if so we have a packed 3 letter code if (((in0 >> 7) & 1) == 1) { int first = in1 & 0x1F; @@ -478,7 +484,7 @@ return new char[] { (char) in0, (char) in1 }; } - private String readScriptOrVariantChar(int length) throws AndrolibException, IOException { + private String readScriptOrVariantChar(int length) throws IOException { StringBuilder string = new StringBuilder(16); while(length-- != 0) { @@ -505,7 +511,7 @@ continue; } - ResResSpec spec = new ResResSpec(new ResID(resId | i), "APKTOOL_DUMMY_" + Integer.toHexString(i), mPkg, mTypeSpec); + ResResSpec spec = new ResResSpec(new ResID(resId | i), "APKTOOL_DUMMY_" + Integer.toHexString(i), ENTRY_FLAG_PUBLIC, mPkg, mTypeSpec); // If we already have this resID dont add it again. if (! mPkg.hasResSpec(new ResID(resId | i))) { @@ -521,7 +527,6 @@ ResValue value = new ResReferenceValue(mPkg, 0, ""); ResResource res = new ResResource(mType, spec, value); - mPkg.addResource(res); mType.addResource(res); spec.addResource(res); } @@ -567,10 +572,10 @@ private int mResId; private int mTypeIdOffset = 0; private boolean[] mMissingResSpecs; - private HashMap mResTypeSpecs = new HashMap<>(); + private final HashMap mResTypeSpecs = new HashMap<>(); private final static short ENTRY_FLAG_COMPLEX = 0x0001; - private final static short ENTRY_FLAG_PUBLIC = 0x0002; + public final static short ENTRY_FLAG_PUBLIC = 0x0002; private final static short ENTRY_FLAG_WEAK = 0x0004; public static class Header { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -23,28 +23,24 @@ import brut.androlib.res.xml.ResXmlEncoders; import brut.util.ExtDataInput; import com.google.common.io.LittleEndianDataInputStream; +import org.xmlpull.v1.XmlPullParserException; import java.io.DataInput; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.logging.Level; import java.util.logging.Logger; -import org.xmlpull.v1.XmlPullParserException; /** - * @author Ryszard Wiśniewski - * @author Dmitry Skiba - * - * Binary xml files parser. + * Binary xml files parser. * - * Parser has only two states: (1) Operational state, which parser - * obtains after first successful call to next() and retains until - * open(), close(), or failed call to next(). (2) Closed state, which - * parser obtains after open(), close(), or failed call to next(). In - * this state methods return invalid values or throw exceptions. - * - * TODO: * check all methods in closed state + * Parser has only two states: (1) Operational state, which parser + * obtains after first successful call to next() and retains until + * open(), close(), or failed call to next(). (2) Closed state, which + * parser obtains after open(), close(), or failed call to next(). In + * this state methods return invalid values or throw exceptions. * + * TODO: * check all methods in closed state */ public class AXmlResourceParser implements XmlResourceParser { @@ -214,18 +210,18 @@ } @Override - public int getNamespaceCount(int depth) throws XmlPullParserException { + public int getNamespaceCount(int depth) { return m_namespaces.getAccumulatedCount(depth); } @Override - public String getNamespacePrefix(int pos) throws XmlPullParserException { + public String getNamespacePrefix(int pos) { int prefix = m_namespaces.getPrefix(pos); return m_strings.getString(prefix); } @Override - public String getNamespaceUri(int pos) throws XmlPullParserException { + public String getNamespaceUri(int pos) { int uri = m_namespaces.getUri(pos); return m_strings.getString(uri); } @@ -349,7 +345,7 @@ if (resourceId != 0) { value = mAttrDecoder.decodeManifestAttr(getAttributeNameResource(index)); } - } catch (AndrolibException | NullPointerException e) { } + } catch (AndrolibException | NullPointerException ignored) {} } return value; } @@ -521,8 +517,7 @@ // ///////////////////////////////// dummies @Override - public void setInput(InputStream stream, String inputEncoding) - throws XmlPullParserException { + public void setInput(InputStream stream, String inputEncoding) { open(stream); } @@ -542,12 +537,12 @@ } @Override - public boolean isEmptyElementTag() throws XmlPullParserException { + public boolean isEmptyElementTag() { return false; } @Override - public boolean isWhitespace() throws XmlPullParserException { + public boolean isWhitespace() { return false; } @@ -606,17 +601,12 @@ m_data = new int[32]; } - public final void reset() { + public void reset() { m_dataLength = 0; - m_count = 0; m_depth = 0; } - public final int getTotalCount() { - return m_count; - } - - public final int getCurrentCount() { + public int getCurrentCount() { if (m_dataLength == 0) { return 0; } @@ -624,7 +614,7 @@ return m_data[offset]; } - public final int getAccumulatedCount(int depth) { + public int getAccumulatedCount(int depth) { if (m_dataLength == 0 || depth < 0) { return 0; } @@ -641,7 +631,7 @@ return accumulatedCount; } - public final void push(int prefix, int uri) { + public void push(int prefix, int uri) { if (m_depth == 0) { increaseDepth(); } @@ -653,38 +643,9 @@ m_data[offset + 1] = uri; m_data[offset + 2] = count + 1; m_dataLength += 2; - m_count += 1; } - public final boolean pop(int prefix, int uri) { - if (m_dataLength == 0) { - return false; - } - int offset = m_dataLength - 1; - int count = m_data[offset]; - for (int i = 0, o = offset - 2; i != count; ++i, o -= 2) { - if (m_data[o] != prefix || m_data[o + 1] != uri) { - continue; - } - count -= 1; - if (i == 0) { - m_data[o] = count; - o -= (1 + count * 2); - m_data[o] = count; - } else { - m_data[offset] = count; - offset -= (1 + 2 + count * 2); - m_data[offset] = count; - System.arraycopy(m_data, o + 2, m_data, o, m_dataLength - o); - } - m_dataLength -= 2; - m_count -= 1; - return true; - } - return false; - } - - public final boolean pop() { + public boolean pop() { if (m_dataLength == 0) { return false; } @@ -699,31 +660,26 @@ offset -= (1 + count * 2); m_data[offset] = count; m_dataLength -= 2; - m_count -= 1; return true; } - public final int getPrefix(int index) { + public int getPrefix(int index) { return get(index, true); } - public final int getUri(int index) { + public int getUri(int index) { return get(index, false); } - public final int findPrefix(int uri) { + public int findPrefix(int uri) { return find(uri, false); } - public final int findUri(int prefix) { - return find(prefix, true); - } - - public final int getDepth() { + public int getDepth() { return m_depth; } - public final void increaseDepth() { + public void increaseDepth() { ensureDataCapacity(2); int offset = m_dataLength; m_data[offset] = 0; @@ -732,7 +688,7 @@ m_depth += 1; } - public final void decreaseDepth() { + public void decreaseDepth() { if (m_dataLength == 0) { return; } @@ -742,7 +698,6 @@ return; } m_dataLength -= 2 + count * 2; - m_count -= count; m_depth -= 1; } @@ -757,7 +712,7 @@ m_data = newData; } - private final int find(int prefixOrUri, boolean prefix) { + private int find(int prefixOrUri, boolean prefix) { if (m_dataLength == 0) { return -1; } @@ -781,7 +736,7 @@ return -1; } - private final int get(int index, boolean prefix) { + private int get(int index, boolean prefix) { if (m_dataLength == 0 || index < 0) { return -1; } @@ -804,15 +759,10 @@ private int[] m_data; private int m_dataLength; - private int m_count; private int m_depth; } - final StringBlock getStrings() { - return m_strings; - } - - private final int getAttributeOffset(int index) { + private int getAttributeOffset(int index) { if (m_event != START_TAG) { throw new IndexOutOfBoundsException("Current event is not START_TAG."); } @@ -823,7 +773,7 @@ return offset; } - private final int findAttribute(String namespace, String attribute) { + private int findAttribute(String namespace, String attribute) { if (m_strings == null || attribute == null) { return -1; } @@ -841,7 +791,7 @@ return -1; } - private final void resetEventInfo() { + private void resetEventInfo() { m_event = -1; m_lineNumber = -1; m_name = -1; @@ -852,7 +802,7 @@ m_styleAttribute = -1; } - private final void doNext() throws IOException { + private void doNext() throws IOException { // Delayed initialization. if (m_strings == null) { m_reader.skipCheckInt(CHUNK_AXML_FILE, CHUNK_AXML_FILE_BROKEN); @@ -988,7 +938,7 @@ private boolean m_operational = false; private StringBlock m_strings; private int[] m_resourceIDs; - private NamespaceStack m_namespaces = new NamespaceStack(); + private final NamespaceStack m_namespaces = new NamespaceStack(); private final String android_ns = "http://schemas.android.com/apk/res/android"; private boolean m_decreaseDepth; private int m_event; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,21 +19,21 @@ import brut.androlib.AndrolibException; import brut.androlib.err.CantFind9PatchChunkException; import brut.util.ExtDataInput; +import org.apache.commons.io.IOUtils; + +import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.awt.image.Raster; import java.awt.image.WritableRaster; -import java.io.*; -import javax.imageio.ImageIO; +import java.io.ByteArrayInputStream; +import java.io.DataInput; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; -import org.apache.commons.io.IOUtils; - -/** - * @author Ryszard Wiśniewski - */ public class Res9patchStreamDecoder implements ResStreamDecoder { @Override - public void decode(InputStream in, OutputStream out) - throws AndrolibException { + public void decode(InputStream in, OutputStream out) throws AndrolibException { try { byte[] data = IOUtils.toByteArray(in); @@ -114,9 +114,7 @@ } ImageIO.write(im2, "png", out); - } catch (IOException ex) { - throw new AndrolibException(ex); - } catch (NullPointerException ex) { + } catch (IOException | NullPointerException ex) { // In my case this was triggered because a .png file was // containing a html document instead of an image. // This could be more verbose and try to MIME ? @@ -125,21 +123,21 @@ } private NinePatch getNinePatch(byte[] data) throws AndrolibException, - IOException { + IOException { ExtDataInput di = new ExtDataInput(new ByteArrayInputStream(data)); find9patchChunk(di, NP_CHUNK_TYPE); return NinePatch.decode(di); } private OpticalInset getOpticalInset(byte[] data) throws AndrolibException, - IOException { + IOException { ExtDataInput di = new ExtDataInput(new ByteArrayInputStream(data)); find9patchChunk(di, OI_CHUNK_TYPE); return OpticalInset.decode(di); } private void find9patchChunk(DataInput di, int magic) throws AndrolibException, - IOException { + IOException { di.skipBytes(8); while (true) { int size; @@ -200,19 +198,18 @@ int[] xDivs = di.readIntArray(numXDivs); int[] yDivs = di.readIntArray(numYDivs); - return new NinePatch(padLeft, padRight, padTop, padBottom, xDivs, - yDivs); + return new NinePatch(padLeft, padRight, padTop, padBottom, xDivs, yDivs); } } private static class OpticalInset { - public final int layoutBoundsLeft, layoutBoundsTop, layoutBoundsRight, layoutBoundsBottom; + public final int layoutBoundsLeft, layoutBoundsTop, layoutBoundsRight, layoutBoundsBottom; public OpticalInset(int layoutBoundsLeft, int layoutBoundsTop, - int layoutBoundsRight, int layoutBoundsBottom) { - this.layoutBoundsLeft = layoutBoundsLeft; - this.layoutBoundsTop = layoutBoundsTop; - this.layoutBoundsRight = layoutBoundsRight; + int layoutBoundsRight, int layoutBoundsBottom) { + this.layoutBoundsLeft = layoutBoundsLeft; + this.layoutBoundsTop = layoutBoundsTop; + this.layoutBoundsRight = layoutBoundsRight; this.layoutBoundsBottom = layoutBoundsBottom; } @@ -222,7 +219,7 @@ int layoutBoundsRight = Integer.reverseBytes(di.readInt()); int layoutBoundsBottom = Integer.reverseBytes(di.readInt()); return new OpticalInset(layoutBoundsLeft, layoutBoundsTop, - layoutBoundsRight, layoutBoundsBottom); + layoutBoundsRight, layoutBoundsBottom); } } } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResAttrDecoder.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResAttrDecoder.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResAttrDecoder.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResAttrDecoder.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -23,9 +23,6 @@ import brut.androlib.res.data.value.ResAttr; import brut.androlib.res.data.value.ResScalarValue; -/** - * @author Ryszard Wiśniewski - */ public class ResAttrDecoder { public String decode(int type, int value, String rawValue, int attrResId) throws AndrolibException { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -30,9 +30,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -/** - * @author Ryszard Wiśniewski - */ public class ResFileDecoder { private final ResStreamDecoderContainer mDecoders; diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResRawStreamDecoder.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResRawStreamDecoder.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResRawStreamDecoder.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResRawStreamDecoder.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,14 +17,12 @@ package brut.androlib.res.decoder; import brut.androlib.AndrolibException; +import org.apache.commons.io.IOUtils; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import org.apache.commons.io.IOUtils; -/** - * @author Ryszard Wiśniewski - */ public class ResRawStreamDecoder implements ResStreamDecoder { @Override public void decode(InputStream in, OutputStream out) diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoderContainer.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoderContainer.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoderContainer.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoderContainer.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -22,11 +22,8 @@ import java.util.HashMap; import java.util.Map; -/** - * @author Ryszard Wiśniewski - */ public class ResStreamDecoderContainer { - private final Map mDecoders = new HashMap(); + private final Map mDecoders = new HashMap<>(); public void decode(InputStream in, OutputStream out, String decoderName) throws AndrolibException { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoder.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoder.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoder.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResStreamDecoder.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,10 +20,7 @@ import java.io.InputStream; import java.io.OutputStream; -/** - * @author Ryszard Wiśniewski - */ public interface ResStreamDecoder { - public void decode(InputStream in, OutputStream out) + void decode(InputStream in, OutputStream out) throws AndrolibException; } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,25 +18,33 @@ import brut.androlib.res.xml.ResXmlEncoders; import brut.util.ExtDataInput; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Splitter; +import com.google.common.base.Splitter.MapSplitter; +import com.google.common.collect.ComparisonChain; + import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.*; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; import java.util.logging.Logger; +import java.util.stream.Stream; + +import static com.google.common.collect.Ordering.explicit; +import static java.util.Comparator.naturalOrder; +import static java.util.Comparator.reverseOrder; -/** - * @author Ryszard Wiśniewski - * @author Dmitry Skiba - * - * Block of strings, used in binary xml and arsc. - * - * TODO: - implement get() - * - */ public class StringBlock { /** * Reads whole (including chunk type) string block from stream. Stream must * be at the chunk type. + * @param reader ExtDataInput + * @return StringBlock + * + * @throws IOException Parsing resources.arsc error */ public static StringBlock read(ExtDataInput reader) throws IOException { reader.skipCheckChunkTypeInt(CHUNK_STRINGPOOL_TYPE, CHUNK_NULL_TYPE); @@ -78,14 +86,9 @@ } /** - * Returns number of strings in block. - */ - public int getCount() { - return m_stringOffsets != null ? m_stringOffsets.length : 0; - } - - /** * Returns raw string (without any styling information) at specified index. + * @param index int + * @return String */ public String getString(int index) { if (index < 0 || m_stringOffsets == null || index >= m_stringOffsets.length) { @@ -106,17 +109,165 @@ return decodeString(offset, length); } + private static class Tag implements Comparable { + private static final MapSplitter ATTRIBUTES_SPLITTER = + Splitter.on(';').withKeyValueSeparator(Splitter.on('=').limit(2)); + + private final String tag; + private final Type type; + private final int position; + private final int matchingTagPosition; + + Tag(String tag, Type type, int position, int matchingTagPosition) { + this.tag = ResXmlEncoders.escapeXmlChars(tag); + this.type = type; + this.position = position; + this.matchingTagPosition = matchingTagPosition; + } + + /** + * compares this tag and another, returning the order that should be between them. + * order by: + * position + * closing tag has precedence over openning tag (unless it is the same tag) + * tags that are enclosed in others should appear later if openning tag, or first if closing tag + * lexicographical sort. openning tag and closing tag in reverse so that one tag will be contained in the other and not each contain the other partially + * @param o - the other tag object to compare to + * @return the order in between this object and the other + */ + @Override + public int compareTo(Tag o) { + return ComparisonChain.start() + .compare(position, o.position) + // When one tag closes where another starts, we always close before opening. + .compare(type, o.type, this.tag.equals(o.tag) ? explicit(Type.OPEN, Type.CLOSE) : explicit(Type.CLOSE, Type.OPEN)) + // Open first the tag which closes last, and close first the tag which opened last. + .compare(matchingTagPosition, o.matchingTagPosition, reverseOrder()) + // When two tags open and close together, we order alphabetically. When they close, + // we reversed the order. This ensures that the XML tags are properly nested. + .compare(tag, o.tag, type.equals(Type.OPEN) ? naturalOrder() : reverseOrder()) + .result(); + } + + /** + * formats the tag value and attributes according to whether the tag is an openning or closing tag + * @return the formatted tag value as a string + */ + @Override + public String toString() { + // "tag" can either be just the tag or have the form "tag;attr1=value1;attr2=value2;[...]". + int separatorIdx = tag.indexOf(';'); + String actualTag = separatorIdx == -1 ? tag : tag.substring(0, separatorIdx); + + switch (type) { + case OPEN: + if (separatorIdx != -1) { + StringJoiner attributes = new StringJoiner(" "); + ATTRIBUTES_SPLITTER + .split(tag.substring(separatorIdx + 1, tag.endsWith(";") ? tag.length() - 1: tag.length())) + .forEach((key, value) -> attributes.add(String.format("%s=\"%s\"", key, value))); + return String.format("<%s %s>", actualTag, attributes); + } + return String.format("<%s>", actualTag); + case CLOSE: + return String.format("", actualTag); + } + throw new IllegalStateException(); + } + + private enum Type { + OPEN, + CLOSE + } + } + + private static class Span { + private String tag; + private int firstChar, lastChar; + + Span(String val, int firstIndex, int lastIndex) { + this.tag = val; + this.firstChar = firstIndex; + this.lastChar = lastIndex; + } + + String getTag() { + return tag; + } + + int getFirstChar() { + return firstChar; + } + + int getLastChar() { + return lastChar; + } + } + + private static class StyledString { + String val; + int[] styles; + + StyledString(String raw, int[] stylesArr) { + this.val = raw; + this.styles = stylesArr; + } + + String getValue() { + return val; + } + + List getSpanList(StringBlock stringBlock) { + ArrayList spanList = new ArrayList<>(); + for (int i = 0; i != styles.length; i += 3) { + spanList.add(new Span(stringBlock.getString(styles[i]), styles[i + 1], styles[i + 2])); + } + return spanList; + } + } + /** - * Not yet implemented. * - * Returns string with style information (if any). + * @param styledString - the raw string with its corresponding styling tags and their locations + * @return a formatted styled string that contains the styling tag in the correct locations */ - public CharSequence get(int index) { - return getString(index); + String processStyledString(StyledString styledString) { + + ArrayList sortedTagsList = new ArrayList<>(); + + styledString.getSpanList(this).stream() + .flatMap( + span -> + Stream.of( + // "+ 1" because the last char is included. + new Tag( + span.getTag(), Tag.Type.OPEN, span.getFirstChar(), span.getLastChar() + 1), + // "+ 1" because the last char is included. + new Tag( + span.getTag(), + Tag.Type.CLOSE, + span.getLastChar() + 1, + span.getFirstChar()))) + // So we can edit the string in place, we need to start from the end. + .sorted(naturalOrder()) + .forEach(tag -> sortedTagsList.add(tag)); + + String raw = styledString.getValue(); + StringBuilder string = new StringBuilder(raw.length() + 32); + int lastIndex = 0; + for (Tag tag : sortedTagsList) { + string.append(ResXmlEncoders.escapeXmlChars(raw.substring(lastIndex, tag.position))); + string.append(tag); + lastIndex = tag.position; + } + string.append(ResXmlEncoders.escapeXmlChars(raw.substring(lastIndex))); + + return string.toString(); } /** - * Returns string with style tags (html-like). + * @param index Location (index) of string to process to HTML + * @return String Returns string with style tags (html-like). */ public String getHTML(int index) { String raw = getString(index); @@ -132,100 +283,16 @@ if (style[1] > raw.length()) { return ResXmlEncoders.escapeXmlChars(raw); } - StringBuilder html = new StringBuilder(raw.length() + 32); - int[] opened = new int[style.length / 3]; - boolean[] unclosed = new boolean[style.length / 3]; - int offset = 0, depth = 0; - while (true) { - int i = -1, j; - for (j = 0; j != style.length; j += 3) { - if (style[j + 1] == -1) { - continue; - } - if (i == -1 || style[i + 1] > style[j + 1]) { - i = j; - } - } - int start = ((i != -1) ? style[i + 1] : raw.length()); - for (j = depth - 1; j >= 0; j--) { - int last = opened[j]; - int end = style[last + 2]; - if (end >= start) { - if (style[last + 1] == -1 && end != -1) { - unclosed[j] = true; - } - break; - } - if (offset <= end) { - html.append(ResXmlEncoders.escapeXmlChars(raw.substring(offset, end + 1))); - offset = end + 1; - } - outputStyleTag(getString(style[last]), html, true); - } - depth = j + 1; - if (offset < start) { - html.append(ResXmlEncoders.escapeXmlChars(raw.substring(offset, start))); - if (j >= 0 && unclosed.length >= j && unclosed[j]) { - if (unclosed.length > (j + 1) && unclosed[j + 1] || unclosed.length == 1) { - outputStyleTag(getString(style[opened[j]]), html, true); - } - } - offset = start; - } - if (i == -1) { - break; - } - outputStyleTag(getString(style[i]), html, false); - style[i + 1] = -1; - opened[depth++] = i; - } - return html.toString(); - } - private void outputStyleTag(String tag, StringBuilder builder, boolean close) { - builder.append('<'); - if (close) { - builder.append('/'); - } - - int pos = tag.indexOf(';'); - if (pos == -1) { - builder.append(tag); - } else { - builder.append(tag.substring(0, pos)); - if (!close) { - boolean loop = true; - while (loop) { - int pos2 = tag.indexOf('=', pos + 1); - - // malformed style information will cause crash. so - // prematurely end style tags, if recreation - // cannot be created. - if (pos2 != -1) { - builder.append(' ').append(tag.substring(pos + 1, pos2)).append("=\""); - pos = tag.indexOf(';', pos2 + 1); - - String val; - if (pos != -1) { - val = tag.substring(pos2 + 1, pos); - } else { - loop = false; - val = tag.substring(pos2 + 1); - } - - builder.append(ResXmlEncoders.escapeXmlChars(val)).append('"'); - } else { - loop = false; - } - - } - } - } - builder.append('>'); + StyledString styledString = new StyledString(raw, style); + return processStyledString(styledString); } /** * Finds index of the string. Returns -1 if the string was not found. + * + * @param string String to index location of + * @return int (Returns -1 if not found) */ public int find(String string) { if (string == null) { @@ -254,6 +321,12 @@ private StringBlock() { } + @VisibleForTesting + StringBlock(byte[] strings, boolean isUTF8) { + m_strings = strings; + m_isUTF8 = isUTF8; + } + /** * Returns style information - array of int triplets, where in each triplet: * * first int is index of tag name ('b','i', etc.) * second int is tag @@ -288,42 +361,47 @@ return style; } - private String decodeString(int offset, int length) { + @VisibleForTesting + String decodeString(int offset, int length) { try { - return (m_isUTF8 ? UTF8_DECODER : UTF16LE_DECODER).decode( - ByteBuffer.wrap(m_strings, offset, length)).toString(); + final ByteBuffer wrappedBuffer = ByteBuffer.wrap(m_strings, offset, length); + return (m_isUTF8 ? UTF8_DECODER : UTF16LE_DECODER).decode(wrappedBuffer).toString(); } catch (CharacterCodingException ex) { + if (!m_isUTF8) { + LOGGER.warning("Failed to decode a string at offset " + offset + " of length " + length); + return null; + } + } + + try { + final ByteBuffer wrappedBufferRetry = ByteBuffer.wrap(m_strings, offset, length); + // in some places, Android uses 3-byte UTF-8 sequences instead of 4-bytes. + // If decoding failed, we try to use CESU-8 decoder, which is closer to what Android actually uses. + return CESU8_DECODER.decode(wrappedBufferRetry).toString(); + } catch (CharacterCodingException e) { + LOGGER.warning("Failed to decode a string with CESU-8 decoder."); return null; } } - private static final int getShort(byte[] array, int offset) { + private static int getShort(byte[] array, int offset) { return (array[offset + 1] & 0xff) << 8 | array[offset] & 0xff; } - private static final int getShort(int[] array, int offset) { - int value = array[offset / 4]; - if ((offset % 4) / 2 == 0) { - return (value & 0xFFFF); - } else { - return (value >>> 16); - } - } - - private static final int[] getUtf8(byte[] array, int offset) { + private static int[] getUtf8(byte[] array, int offset) { int val = array[offset]; int length; // We skip the utf16 length of the string if ((val & 0x80) != 0) { offset += 2; } else { - offset += 1; + offset += 1; } // And we read only the utf-8 encoded length of the string val = array[offset]; offset += 1; if ((val & 0x80) != 0) { - int low = (array[offset] & 0xFF); + int low = (array[offset] & 0xFF); length = ((val & 0x7F) << 8) + low; offset += 1; } else { @@ -331,8 +409,8 @@ } return new int[] { offset, length}; } - - private static final int[] getUtf16(byte[] array, int offset) { + + private static int[] getUtf16(byte[] array, int offset) { int val = ((array[offset + 1] & 0xFF) << 8 | array[offset] & 0xFF); if ((val & 0x8000) != 0) { @@ -340,7 +418,7 @@ int low = (array[offset + 2] & 0xFF); int len_value = ((val & 0x7FFF) << 16) + (high + low); return new int[] {4, len_value * 2}; - + } return new int[] {2, val * 2}; } @@ -351,8 +429,9 @@ private int[] m_styles; private boolean m_isUTF8; - private final CharsetDecoder UTF16LE_DECODER = Charset.forName("UTF-16LE").newDecoder(); - private final CharsetDecoder UTF8_DECODER = Charset.forName("UTF-8").newDecoder(); + private final CharsetDecoder UTF16LE_DECODER = StandardCharsets.UTF_16LE.newDecoder(); + private final CharsetDecoder UTF8_DECODER = StandardCharsets.UTF_8.newDecoder(); + private final CharsetDecoder CESU8_DECODER = Charset.forName("CESU8").newDecoder(); private static final Logger LOGGER = Logger.getLogger(StringBlock.class.getName()); // ResChunk_header = header.type (0x0001) + header.headerSize (0x001C) diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,12 +16,11 @@ */ package brut.androlib.res.decoder; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - +import brut.androlib.AndrolibException; import brut.androlib.err.AXmlDecodingException; import brut.androlib.err.RawXmlEncounteredException; +import brut.androlib.res.data.ResTable; +import brut.androlib.res.util.ExtXmlSerializer; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.wrapper.XmlPullParserWrapper; @@ -29,13 +28,10 @@ import org.xmlpull.v1.wrapper.XmlSerializerWrapper; import org.xmlpull.v1.wrapper.classic.StaticXmlSerializerWrapper; -import brut.androlib.AndrolibException; -import brut.androlib.res.data.ResTable; -import brut.androlib.res.util.ExtXmlSerializer; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; -/** - * @author Ryszard Wiśniewski - */ public class XmlPullStreamDecoder implements ResStreamDecoder { public XmlPullStreamDecoder(XmlPullParser parser, ExtXmlSerializer serializer) { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtFile.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtFile.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtFile.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtFile.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtMXSerializer.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtMXSerializer.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtMXSerializer.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtMXSerializer.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,12 +16,12 @@ */ package brut.androlib.res.util; -import java.io.*; import org.xmlpull.renamed.MXSerializer; -/** - * @author Ryszard Wiśniewski - */ +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + public class ExtMXSerializer extends MXSerializer implements ExtXmlSerializer { @Override public void startDocument(String encoding, Boolean standalone) diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtXmlSerializer.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtXmlSerializer.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtXmlSerializer.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/util/ExtXmlSerializer.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,19 +16,17 @@ */ package brut.androlib.res.util; -import java.io.IOException; import org.xmlpull.v1.XmlSerializer; -/** - * @author Ryszard Wiśniewski - */ +import java.io.IOException; + public interface ExtXmlSerializer extends XmlSerializer { - public ExtXmlSerializer newLine() throws IOException; + ExtXmlSerializer newLine() throws IOException; - public void setDisabledAttrEscape(boolean disabled); + void setDisabledAttrEscape(boolean disabled); - public static final String PROPERTY_SERIALIZER_INDENTATION = "http://xmlpull.org/v1/doc/properties.html#serializer-indentation"; - public static final String PROPERTY_SERIALIZER_LINE_SEPARATOR = "http://xmlpull.org/v1/doc/properties.html#serializer-line-separator"; - public static final String PROPERTY_DEFAULT_ENCODING = "DEFAULT_ENCODING"; + String PROPERTY_SERIALIZER_INDENTATION = "http://xmlpull.org/v1/doc/properties.html#serializer-indentation"; + String PROPERTY_SERIALIZER_LINE_SEPARATOR = "http://xmlpull.org/v1/doc/properties.html#serializer-line-separator"; + String PROPERTY_DEFAULT_ENCODING = "DEFAULT_ENCODING"; } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResValuesXmlSerializable.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResValuesXmlSerializable.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResValuesXmlSerializable.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResValuesXmlSerializable.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,13 +18,11 @@ import brut.androlib.AndrolibException; import brut.androlib.res.data.ResResource; -import java.io.IOException; import org.xmlpull.v1.XmlSerializer; -/** - * @author Ryszard Wiśniewski - */ +import java.io.IOException; + public interface ResValuesXmlSerializable { - public void serializeToResValuesXml(XmlSerializer serializer, - ResResource res) throws IOException, AndrolibException; + void serializeToResValuesXml(XmlSerializer serializer, + ResResource res) throws IOException, AndrolibException; } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncodable.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncodable.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncodable.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncodable.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,11 +18,8 @@ import brut.androlib.AndrolibException; -/** - * @author Ryszard Wiśniewski - */ public interface ResXmlEncodable { - public String encodeAsResXmlAttr() throws AndrolibException; + String encodeAsResXmlAttr() throws AndrolibException; - public String encodeAsResXmlValue() throws AndrolibException; + String encodeAsResXmlValue() throws AndrolibException; } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlEncoders.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,16 +17,12 @@ package brut.androlib.res.xml; import brut.util.Duo; +import org.apache.commons.lang3.StringUtils; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang3.StringUtils; - -/** - * @author Ryszard Wiśniewski - */ public final class ResXmlEncoders { public static String escapeXmlChars(String str) { @@ -106,15 +102,13 @@ wasSpace = false; switch (c) { case '\\': + case '"': out.append('\\'); break; case '\'': case '\n': enclose = true; break; - case '"': - out.append('\\'); - break; case '<': isInStyleTag = true; if (enclose) { @@ -158,7 +152,7 @@ int pos = 0; int count = 0; for (Integer sub : subs) { - out.append(str.substring(pos, ++sub)).append(++count).append('$'); + out.append(str, pos, ++sub).append(++count).append('$'); pos = sub; } out.append(str.substring(pos)); diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlPatcher.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlPatcher.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlPatcher.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlPatcher.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,10 +16,12 @@ */ package brut.androlib.res.xml; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.logging.Logger; +import brut.androlib.AndrolibException; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -29,27 +31,19 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - -import org.w3c.dom.*; -import org.xml.sax.SAXException; - -import brut.androlib.AndrolibException; +import javax.xml.xpath.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.logging.Logger; -/** - * @author Connor Tumbleson - */ public final class ResXmlPatcher { /** * Removes "debug" tag from file * * @param file AndroidManifest file - * @throws AndrolibException + * @throws AndrolibException Error reading Manifest file */ public static void removeApplicationDebugTag(File file) throws AndrolibException { if (file.exists()) { @@ -77,9 +71,8 @@ * Sets "debug" tag in the file to true * * @param file AndroidManifest file - * @throws AndrolibException */ - public static void setApplicationDebugTagTrue(File file) throws AndrolibException { + public static void setApplicationDebugTagTrue(File file) { if (file.exists()) { try { Document doc = loadDocument(file); @@ -105,18 +98,17 @@ } /** - * Any @string reference in a value in AndroidManifest.xml will break on + * Any @string reference in a provider value in AndroidManifest.xml will break on * build, thus preventing the application from installing. This is from a bug/error * in AOSP where public resources cannot be part of an authorities attribute within - * a tag. + * a provider tag. * * This finds any reference and replaces it with the literal value found in the * res/values/strings.xml file. * * @param file File for AndroidManifest.xml - * @throws AndrolibException */ - public static void fixingPublicAttrsInProviderAttributes(File file) throws AndrolibException { + public static void fixingPublicAttrsInProviderAttributes(File file) { boolean saved = false; if (file.exists()) { try { @@ -177,9 +169,8 @@ * @param saved boolean on whether we need to save * @param provider Node we are attempting to replace * @return boolean - * @throws AndrolibException setting node value failed */ - private static boolean isSaved(File file, boolean saved, Node provider) throws AndrolibException { + private static boolean isSaved(File file, boolean saved, Node provider) { String reference = provider.getNodeValue(); String replacement = pullValueFromStrings(file.getParentFile(), reference); @@ -196,9 +187,8 @@ * @param directory Root directory of apk * @param key String reference (ie @string/foo) * @return String|null - * @throws AndrolibException */ - public static String pullValueFromStrings(File directory, String key) throws AndrolibException { + public static String pullValueFromStrings(File directory, String key) { if (key == null || ! key.contains("@")) { return null; } @@ -231,9 +221,8 @@ * @param directory Root directory of apk * @param key Integer reference (ie @integer/foo) * @return String|null - * @throws AndrolibException */ - public static String pullValueFromIntegers(File directory, String key) throws AndrolibException { + public static String pullValueFromIntegers(File directory, String key) { if (key == null || ! key.contains("@")) { return null; } @@ -264,9 +253,8 @@ * Removes attributes like "versionCode" and "versionName" from file. * * @param file File representing AndroidManifest.xml - * @throws AndrolibException */ - public static void removeManifestVersions(File file) throws AndrolibException { + public static void removeManifestVersions(File file) { if (file.exists()) { try { Document doc = loadDocument(file); @@ -293,9 +281,8 @@ * * @param file File for AndroidManifest.xml * @param packageOriginal Package name to replace - * @throws AndrolibException */ - public static void renameManifestPackage(File file, String packageOriginal) throws AndrolibException { + public static void renameManifestPackage(File file, String packageOriginal) { try { Document doc = loadDocument(file); @@ -337,11 +324,8 @@ DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); // Not using the parse(File) method on purpose, so that we can control when // to close it. Somehow parse(File) does not seem to close the file in all cases. - FileInputStream inputStream = new FileInputStream(file); - try { - return docBuilder.parse(inputStream); - } finally { - inputStream.close(); + try (FileInputStream inputStream = new FileInputStream(file)) { + return docBuilder.parse(inputStream); } } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,28 +18,25 @@ import brut.androlib.AndrolibException; import brut.androlib.mod.SmaliMod; -import brut.directory.ExtFile; import brut.directory.DirectoryException; -import java.io.*; -import java.util.logging.Logger; - +import brut.directory.ExtFile; import org.antlr.runtime.RecognitionException; import org.jf.dexlib2.Opcodes; import org.jf.dexlib2.writer.builder.DexBuilder; import org.jf.dexlib2.writer.io.FileDataStore; -/** - * @author Ryszard Wiśniewski - */ +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Logger; + public class SmaliBuilder { + public static void build(ExtFile smaliDir, File dexFile, int apiLevel) throws AndrolibException { new SmaliBuilder(smaliDir, dexFile, apiLevel).build(); } - public static void build(ExtFile smaliDir, File dexFile) throws AndrolibException { - new SmaliBuilder(smaliDir, dexFile, 0).build(); - } - private SmaliBuilder(ExtFile smaliDir, File dexFile, int apiLevel) { mSmaliDir = smaliDir; mDexFile = dexFile; @@ -85,7 +82,7 @@ private final ExtFile mSmaliDir; private final File mDexFile; - private int mApiLevel = 0; + private final int mApiLevel; private final static Logger LOGGER = Logger.getLogger(SmaliBuilder.class.getName()); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliDecoder.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliDecoder.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliDecoder.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliDecoder.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -24,30 +24,28 @@ import org.jf.dexlib2.dexbacked.DexBackedDexFile; import org.jf.dexlib2.dexbacked.DexBackedOdexFile; import org.jf.dexlib2.analysis.InlineMethodResolver; +import org.jf.dexlib2.iface.DexFile; import org.jf.dexlib2.iface.MultiDexContainer; import java.io.File; import java.io.IOException; -/** - * @author Ryszard Wiśniewski - */ public class SmaliDecoder { - public static void decode(File apkFile, File outDir, String dexName, boolean bakdeb, int api) + public static DexFile decode(File apkFile, File outDir, String dexName, boolean bakDeb, int apiLevel) throws AndrolibException { - new SmaliDecoder(apkFile, outDir, dexName, bakdeb, api).decode(); + return new SmaliDecoder(apkFile, outDir, dexName, bakDeb, apiLevel).decode(); } - private SmaliDecoder(File apkFile, File outDir, String dexName, boolean bakdeb, int api) { + private SmaliDecoder(File apkFile, File outDir, String dexName, boolean bakDeb, int apiLevel) { mApkFile = apkFile; - mOutDir = outDir; + mOutDir = outDir; mDexFile = dexName; - mBakDeb = bakdeb; - mApi = api; + mBakDeb = bakDeb; + mApiLevel = apiLevel; } - private void decode() throws AndrolibException { + private DexFile decode() throws AndrolibException { try { final BaksmaliOptions options = new BaksmaliOptions(); @@ -70,7 +68,8 @@ } // create the container - MultiDexContainer container = DexFileFactory.loadDexContainer(mApkFile, Opcodes.forApi(mApi)); + MultiDexContainer container = + DexFileFactory.loadDexContainer(mApkFile, mApiLevel > 0 ? Opcodes.forApi(mApiLevel) : null); MultiDexContainer.DexEntry dexEntry; DexBackedDexFile dexFile; @@ -99,6 +98,8 @@ } Baksmali.disassembleDexFile(dexFile, mOutDir, jobs, options); + + return dexFile; } catch (IOException ex) { throw new AndrolibException(ex); } @@ -108,5 +109,5 @@ private final File mOutDir; private final String mDexFile; private final boolean mBakDeb; - private final int mApi; + private final int mApiLevel; } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/org/xmlpull/renamed/MXSerializer.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/org/xmlpull/renamed/MXSerializer.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/main/java/org/xmlpull/renamed/MXSerializer.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/main/java/org/xmlpull/renamed/MXSerializer.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,13 +16,13 @@ */ package org.xmlpull.renamed; +import org.xmlpull.v1.XmlSerializer; + import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; -import org.xmlpull.v1.XmlSerializer; - /** * Implementation of XmlSerializer interface from XmlPull V1 API. This * implementation is optimized for performance and low memory footprint. @@ -69,15 +69,15 @@ protected int depth = 0; // element stack - protected String elNamespace[] = new String[2]; - protected String elName[] = new String[elNamespace.length]; - protected String elPrefix[] = new String[elNamespace.length]; - protected int elNamespaceCount[] = new int[elNamespace.length]; + protected String[] elNamespace = new String[2]; + protected String[] elName = new String[elNamespace.length]; + protected String[] elPrefix = new String[elNamespace.length]; + protected int[] elNamespaceCount = new int[elNamespace.length]; // namespace stack protected int namespaceEnd = 0; - protected String namespacePrefix[] = new String[8]; - protected String namespaceUri[] = new String[namespacePrefix.length]; + protected String[] namespacePrefix = new String[8]; + protected String[] namespaceUri = new String[namespacePrefix.length]; protected boolean finished; protected boolean pastRoot; @@ -92,9 +92,9 @@ // buffer output if needed to write escaped String see text(String) private static final int BUF_LEN = Runtime.getRuntime().freeMemory() > 1000000L ? 8 * 1024 : 256; - protected char buf[] = new char[BUF_LEN]; + protected char[] buf = new char[BUF_LEN]; - protected static final String precomputedPrefixes[]; + protected static final String[] precomputedPrefixes; static { precomputedPrefixes = new String[32]; // arbitrary number ... @@ -103,7 +103,7 @@ } } - private boolean checkNamesInterned = false; + private final boolean checkNamesInterned = false; private void checkInterning(String name) { if (namesInterned && name != name.intern()) { @@ -157,7 +157,7 @@ + elStackSize + " ==> " + newSize); } final boolean needsCopying = elStackSize > 0; - String[] arr = null; + String[] arr; // reuse arr local variable slot arr = new String[newSize]; if (needsCopying) @@ -242,7 +242,7 @@ * requested chnages. */ protected void rebuildIndentationBuf() { - if (doIndent == false) + if (!doIndent) return; final int maxIndent = 65; // hardcoded maximum indentation size in characters int bufSize = 0; @@ -277,7 +277,7 @@ protected void writeIndent() throws IOException { final int start = writeLineSepartor ? 0 : offsetNewLine; - final int level = (depth > maxIndentLevel) ? maxIndentLevel : depth; + final int level = Math.min(depth, maxIndentLevel); out.write(indentationBuf, start, ((level - 1) * indentationJump) + offsetNewLine); } @@ -288,15 +288,19 @@ if (name == null) { throw new IllegalArgumentException("property name can not be null"); } - if (PROPERTY_SERIALIZER_INDENTATION.equals(name)) { - indentationString = (String) value; - } else if (PROPERTY_SERIALIZER_LINE_SEPARATOR.equals(name)) { - lineSeparator = (String) value; - } else if (PROPERTY_LOCATION.equals(name)) { - location = (String) value; - } else { - throw new IllegalStateException("unsupported property " + name); - } + switch (name) { + case PROPERTY_SERIALIZER_INDENTATION: + indentationString = (String) value; + break; + case PROPERTY_SERIALIZER_LINE_SEPARATOR: + lineSeparator = (String) value; + break; + case PROPERTY_LOCATION: + location = (String) value; + break; + default: + throw new IllegalStateException("unsupported property " + name); + } writeLineSepartor = lineSeparator != null && lineSeparator.length() > 0; writeIndentation = indentationString != null && indentationString.length() > 0; @@ -314,15 +318,16 @@ if (name == null) { throw new IllegalArgumentException("property name can not be null"); } - if (PROPERTY_SERIALIZER_INDENTATION.equals(name)) { - return indentationString; - } else if (PROPERTY_SERIALIZER_LINE_SEPARATOR.equals(name)) { - return lineSeparator; - } else if (PROPERTY_LOCATION.equals(name)) { - return location; - } else { - return null; - } + switch (name) { + case PROPERTY_SERIALIZER_INDENTATION: + return indentationString; + case PROPERTY_SERIALIZER_LINE_SEPARATOR: + return lineSeparator; + case PROPERTY_LOCATION: + return location; + default: + return null; + } } private String getLocation() { @@ -370,7 +375,7 @@ if (standalone != null) { out.write(" standalone="); out.write(attributeUseApostrophe ? '\'' : '"'); - if (standalone.booleanValue()) { + if (standalone) { out.write("yes"); } else { out.write("no"); @@ -406,14 +411,6 @@ throw new IllegalArgumentException("prefix must be not null" + getLocation()); } - // check that prefix is not duplicated ... - for (int i = elNamespaceCount[depth]; i < namespaceEnd; i++) { - if (prefix == namespacePrefix[i]) { - // Toss out extra namespaces at same depth to fix #1456 - return; - } - } - if (!namesInterned) { namespace = namespace.intern(); } else if (checkNamesInterned) { @@ -456,15 +453,12 @@ // first check if namespace is already in scope for (int i = namespaceEnd - 1; i >= 0; --i) { - if (namespace == namespaceUri[i]) { + if (namespace.equals(namespaceUri[i])) { final String prefix = namespacePrefix[i]; - if (nonEmpty && prefix.length() == 0) - continue; - // now check that prefix is still in scope - for (int p = namespaceEnd - 1; p > i; --p) { - if (prefix == namespacePrefix[p]) - continue; // too bad - prefix is redeclared with different namespace - } + if (nonEmpty && prefix.length() == 0) { + continue; + } + return prefix; } } @@ -477,30 +471,21 @@ } private String generatePrefix(String namespace) { - while (true) { - ++autoDeclaredPrefixes; - // fast lookup uses table that was pre-initialized in static{} .... - final String prefix = autoDeclaredPrefixes < precomputedPrefixes.length - ? precomputedPrefixes[autoDeclaredPrefixes] - : ("n" + autoDeclaredPrefixes).intern(); - - // make sure this prefix is not declared in any scope (avoid hiding in-scope prefixes)! - for (int i = namespaceEnd - 1; i >= 0; --i) { - if (prefix == namespacePrefix[i]) { - continue; // prefix is already declared - generate new and try again - } - } - // declare prefix + ++autoDeclaredPrefixes; + // fast lookup uses table that was pre-initialized in static{} .... + final String prefix = autoDeclaredPrefixes < precomputedPrefixes.length + ? precomputedPrefixes[autoDeclaredPrefixes] + : ("n" + autoDeclaredPrefixes).intern(); + + // declare prefix + if (namespaceEnd >= namespacePrefix.length) { + ensureNamespacesCapacity(); + } + namespacePrefix[namespaceEnd] = prefix; + namespaceUri[namespaceEnd] = namespace; + ++namespaceEnd; - if (namespaceEnd >= namespacePrefix.length) { - ensureNamespacesCapacity(); - } - namespacePrefix[namespaceEnd] = prefix; - namespaceUri[namespaceEnd] = namespace; - ++namespaceEnd; - - return prefix; - } + return prefix; } @Override @@ -713,8 +698,7 @@ if (startTagIncomplete) { writeNamespaceDeclarations(); out.write(" />"); // space is added to make it easier to work in XHTML!!! - --depth; - } else { + } else { if (doIndent && seenTag) { writeIndent(); } @@ -726,9 +710,9 @@ } out.write(name); out.write('>'); - --depth; - } - namespaceEnd = elNamespaceCount[depth]; + } + --depth; + namespaceEnd = elNamespaceCount[depth]; startTagIncomplete = false; seenTag = true; return this; @@ -1009,8 +993,7 @@ } } - /** simple utility method -- good for debugging */ - protected static final String printable(String s) { + protected static String printable(String s) { if (s == null) { return "null"; } @@ -1023,7 +1006,7 @@ return retval.toString(); } - protected static final String printable(char ch) { + protected static String printable(char ch) { StringBuffer retval = new StringBuffer(); addPrintable(retval, ch); return retval.toString(); @@ -1050,7 +1033,7 @@ retval.append("\\\""); break; case '\'': - retval.append("\\\'"); + retval.append("\\'"); break; case '\\': retval.append("\\\\"); @@ -1058,7 +1041,7 @@ default: if (ch < 0x20 || ch > 0x7e) { final String ss = "0000" + Integer.toString(ch, 16); - retval.append("\\u" + ss.substring(ss.length() - 4)); + retval.append("\\u").append(ss.substring(ss.length() - 4)); } else { retval.append(ch); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/AndroidOreoNotSparseTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/AndroidOreoNotSparseTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/AndroidOreoNotSparseTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/AndroidOreoNotSparseTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,6 +17,7 @@ package brut.androlib.aapt1; import brut.androlib.*; +import brut.androlib.options.BuildOptions; import brut.directory.ExtFile; import brut.common.BrutException; import brut.util.OS; @@ -28,9 +29,6 @@ import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class AndroidOreoNotSparseTest extends BaseTest { @BeforeClass public static void beforeClass() throws Exception { @@ -49,8 +47,8 @@ apkDecoder.decode(); LOGGER.info("Building not_sparse.apk..."); - ApkOptions apkOptions = new ApkOptions(); - new Androlib(apkOptions).build(sTestNewDir, testApk); + BuildOptions buildOptions = new BuildOptions(); + new Androlib(buildOptions).build(sTestNewDir, testApk); } @AfterClass @@ -63,4 +61,4 @@ assertTrue(sTestNewDir.isDirectory()); assertTrue(sTestOrigDir.isDirectory()); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/AndroidOreoSparseTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/AndroidOreoSparseTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/AndroidOreoSparseTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/AndroidOreoSparseTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,6 +17,7 @@ package brut.androlib.aapt1; import brut.androlib.*; +import brut.androlib.options.BuildOptions; import brut.directory.ExtFile; import brut.common.BrutException; import brut.util.OS; @@ -28,9 +29,6 @@ import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class AndroidOreoSparseTest extends BaseTest { @BeforeClass public static void beforeClass() throws Exception { @@ -49,8 +47,8 @@ apkDecoder.decode(); LOGGER.info("Building sparse.apk..."); - ApkOptions apkOptions = new ApkOptions(); - new Androlib(apkOptions).build(sTestNewDir, testApk); + BuildOptions buildOptions = new BuildOptions(); + new Androlib(buildOptions).build(sTestNewDir, testApk); } @AfterClass @@ -68,4 +66,4 @@ public void ensureStringsOreoTest() { assertTrue((new File(sTestNewDir, "res/values-v26/strings.xml").isFile())); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/BuildAndDecodeJarTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/BuildAndDecodeJarTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/BuildAndDecodeJarTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/BuildAndDecodeJarTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -31,9 +31,6 @@ import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class BuildAndDecodeJarTest extends BaseTest { @BeforeClass @@ -64,4 +61,4 @@ public void buildAndDecodeTest() { assertTrue(sTestNewDir.isDirectory()); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/BuildAndDecodeTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/BuildAndDecodeTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/BuildAndDecodeTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/BuildAndDecodeTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,25 +21,23 @@ import brut.androlib.BaseTest; import brut.androlib.TestUtils; import brut.androlib.meta.MetaInfo; -import brut.directory.ExtFile; import brut.common.BrutException; +import brut.directory.ExtFile; import brut.util.OS; +import brut.util.OSDetection; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import javax.imageio.ImageIO; import java.awt.image.BufferedImage; -import java.io.*; +import java.io.File; +import java.io.IOException; import java.util.Map; -import brut.util.OSDetection; -import org.junit.*; - import static org.junit.Assert.*; -import static org.junit.Assume.*; - -import javax.imageio.ImageIO; +import static org.junit.Assume.assumeTrue; -/** - * @author Ryszard Wiśniewski - */ public class BuildAndDecodeTest extends BaseTest { @BeforeClass @@ -178,7 +176,7 @@ public void storedMp3FilesAreNotCompressedTest() throws BrutException { ExtFile extFile = new ExtFile(sTmpDir, "testapp.apk"); Integer built = extFile.getDirectory().getCompressionLevel("res/raw/rain.mp3"); - assertEquals(new Integer(0), built); + assertEquals(Integer.valueOf(0), built); } @Test @@ -497,7 +495,7 @@ MetaInfo metaInfo = new Androlib().readMetaFile(sTestNewDir); for (String item : metaInfo.doNotCompress) { - assertFalse(item.equals("jpg")); + assertNotEquals("jpg", item); } } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/DebugTagRetainedTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/DebugTagRetainedTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/DebugTagRetainedTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/DebugTagRetainedTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,6 +17,7 @@ package brut.androlib.aapt1; import brut.androlib.*; +import brut.androlib.options.BuildOptions; import brut.directory.ExtFile; import brut.common.BrutException; import brut.util.OS; @@ -34,9 +35,6 @@ import static org.junit.Assert.assertTrue; import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; -/** - * @author Connor Tumbleson - */ public class DebugTagRetainedTest extends BaseTest { @BeforeClass @@ -49,11 +47,11 @@ TestUtils.copyResourceDir(DebugTagRetainedTest.class, "aapt1/issue1235/", sTestOrigDir); LOGGER.info("Building issue1235.apk..."); - ApkOptions apkOptions = new ApkOptions(); - apkOptions.debugMode = true; + BuildOptions buildOptions = new BuildOptions(); + buildOptions.debugMode = true; File testApk = new File(sTmpDir, "issue1235.apk"); - new Androlib(apkOptions).build(sTestOrigDir, testApk); + new Androlib(buildOptions).build(sTestOrigDir, testApk); LOGGER.info("Decoding issue1235.apk..."); ApkDecoder apkDecoder = new ApkDecoder(testApk); @@ -89,4 +87,4 @@ assertXMLEqual(expected, obtained); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/DefaultBaksmaliVariableTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/DefaultBaksmaliVariableTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/DefaultBaksmaliVariableTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/DefaultBaksmaliVariableTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/EmptyResourcesArscTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/EmptyResourcesArscTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/EmptyResourcesArscTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/EmptyResourcesArscTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,7 +18,7 @@ import brut.androlib.Androlib; import brut.androlib.ApkDecoder; -import brut.androlib.ApkOptions; +import brut.androlib.options.BuildOptions; import brut.androlib.TestUtils; import brut.directory.ExtFile; import brut.common.BrutException; @@ -32,9 +32,6 @@ import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class EmptyResourcesArscTest { @BeforeClass public static void beforeClass() throws Exception { @@ -53,8 +50,8 @@ apkDecoder.decode(); LOGGER.info("Building issue1730.apk..."); - ApkOptions apkOptions = new ApkOptions(); - new Androlib(apkOptions).build(sTestNewDir, testApk); + BuildOptions buildOptions = new BuildOptions(); + new Androlib(buildOptions).build(sTestNewDir, testApk); } @AfterClass @@ -73,4 +70,4 @@ private static ExtFile sTestNewDir; private final static Logger LOGGER = Logger.getLogger(EmptyResourcesArscTest.class.getName()); -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/LargeIntsInManifestTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/LargeIntsInManifestTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/LargeIntsInManifestTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/LargeIntsInManifestTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/ProviderAttributeTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/ProviderAttributeTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/ProviderAttributeTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/ProviderAttributeTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -93,4 +93,4 @@ private boolean fileExists(String filepath) { return Files.exists(Paths.get(sTmpDir.getAbsolutePath() + File.separator + filepath)); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/ReferenceVersionCodeTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/ReferenceVersionCodeTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/ReferenceVersionCodeTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/ReferenceVersionCodeTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -33,9 +33,6 @@ import static org.junit.Assert.assertEquals; -/** - * @author Connor Tumbleson - */ public class ReferenceVersionCodeTest extends BaseTest { @BeforeClass @@ -63,4 +60,4 @@ MetaInfo metaInfo = new Androlib().readMetaFile(decodedApk); assertEquals("v1.0.0", metaInfo.versionInfo.versionName); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/SharedLibraryTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/SharedLibraryTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/SharedLibraryTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/SharedLibraryTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,6 +17,7 @@ package brut.androlib.aapt1; import brut.androlib.*; +import brut.androlib.options.BuildOptions; import brut.directory.ExtFile; import brut.common.BrutException; import brut.util.OS; @@ -49,11 +50,11 @@ public void isFrameworkTaggingWorking() throws AndrolibException { String apkName = "library.apk"; - ApkOptions apkOptions = new ApkOptions(); - apkOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); - apkOptions.frameworkTag = "building"; + BuildOptions buildOptions = new BuildOptions(); + buildOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); + buildOptions.frameworkTag = "building"; - new Androlib(apkOptions).installFramework(new File(sTmpDir + File.separator + apkName)); + new Androlib(buildOptions).installFramework(new File(sTmpDir + File.separator + apkName)); assertTrue(fileExists("2-building.apk")); } @@ -62,10 +63,10 @@ public void isFrameworkInstallingWorking() throws AndrolibException { String apkName = "library.apk"; - ApkOptions apkOptions = new ApkOptions(); - apkOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); + BuildOptions buildOptions = new BuildOptions(); + buildOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); - new Androlib(apkOptions).installFramework(new File(sTmpDir + File.separator + apkName)); + new Androlib(buildOptions).installFramework(new File(sTmpDir + File.separator + apkName)); assertTrue(fileExists("2.apk")); } @@ -76,36 +77,36 @@ String client = "client.apk"; // setup apkOptions - ApkOptions apkOptions = new ApkOptions(); - apkOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); - apkOptions.frameworkTag = "shared"; + BuildOptions buildOptions = new BuildOptions(); + buildOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); + buildOptions.frameworkTag = "shared"; // install library/framework - new Androlib(apkOptions).installFramework(new File(sTmpDir + File.separator + library)); + new Androlib(buildOptions).installFramework(new File(sTmpDir + File.separator + library)); assertTrue(fileExists("2-shared.apk")); // decode client.apk ApkDecoder apkDecoder = new ApkDecoder(new File(sTmpDir + File.separator + client)); apkDecoder.setOutDir(new File(sTmpDir + File.separator + client + ".out")); - apkDecoder.setFrameworkDir(apkOptions.frameworkFolderLocation); - apkDecoder.setFrameworkTag(apkOptions.frameworkTag); + apkDecoder.setFrameworkDir(buildOptions.frameworkFolderLocation); + apkDecoder.setFrameworkTag(buildOptions.frameworkTag); apkDecoder.decode(); // decode library.apk ApkDecoder libraryDecoder = new ApkDecoder(new File(sTmpDir + File.separator + library)); libraryDecoder.setOutDir(new File(sTmpDir + File.separator + library + ".out")); - libraryDecoder.setFrameworkDir(apkOptions.frameworkFolderLocation); - libraryDecoder.setFrameworkTag(apkOptions.frameworkTag); + libraryDecoder.setFrameworkDir(buildOptions.frameworkFolderLocation); + libraryDecoder.setFrameworkTag(buildOptions.frameworkTag); libraryDecoder.decode(); // build client.apk ExtFile clientApk = new ExtFile(sTmpDir, client + ".out"); - new Androlib(apkOptions).build(clientApk, null); + new Androlib(buildOptions).build(clientApk, null); assertTrue(fileExists(client + ".out" + File.separator + "dist" + File.separator + client)); // build library.apk (shared library) ExtFile libraryApk = new ExtFile(sTmpDir, library + ".out"); - new Androlib(apkOptions).build(libraryApk, null); + new Androlib(buildOptions).build(libraryApk, null); assertTrue(fileExists(library + ".out" + File.separator + "dist" + File.separator + library)); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/SkipAssetTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/SkipAssetTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/SkipAssetTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/SkipAssetTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -87,4 +87,4 @@ assertTrue(f.isFile()); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/UnknownCompressionTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/UnknownCompressionTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/UnknownCompressionTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt1/UnknownCompressionTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,6 +17,7 @@ package brut.androlib.aapt1; import brut.androlib.*; +import brut.androlib.options.BuildOptions; import brut.directory.ExtFile; import brut.common.BrutException; import brut.util.OS; @@ -30,9 +31,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; -/** - * @author Connor Tumbleson - */ public class UnknownCompressionTest extends BaseTest { @BeforeClass @@ -42,8 +40,8 @@ TestUtils.copyResourceDir(UnknownCompressionTest.class, "aapt1/unknown_compression/", sTmpDir); String apk = "deflated_unknowns.apk"; - ApkOptions apkOptions = new ApkOptions(); - apkOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); + BuildOptions buildOptions = new BuildOptions(); + buildOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); sTestOrigDir = new ExtFile(sTmpDir, apk); @@ -54,7 +52,7 @@ // build deflated_unknowns ExtFile clientApkFolder = new ExtFile(sTestOrigDir.getAbsolutePath() + ".out"); - new Androlib(apkOptions).build(clientApkFolder, null); + new Androlib(buildOptions).build(clientApkFolder, null); sTestNewDir = new ExtFile(clientApkFolder, "dist" + File.separator + apk); } @@ -82,7 +80,7 @@ // Check that control = rebuilt (both stored) // Add extra check for checking = 0 to enforce check for stored just in case control breaks assertEquals(control, rebuilt); - assertEquals(new Integer(0), rebuilt); + assertEquals(Integer.valueOf(0), rebuilt); } @Test @@ -91,7 +89,7 @@ Integer rebuilt = sTestNewDir.getDirectory().getCompressionLevel("test.json"); assertEquals(control, rebuilt); - assertEquals(new Integer(8), rebuilt); + assertEquals(Integer.valueOf(8), rebuilt); } @Test @@ -100,6 +98,6 @@ Integer rebuilt = sTestNewDir.getDirectory().getCompressionLevel("950x150.png"); assertEquals(control, rebuilt); - assertEquals(new Integer(8), rebuilt); + assertEquals(Integer.valueOf(8), rebuilt); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/BuildAndDecodeTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/BuildAndDecodeTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/BuildAndDecodeTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/BuildAndDecodeTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,6 +18,7 @@ import brut.androlib.*; import brut.androlib.meta.MetaInfo; +import brut.androlib.options.BuildOptions; import brut.common.BrutException; import brut.directory.ExtFile; import brut.util.OS; @@ -30,9 +31,6 @@ import static org.junit.Assert.*; -/** - * @author Ryszard Wiśniewski - */ public class BuildAndDecodeTest extends BaseTest { @BeforeClass @@ -45,13 +43,13 @@ LOGGER.info("Unpacking testapp..."); TestUtils.copyResourceDir(BuildAndDecodeTest.class, "aapt2/testapp/", sTestOrigDir); - ApkOptions apkOptions = new ApkOptions(); - apkOptions.useAapt2 = true; - apkOptions.verbose = true; + BuildOptions buildOptions = new BuildOptions(); + buildOptions.useAapt2 = true; + buildOptions.verbose = true; LOGGER.info("Building testapp.apk..."); File testApk = new File(sTmpDir, "testapp.apk"); - new Androlib(apkOptions).build(sTestOrigDir, testApk); + new Androlib(buildOptions).build(sTestOrigDir, testApk); LOGGER.info("Decoding testapp.apk..."); ApkDecoder apkDecoder = new ApkDecoder(testApk); @@ -75,6 +73,16 @@ } @Test + public void valuesColorsTest() throws BrutException { + compareValuesFiles("values/colors.xml"); + } + + @Test + public void valuesBoolsTest() throws BrutException { + compareValuesFiles("values/bools.xml"); + } + + @Test public void valuesMaxLengthTest() throws BrutException { compareValuesFiles("values-es/strings.xml"); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableFalseChangeToTrueTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableFalseChangeToTrueTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableFalseChangeToTrueTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableFalseChangeToTrueTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -1,12 +1,12 @@ -/** - * Copyright (C) 2019 Ryszard Wiśniewski - * Copyright (C) 2019 Connor Tumbleson +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,25 +17,24 @@ package brut.androlib.aapt2; import brut.androlib.*; +import brut.androlib.options.BuildOptions; import brut.common.BrutException; import brut.directory.ExtFile; import brut.util.OS; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import org.custommonkey.xmlunit.XMLUnit; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.xml.sax.SAXException; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class DebuggableFalseChangeToTrueTest extends BaseTest { @BeforeClass @@ -48,13 +47,13 @@ TestUtils.copyResourceDir(DebuggableFalseChangeToTrueTest.class, "aapt2/issue2328/debuggable-false", sTestOrigDir); LOGGER.info("Building issue2328-debuggable-flase.apk..."); - ApkOptions apkOptions = new ApkOptions(); - apkOptions.debugMode = true; - apkOptions.useAapt2 = true; - apkOptions.verbose = true; + BuildOptions buildOptions = new BuildOptions(); + buildOptions.debugMode = true; + buildOptions.useAapt2 = true; + buildOptions.verbose = true; File testApk = new File(sTmpDir, "issue2328-debuggable-flase.apk"); - new Androlib(apkOptions).build(sTestOrigDir, testApk); + new Androlib(buildOptions).build(sTestOrigDir, testApk); LOGGER.info("Decoding issue2328-debuggable-flase.apk..."); ApkDecoder apkDecoder = new ApkDecoder(testApk); @@ -90,4 +89,4 @@ assertXMLEqual(expected, obtained); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableTrueAddedTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableTrueAddedTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableTrueAddedTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableTrueAddedTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -1,12 +1,12 @@ -/** - * Copyright (C) 2019 Ryszard Wiśniewski - * Copyright (C) 2019 Connor Tumbleson +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,25 +17,24 @@ package brut.androlib.aapt2; import brut.androlib.*; +import brut.androlib.options.BuildOptions; import brut.common.BrutException; import brut.directory.ExtFile; import brut.util.OS; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import org.custommonkey.xmlunit.XMLUnit; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.xml.sax.SAXException; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class DebuggableTrueAddedTest extends BaseTest { @BeforeClass @@ -48,13 +47,13 @@ TestUtils.copyResourceDir(DebuggableTrueAddedTest.class, "aapt2/issue2328/debuggable-missing", sTestOrigDir); LOGGER.info("Building issue2328-debuggable-missing.apk..."); - ApkOptions apkOptions = new ApkOptions(); - apkOptions.debugMode = true; - apkOptions.useAapt2 = true; - apkOptions.verbose = true; + BuildOptions buildOptions = new BuildOptions(); + buildOptions.debugMode = true; + buildOptions.useAapt2 = true; + buildOptions.verbose = true; File testApk = new File(sTmpDir, "issue2328-debuggable-missing.apk"); - new Androlib(apkOptions).build(sTestOrigDir, testApk); + new Androlib(buildOptions).build(sTestOrigDir, testApk); LOGGER.info("Decoding issue2328-debuggable-missing.apk..."); ApkDecoder apkDecoder = new ApkDecoder(testApk); @@ -90,4 +89,4 @@ assertXMLEqual(expected, obtained); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableTrueRetainedTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableTrueRetainedTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableTrueRetainedTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/DebuggableTrueRetainedTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -1,12 +1,12 @@ -/** - * Copyright (C) 2019 Ryszard Wiśniewski - * Copyright (C) 2019 Connor Tumbleson +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,25 +17,24 @@ package brut.androlib.aapt2; import brut.androlib.*; +import brut.androlib.options.BuildOptions; import brut.common.BrutException; import brut.directory.ExtFile; import brut.util.OS; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import org.custommonkey.xmlunit.XMLUnit; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.xml.sax.SAXException; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class DebuggableTrueRetainedTest extends BaseTest { @BeforeClass @@ -48,13 +47,13 @@ TestUtils.copyResourceDir(DebuggableTrueRetainedTest.class, "aapt2/issue2328/debuggable-true", sTestOrigDir); LOGGER.info("Building issue2328-debuggable-true.apk..."); - ApkOptions apkOptions = new ApkOptions(); - apkOptions.debugMode = true; - apkOptions.useAapt2 = true; - apkOptions.verbose = true; + BuildOptions buildOptions = new BuildOptions(); + buildOptions.debugMode = true; + buildOptions.useAapt2 = true; + buildOptions.verbose = true; File testApk = new File(sTmpDir, "issue2328-debuggable-true.apk"); - new Androlib(apkOptions).build(sTestOrigDir, testApk); + new Androlib(buildOptions).build(sTestOrigDir, testApk); LOGGER.info("Decoding issue2328-debuggable-true.apk..."); ApkDecoder apkDecoder = new ApkDecoder(testApk); @@ -90,4 +89,4 @@ assertXMLEqual(expected, obtained); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/NonStandardPkgIdTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/NonStandardPkgIdTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/NonStandardPkgIdTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/NonStandardPkgIdTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,6 +17,7 @@ package brut.androlib.aapt2; import brut.androlib.*; +import brut.androlib.options.BuildOptions; import brut.androlib.res.data.ResTable; import brut.common.BrutException; import brut.directory.ExtFile; @@ -43,13 +44,13 @@ LOGGER.info("Unpacking pkgid8..."); TestUtils.copyResourceDir(BuildAndDecodeTest.class, "aapt2/pkgid8/", sTestOrigDir); - ApkOptions apkOptions = new ApkOptions(); - apkOptions.useAapt2 = true; - apkOptions.verbose = true; + BuildOptions buildOptions = new BuildOptions(); + buildOptions.useAapt2 = true; + buildOptions.verbose = true; LOGGER.info("Building pkgid8.apk..."); File testApk = new File(sTmpDir, "pkgid8.apk"); - new Androlib(apkOptions).build(sTestOrigDir, testApk); + new Androlib(buildOptions).build(sTestOrigDir, testApk); LOGGER.info("Decoding pkgid8.apk..."); ApkDecoder apkDecoder = new ApkDecoder(testApk); diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/androlib/InvalidSdkBoundingTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/androlib/InvalidSdkBoundingTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/androlib/InvalidSdkBoundingTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/androlib/InvalidSdkBoundingTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,11 +18,9 @@ import brut.androlib.BaseTest; import brut.androlib.res.AndrolibResources; +import org.junit.Test; import java.util.LinkedHashMap; import java.util.Map; - -import org.junit.*; - import static org.junit.Assert.assertEquals; public class InvalidSdkBoundingTest extends BaseTest { @@ -75,6 +73,16 @@ assertEquals("25", androlibResources.checkTargetSdkVersionBounds()); } + @Test + public void checkForShortHandSTag() { + AndrolibResources androlibResources = new AndrolibResources(); + + Map sdkInfo = new LinkedHashMap<>(); + sdkInfo.put("targetSdkVersion", "S"); + + androlibResources.setSdkInfo(sdkInfo); + assertEquals("31", androlibResources.checkTargetSdkVersionBounds()); + } @Test public void checkForShortHandSdkTag() { @@ -92,9 +100,9 @@ AndrolibResources androlibResources = new AndrolibResources(); Map sdkInfo = new LinkedHashMap<>(); - sdkInfo.put("targetSdkVersion", "S"); + sdkInfo.put("targetSdkVersion", "T"); androlibResources.setSdkInfo(sdkInfo); assertEquals("10000", androlibResources.checkTargetSdkVersionBounds()); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/BaseTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/BaseTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/BaseTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/BaseTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -31,9 +31,8 @@ import java.util.Set; import java.util.logging.Logger; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import static org.junit.Assert.*; public class BaseTest { @@ -45,16 +44,16 @@ Map controlFiles = control.unknownFiles; Map testFiles = test.unknownFiles; - assertTrue(controlFiles.size() == testFiles.size()); + assertEquals(controlFiles.size(), testFiles.size()); // Make sure that the compression methods are still the same for (Map.Entry controlEntry : controlFiles.entrySet()) { - assertTrue(controlEntry.getValue().equals(testFiles.get(controlEntry.getKey()))); + assertEquals(controlEntry.getValue(), testFiles.get(controlEntry.getKey())); } } protected void compareBinaryFolder(String path, boolean res) throws BrutException, IOException { - Boolean exists = true; + boolean exists = true; String prefixPath = ""; if (res) { diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/AndResGuardTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/AndResGuardTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/AndResGuardTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/AndResGuardTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -56,4 +56,4 @@ File aPng = new File(sTestOrigDir,"res/mipmap-hdpi-v4/a.png"); assertTrue(aPng.isFile()); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeKotlinCoroutinesTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeKotlinCoroutinesTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeKotlinCoroutinesTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeKotlinCoroutinesTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,6 +16,11 @@ */ package brut.androlib.decode; +import brut.androlib.*; +import brut.common.BrutException; +import brut.directory.DirectoryException; +import brut.directory.ExtFile; +import brut.util.OS; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -25,23 +30,10 @@ import java.nio.file.Files; import java.nio.file.Paths; -import brut.androlib.Androlib; -import brut.androlib.AndrolibException; -import brut.androlib.ApkDecoder; -import brut.androlib.BaseTest; -import brut.androlib.TestUtils; -import brut.common.BrutException; -import brut.directory.DirectoryException; -import brut.directory.ExtFile; -import brut.util.OS; - import static org.junit.Assert.assertTrue; -/** - * @author Adib Faramarzi - */ public class DecodeKotlinCoroutinesTest extends BaseTest { - private static String apk = "test-kotlin-coroutines.apk"; + private static final String apk = "test-kotlin-coroutines.apk"; @BeforeClass public static void beforeClass() throws Exception { @@ -103,4 +95,4 @@ private boolean fileExists(String filepath) { return Files.exists(Paths.get(sTmpDir.getAbsolutePath() + File.separator + filepath)); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeKotlinTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeKotlinTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeKotlinTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeKotlinTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -32,9 +32,6 @@ import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class DecodeKotlinTest extends BaseTest { @BeforeClass @@ -72,4 +69,4 @@ assertTrue(FileUtils.readFileToString(kotlinActivity).contains("KotlinActivity.kt")); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DoubleExtensionUnknownFileTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DoubleExtensionUnknownFileTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DoubleExtensionUnknownFileTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DoubleExtensionUnknownFileTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -34,9 +34,6 @@ import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class DoubleExtensionUnknownFileTest extends BaseTest { @BeforeClass @@ -68,4 +65,4 @@ } } } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DuplicateDexTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DuplicateDexTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DuplicateDexTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DuplicateDexTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,6 +17,7 @@ package brut.androlib.decode; import brut.androlib.*; +import brut.androlib.options.BuildOptions; import brut.common.BrutException; import brut.directory.ExtFile; import brut.util.OS; @@ -53,8 +54,8 @@ apkDecoder.decode(); LOGGER.info("Building duplicatedex.apk..."); - ApkOptions apkOptions = new ApkOptions(); - new Androlib(apkOptions).build(sTestNewDir, testApk); + BuildOptions buildOptions = new BuildOptions(); + new Androlib(buildOptions).build(sTestNewDir, testApk); } @Test @@ -68,8 +69,8 @@ apkDecoder.decode(); LOGGER.info("Building duplicatedex.apk..."); - ApkOptions apkOptions = new ApkOptions(); - new Androlib(apkOptions).build(sTestNewDir, testApk); + BuildOptions buildOptions = new BuildOptions(); + new Androlib(buildOptions).build(sTestNewDir, testApk); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/Empty9PatchTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/Empty9PatchTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/Empty9PatchTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/Empty9PatchTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ import java.io.File; import java.io.IOException; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class Empty9PatchTest extends BaseTest { @@ -58,6 +59,6 @@ File aPng = new File(sTestOrigDir,"res/drawable-xhdpi/empty.9.png"); assertTrue(aPng.isFile()); - assertTrue(aPng.length() == 0); + assertEquals(0, aPng.length()); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ExternalEntityTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ExternalEntityTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ExternalEntityTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ExternalEntityTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -34,9 +34,6 @@ import static org.junit.Assert.assertEquals; -/** - * @author Connor Tumbleson - */ public class ExternalEntityTest extends BaseTest { @BeforeClass @@ -72,4 +69,4 @@ String obtained = TestUtils.replaceNewlines(new String(encoded)); assertEquals(expected, obtained); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ForceManifestDecodeNoResourcesTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ForceManifestDecodeNoResourcesTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ForceManifestDecodeNoResourcesTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ForceManifestDecodeNoResourcesTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -30,12 +30,11 @@ import java.io.IOException; import java.util.Arrays; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; public class ForceManifestDecodeNoResourcesTest extends BaseTest { - private byte[] xmlHeader = new byte[] { + private final byte[] xmlHeader = new byte[] { 0x3C, // < 0x3F, // ? 0x78, // x @@ -68,7 +67,7 @@ // lets probe filetype of manifest, we should detect XML File manifestFile = new File(output + File.separator + "AndroidManifest.xml"); byte[] magic = TestUtils.readHeaderOfFile(manifestFile, 6); - assertTrue(Arrays.equals(this.xmlHeader, magic)); + assertArrayEquals(this.xmlHeader, magic); // confirm resources.arsc still exists, as its raw File resourcesArsc = new File(output + File.separator + "resources.arsc"); @@ -87,7 +86,7 @@ // lets probe filetype of manifest, we should detect XML File manifestFile = new File(output + File.separator + "AndroidManifest.xml"); byte[] magic = TestUtils.readHeaderOfFile(manifestFile, 6); - assertTrue(Arrays.equals(this.xmlHeader, magic)); + assertArrayEquals(this.xmlHeader, magic); // confirm resources.arsc does not exist File resourcesArsc = new File(output + File.separator + "resources.arsc"); @@ -106,7 +105,7 @@ // lets probe filetype of manifest, we should detect XML File manifestFile = new File(output + File.separator + "AndroidManifest.xml"); byte[] magic = TestUtils.readHeaderOfFile(manifestFile, 6); - assertTrue(Arrays.equals(this.xmlHeader, magic)); + assertArrayEquals(this.xmlHeader, magic); // confirm resources.arsc does not exist File resourcesArsc = new File(output + File.separator + "resources.arsc"); @@ -142,4 +141,4 @@ apkDecoder.setOutDir(new File(output)); apkDecoder.decode(); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MinifiedArscTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MinifiedArscTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MinifiedArscTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MinifiedArscTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -33,9 +33,6 @@ import static org.junit.Assert.assertEquals; -/** - * @author Connor Tumbleson - */ public class MinifiedArscTest extends BaseTest { @BeforeClass @@ -73,4 +70,4 @@ String obtained = TestUtils.replaceNewlines(new String(encoded)); assertEquals(expected, obtained); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MissingDiv9PatchTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MissingDiv9PatchTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MissingDiv9PatchTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MissingDiv9PatchTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MissingVersionManifestTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MissingVersionManifestTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MissingVersionManifestTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MissingVersionManifestTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,8 +21,8 @@ import brut.androlib.BaseTest; import brut.androlib.TestUtils; import brut.androlib.meta.MetaInfo; -import brut.directory.ExtFile; import brut.common.BrutException; +import brut.directory.ExtFile; import brut.util.OS; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -31,11 +31,8 @@ import java.io.File; import java.io.IOException; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; -/** - * @author Connor Tumbleson - */ public class MissingVersionManifestTest extends BaseTest { @BeforeClass @@ -61,6 +58,6 @@ apkDecoder.decode(); MetaInfo metaInfo = new Androlib().readMetaFile(decodedApk); - assertEquals(null, metaInfo.versionInfo.versionName); + assertNull(metaInfo.versionInfo.versionName); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/OutsideOfDirectoryEntryTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/OutsideOfDirectoryEntryTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/OutsideOfDirectoryEntryTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/OutsideOfDirectoryEntryTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -31,9 +31,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class OutsideOfDirectoryEntryTest extends BaseTest { @BeforeClass @@ -64,4 +61,4 @@ File testAssetFolder = new File(sTestNewDir, "assets"); assertFalse(testAssetFolder.isDirectory()); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ParentDirectoryTraversalTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ParentDirectoryTraversalTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ParentDirectoryTraversalTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/ParentDirectoryTraversalTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/VectorDrawableTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/VectorDrawableTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/VectorDrawableTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/VectorDrawableTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/encoders/PositionalEnumerationTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/encoders/PositionalEnumerationTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/encoders/PositionalEnumerationTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/encoders/PositionalEnumerationTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -22,9 +22,6 @@ import static org.junit.Assert.assertEquals; -/** - * @author Connor Tumbleson - */ public class PositionalEnumerationTest extends BaseTest { @Test @@ -65,4 +62,4 @@ private String enumerateArguments(String value) { return ResXmlEncoders.enumerateNonPositionalSubstitutionsIfRequired(value); } -} \ No newline at end of file +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/res/decoder/StringBlockWithSurrogatePairInUtf8Test.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/res/decoder/StringBlockWithSurrogatePairInUtf8Test.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/res/decoder/StringBlockWithSurrogatePairInUtf8Test.java 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/res/decoder/StringBlockWithSurrogatePairInUtf8Test.java 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package brut.androlib.res.decoder; + +import org.junit.Test; + +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertEquals; + +public class StringBlockWithSurrogatePairInUtf8Test { + @Test + public void decodeSingleOctet() { + final String actual = new StringBlock("abcDEF123".getBytes(StandardCharsets.UTF_8), true).decodeString(0, 9); + assertEquals("Incorrect decoding", "abcDEF123", actual); + } + + @Test + public void decodeTwoOctets() { + final String actual0 = new StringBlock(new byte[] { (byte) 0xC2, (byte) 0x80}, true).decodeString(0, 2); + assertEquals("Incorrect decoding", "\u0080", actual0); + + final String actual1 = new StringBlock(new byte[] { (byte) 0xDF, (byte) 0xBF}, true).decodeString(0, 2); + assertEquals("Incorrect decoding", "\u07FF", actual1); + } + + @Test + public void decodeThreeOctets() { + final String actual0 = new StringBlock(new byte[] { (byte) 0xE0, (byte) 0xA0, (byte) 0x80}, true).decodeString(0, 3); + assertEquals("Incorrect decoding", "\u0800", actual0); + + final String actual1 = new StringBlock(new byte[] { (byte) 0xEF, (byte) 0xBF, (byte) 0xBF}, true).decodeString(0, 3); + assertEquals("Incorrect decoding", "\uFFFF", actual1); + } + + @Test + public void decodeSurrogatePair_when_givesAsThreeOctetsFromInvalidRangeOfUtf8() { + // See: https://github.com/iBotPeaches/Apktool/issues/2299 + final String actual = new StringBlock(new byte[] { (byte) 0xED, (byte) 0xA0, (byte) 0xBD, (byte) 0xED, (byte) 0xB4, (byte) 0x86}, true).decodeString(0, 6); + assertEquals("Incorrect decoding", "\uD83D\uDD06", actual); + + // See: https://github.com/iBotPeaches/Apktool/issues/2546 + final byte[] bytesWithCharactersBeforeSurrogatePair = {'G', 'o', 'o', 'd', ' ', 'm', 'o', 'r', 'n', 'i', 'n', 'g', '!', ' ', + (byte) 0xED, (byte) 0xA0, (byte) 0xBD, (byte) 0xED, (byte) 0xB1, (byte) 0x8B, + ' ', 'S', 'u', 'n', ' ', + (byte) 0xED, (byte) 0xA0, (byte) 0xBC, (byte) 0xED, (byte) 0xBC, (byte) 0x9E + }; + final String actual2 = new StringBlock(bytesWithCharactersBeforeSurrogatePair, true).decodeString(0, 31); + + // D83D -> 0xED 0xA0 0xBD + // DC4B -> 0xED 0xB1 0x8B + // D83C -> 0xED 0xA0 0xBC + // DF1E -> 0xED 0xBC 0x9E + assertEquals("Incorrect decoding when there are valid characters before the surrogate pair", + "Good morning! \uD83D\uDC4B Sun \uD83C\uDF1E", actual2); + } + + @Test + public void decodeSurrogatePair_when_givesAsThreeOctetsFromTheValidRangeOfUtf8() { + // \u10FFFF is encoded in UTF-8 as "0xDBFF 0xDFFF" (4-byte encoding), + // but when used in Android resources which are encoded in UTF-8, 3-byte encoding is used, + // so each of these is encoded as 3-bytes + final String actual = new StringBlock(new byte[] { (byte) 0xED, (byte) 0xAF, (byte) 0xBF, (byte) 0xED, (byte) 0xBF, (byte) 0xBF}, true).decodeString(0, 6); + assertEquals("Incorrect decoding", "\uDBFF\uDFFF", actual); + } +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/res/src/DexStaticFieldValueTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/res/src/DexStaticFieldValueTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/res/src/DexStaticFieldValueTest.java 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/res/src/DexStaticFieldValueTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package brut.androlib.res.src; + +import brut.androlib.*; +import brut.androlib.aapt2.BuildAndDecodeTest; +import brut.androlib.options.BuildOptions; +import brut.common.BrutException; +import brut.directory.ExtFile; +import brut.util.OS; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; + +public class DexStaticFieldValueTest extends BaseTest { + + @BeforeClass + public static void beforeClass() throws Exception { + TestUtils.cleanFrameworkFile(); + + sTmpDir = new ExtFile(OS.createTempDirectory()); + sTestOrigDir = new ExtFile(sTmpDir, "issue2543-orig"); + sTestNewDir = new ExtFile(sTmpDir, "issue2543-new"); + LOGGER.info("Unpacking issue2543..."); + TestUtils.copyResourceDir(BuildAndDecodeTest.class, "decode/issue2543/", sTestOrigDir); + + BuildOptions buildOptions = new BuildOptions(); + + LOGGER.info("Building issue2543.apk..."); + File testApk = new File(sTmpDir, "issue2543.apk"); + new Androlib(buildOptions).build(sTestOrigDir, testApk); + + LOGGER.info("Decoding issue2543.apk..."); + ApkDecoder apkDecoder = new ApkDecoder(testApk); + apkDecoder.setOutDir(sTestNewDir); + apkDecoder.setBaksmaliDebugMode(false); + apkDecoder.decode(); + } + + @AfterClass + public static void afterClass() throws BrutException { + OS.rmdir(sTmpDir); + } + + @Test + public void disassembleDexFileToKeepDefaultParameters() throws IOException { + String expected = TestUtils.replaceNewlines( + ".class public LHelloWorld;\n" + + ".super Ljava/lang/Object;\n" + + "\n" + + "\n" + + "# static fields\n" + + ".field private static b:Z = false\n" + + "\n" + + ".field private static c:Z = true\n" + + "\n" + + "\n" + + "# direct methods\n" + + ".method public static main([Ljava/lang/String;)V\n" + + " .locals 1\n" + + "\n" + + " return-void\n" + + ".end method"); + + byte[] encoded = Files.readAllBytes(Paths.get(sTestNewDir + File.separator + "smali" + File.separator + + "HelloWorld.smali")); + + String obtained = TestUtils.replaceNewlines(new String(encoded)); + assertEquals(expected, obtained); + } +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/TestUtils.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/TestUtils.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/TestUtils.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/TestUtils.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,19 @@ */ package brut.androlib; +import brut.androlib.options.BuildOptions; import brut.androlib.res.AndrolibResources; import brut.common.BrutException; -import brut.directory.*; +import brut.directory.DirUtil; +import brut.directory.Directory; +import brut.directory.FileDirectory; +import brut.util.OS; +import org.custommonkey.xmlunit.ElementQualifier; +import org.w3c.dom.Element; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + import java.io.*; import java.net.URL; import java.net.URLDecoder; @@ -26,14 +36,6 @@ import java.util.HashMap; import java.util.Map; -import brut.util.OS; -import org.custommonkey.xmlunit.ElementQualifier; -import org.w3c.dom.Element; -import org.xmlpull.v1.*; - -/** - * @author Ryszard Wiśniewski - */ public abstract class TestUtils { public static Map parseStringsXml(File file) @@ -44,7 +46,7 @@ int eventType; String key = null; - Map map = new HashMap(); + Map map = new HashMap<>(); while ((eventType = xpp.next()) != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_TAG: @@ -77,14 +79,14 @@ } } - public static void copyResourceDir(Class class_, String dirPath, File out) throws BrutException { + public static void copyResourceDir(Class class_, String dirPath, File out) throws BrutException { if (!out.exists()) { out.mkdirs(); } copyResourceDir(class_, dirPath, new FileDirectory(out)); } - public static void copyResourceDir(Class class_, String dirPath, Directory out) throws BrutException { + public static void copyResourceDir(Class class_, String dirPath, Directory out) throws BrutException { if (class_ == null) { class_ = Class.class; } @@ -136,7 +138,7 @@ static File getFrameworkDir() throws AndrolibException { AndrolibResources androlibResources = new AndrolibResources(); - androlibResources.apkOptions = new ApkOptions(); + androlibResources.buildOptions = new BuildOptions(); return androlibResources.getFrameworkDir(); } diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/util/AaptVersionTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/util/AaptVersionTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/util/AaptVersionTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/util/AaptVersionTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/util/UnknownDirectoryTraversalTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/util/UnknownDirectoryTraversalTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/util/UnknownDirectoryTraversalTest.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/util/UnknownDirectoryTraversalTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -26,6 +26,7 @@ import brut.util.BrutIO; import brut.util.OS; import brut.util.OSDetection; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -35,9 +36,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -/** - * @author Connor Tumbleson - */ public class UnknownDirectoryTraversalTest extends BaseTest { @BeforeClass @@ -46,6 +44,11 @@ TestUtils.copyResourceDir(UnknownDirectoryTraversalTest.class, "util/traversal", sTmpDir); } + @AfterClass + public static void afterClass() throws BrutException { + OS.rmdir(sTmpDir); + } + @Test public void validFileTest() throws IOException, BrutException { String validFilename = BrutIO.sanitizeUnknownFile(sTmpDir, "file"); diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/MaliciousYamlTest.java apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/MaliciousYamlTest.java --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/MaliciousYamlTest.java 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/MaliciousYamlTest.java 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package brut.androlib.yaml; + +import brut.androlib.Androlib; +import brut.androlib.BaseTest; +import brut.androlib.TestUtils; +import brut.androlib.options.BuildOptions; +import brut.common.BrutException; +import brut.directory.ExtFile; +import brut.util.OS; +import org.junit.BeforeClass; +import org.junit.Test; +import org.yaml.snakeyaml.constructor.ConstructorException; + +import java.io.File; + +public class MaliciousYamlTest extends BaseTest { + + @BeforeClass + public static void beforeClass() throws Exception { + TestUtils.cleanFrameworkFile(); + + sTmpDir = new ExtFile(OS.createTempDirectory()); + sTestNewDir = new ExtFile(sTmpDir, "cve20220476"); + LOGGER.info("Unpacking cve20220476..."); + TestUtils.copyResourceDir(MaliciousYamlTest.class, "yaml/cve20220476/", sTestNewDir); + } + + @Test(expected = ConstructorException.class) + public void testMaliciousYamlNotLoaded() throws BrutException { + BuildOptions buildOptions = new BuildOptions(); + File testApk = new File(sTmpDir, "cve20220476.apk"); + new Androlib(buildOptions).build(sTestNewDir, testApk); + } +} diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt1/testapp/AndroidManifest.xml apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt1/testapp/AndroidManifest.xml --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt1/testapp/AndroidManifest.xml 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt1/testapp/AndroidManifest.xml 2022-04-11 21:08:20.000000000 +0000 @@ -2,4 +2,8 @@ + + + + diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt1/testapp/res/values-mcc001/strings.xml apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt1/testapp/res/values-mcc001/strings.xml --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt1/testapp/res/values-mcc001/strings.xml 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt1/testapp/res/values-mcc001/strings.xml 2022-04-11 21:08:20.000000000 +0000 @@ -41,4 +41,6 @@ [Ţåþ ţö ţýþé þåššŵöŕð one two three] []Ţåþ ţö ţýþé þåššŵöŕð one two three [Ţåþ ţö ţýþé þåššŵöŕð one two three] + 🔆 +
  • aaaaa aa aaaaa – aaaaaaa aaaaaaaaaa aa aaaaaaaa aaaaaa aaaaa (aaaa) aaaa aaaaaaaaa aaaaa aa aaaaaaaaa aaaaaaa aaaa
  • aaaaaaaaa aaaaaaaaaaaaaaa aaaaaaaa – aaaaaaa aaaaaaaaaa aaaaaaaaa aaaa aaaaaa aa aaaa aaaa aaaa aaaa aaaaaaa aaaaaaaaaaaaa, aaaaaa aaa aaaaaaaaaa (aaa) aaaaaaaaaaaaaaa
  • aaaaaaaaaaa aaaaaa aaaaaaaaaa – aaaaaaaaaa aaaa aaaaaa aa a aaa aa aaaaaa aaa aaaaaaa (aaaaa aaaaaaaa) aaaaaaaa aa aaaaaa aaaaa aaa aaaa
diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/AndroidManifest.xml apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/AndroidManifest.xml --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/AndroidManifest.xml 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/AndroidManifest.xml 2022-04-11 21:08:20.000000000 +0000 @@ -1,3 +1,7 @@ + + + + diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/bools.xml apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/bools.xml --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/bools.xml 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/bools.xml 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,4 @@ + + + @*android:bool/config_enableActivityRecognitionHardwareOverlay + diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/colors.xml apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/colors.xml --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/colors.xml 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/colors.xml 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,4 @@ + + + @*android:color/Indigo_700 + diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/strings.xml apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/strings.xml --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/strings.xml 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/aapt2/testapp/res/values/strings.xml 2022-04-11 21:08:20.000000000 +0000 @@ -2,4 +2,6 @@ testapp + 🔆 +
  • aaaaa aa aaaaa – aaaaaaa aaaaaaaaaa aa aaaaaaaa aaaaaa aaaaa (aaaa) aaaa aaaaaaaaa aaaaa aa aaaaaaaaa aaaaaaa aaaa
  • aaaaaaaaa aaaaaaaaaaaaaaa aaaaaaaa – aaaaaaa aaaaaaaaaa aaaaaaaaa aaaa aaaaaa aa aaaa aaaa aaaa aaaa aaaaaaa aaaaaaaaaaaaa, aaaaaa aaa aaaaaaaaaa (aaa) aaaaaaaaaaaaaaa
  • aaaaaaaaaaa aaaaaa aaaaaaaaaa – aaaaaaaaaa aaaa aaaaaa aa a aaa aa aaaaaa aaa aaaaaaa (aaaaa aaaaaaaa) aaaaaaaa aa aaaaaa aaaaa aaa aaaa
diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/decode/issue2543/AndroidManifest.xml apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/decode/issue2543/AndroidManifest.xml --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/decode/issue2543/AndroidManifest.xml 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/decode/issue2543/AndroidManifest.xml 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/decode/issue2543/apktool.yml apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/decode/issue2543/apktool.yml --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/decode/issue2543/apktool.yml 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/decode/issue2543/apktool.yml 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,12 @@ +version: 2.0.0 +apkFileName: issue2543.apk +isFrameworkApk: false +usesFramework: + ids: + - 1 +packageInfo: + forcedPackageId: '127' +versionInfo: + versionCode: '1' + versionName: '1.0' +compressionType: false \ No newline at end of file Binary files /tmp/tmppx8b2jgk/fCNYn8NsWd/apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/decode/issue2543/classes.dex and /tmp/tmppx8b2jgk/1p2o6NjBNX/apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/decode/issue2543/classes.dex differ diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/AndroidManifest.xml apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/AndroidManifest.xml --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/AndroidManifest.xml 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/AndroidManifest.xml 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,4 @@ + + + + diff -Nru apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/apktool.yml apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/apktool.yml --- apktool-2.5.0+dfsg.1/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/apktool.yml 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/apktool.yml 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,23 @@ +!!brut.androlib.meta.MetaInfo +apkFileName: cve20220476.apk +compressionType: false +some_var: !!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["https://127.0.0.1:8000"]]]] +doNotCompress: +- resources.arsc +isFrameworkApk: false +packageInfo: + forcedPackageId: '127' + renameManifestPackage: null +sdkInfo: + minSdkVersion: '25' + targetSdkVersion: '30' +sharedLibrary: false +sparseResources: false +usesFramework: + ids: + - 1 + tag: null +version: 2.6.1-ddc4bb-SNAPSHOT +versionInfo: + versionCode: null + versionName: null diff -Nru apktool-2.5.0+dfsg.1/brut.j.common/build.gradle apktool-2.6.1+dfsg.1/brut.j.common/build.gradle --- apktool-2.5.0+dfsg.1/brut.j.common/build.gradle 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.common/build.gradle 2022-04-11 21:08:20.000000000 +0000 @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.j.common/src/main/java/brut/common/BrutException.java apktool-2.6.1+dfsg.1/brut.j.common/src/main/java/brut/common/BrutException.java --- apktool-2.5.0+dfsg.1/brut.j.common/src/main/java/brut/common/BrutException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.common/src/main/java/brut/common/BrutException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,6 @@ */ package brut.common; -/** - * @author Ryszard Wiśniewski - */ public class BrutException extends Exception { public BrutException(Throwable cause) { super(cause); diff -Nru apktool-2.5.0+dfsg.1/brut.j.common/src/main/java/brut/common/InvalidUnknownFileException.java apktool-2.6.1+dfsg.1/brut.j.common/src/main/java/brut/common/InvalidUnknownFileException.java --- apktool-2.5.0+dfsg.1/brut.j.common/src/main/java/brut/common/InvalidUnknownFileException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.common/src/main/java/brut/common/InvalidUnknownFileException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.j.common/src/main/java/brut/common/RootUnknownFileException.java apktool-2.6.1+dfsg.1/brut.j.common/src/main/java/brut/common/RootUnknownFileException.java --- apktool-2.5.0+dfsg.1/brut.j.common/src/main/java/brut/common/RootUnknownFileException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.common/src/main/java/brut/common/RootUnknownFileException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.j.common/src/main/java/brut/common/TraversalUnknownFileException.java apktool-2.6.1+dfsg.1/brut.j.common/src/main/java/brut/common/TraversalUnknownFileException.java --- apktool-2.5.0+dfsg.1/brut.j.common/src/main/java/brut/common/TraversalUnknownFileException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.common/src/main/java/brut/common/TraversalUnknownFileException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.j.common/src/templates/apache2.0-header.txt apktool-2.6.1+dfsg.1/brut.j.common/src/templates/apache2.0-header.txt --- apktool-2.5.0+dfsg.1/brut.j.common/src/templates/apache2.0-header.txt 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.common/src/templates/apache2.0-header.txt 2022-04-11 21:08:20.000000000 +0000 @@ -5,7 +5,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/build.gradle apktool-2.6.1+dfsg.1/brut.j.dir/build.gradle --- apktool-2.5.0+dfsg.1/brut.j.dir/build.gradle 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/build.gradle 2022-04-11 21:08:20.000000000 +0000 @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/AbstractDirectory.java apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/AbstractDirectory.java --- apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/AbstractDirectory.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/AbstractDirectory.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -44,7 +44,7 @@ return mFiles; } if (mFilesRecursive == null) { - mFilesRecursive = new LinkedHashSet(mFiles); + mFilesRecursive = new LinkedHashSet<>(mFiles); for (Map.Entry dir : getAbstractDirs().entrySet()) { for (String path : dir.getValue().getFiles(true)) { mFilesRecursive.add(dir.getKey() + separator + path); @@ -93,7 +93,7 @@ @Override public Map getDirs(boolean recursive) throws UnsupportedOperationException { - return new LinkedHashMap(getAbstractDirs(recursive)); + return new LinkedHashMap<>(getAbstractDirs(recursive)); } @Override @@ -115,7 +115,7 @@ getFiles().add(parsed.subpath); return getFileOutputLocal(parsed.subpath); } - + Directory dir; // IMPOSSIBLE_EXCEPTION try { @@ -150,7 +150,7 @@ getAbstractDirs().put(parsed.subpath, dir); return dir; } - + if (getAbstractDirs().containsKey(parsed.dir)) { dir = getAbstractDirs().get(parsed.dir); } else { @@ -225,7 +225,7 @@ return mDirs; } - Map dirs = new LinkedHashMap(mDirs); + Map dirs = new LinkedHashMap<>(mDirs); for (Map.Entry dir : getAbstractDirs().entrySet()) { for (Map.Entry subdir : dir.getValue().getAbstractDirs( true).entrySet()) { @@ -251,38 +251,38 @@ } return new SubPath(getAbstractDirs().get(parsed.dir), parsed.subpath); } - + private ParsedPath parsePath(String path) { int pos = path.indexOf(separator); if (pos == -1) { return new ParsedPath(null, path); } - return new ParsedPath(path.substring(0, pos), path.substring(pos + 1)); + return new ParsedPath(path.substring(0, pos), path.substring(pos + 1)); } - abstract protected void loadFiles(); - abstract protected void loadDirs(); - abstract protected InputStream getFileInputLocal(String name) + protected abstract void loadFiles(); + protected abstract void loadDirs(); + protected abstract InputStream getFileInputLocal(String name) throws DirectoryException; - abstract protected OutputStream getFileOutputLocal(String name) + protected abstract OutputStream getFileOutputLocal(String name) throws DirectoryException; - abstract protected AbstractDirectory createDirLocal(String name) + protected abstract AbstractDirectory createDirLocal(String name) throws DirectoryException; - abstract protected void removeFileLocal(String name); - - + protected abstract void removeFileLocal(String name); + + private class ParsedPath { - public String dir; - public String subpath; + public final String dir; + public final String subpath; public ParsedPath(String dir, String subpath) { this.dir = dir; this.subpath = subpath; } - } - + } + private class SubPath { - public AbstractDirectory dir; - public String path; + public final AbstractDirectory dir; + public final String path; public SubPath(AbstractDirectory dir, String path) { this.dir = dir; diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/DirectoryException.java apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/DirectoryException.java --- apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/DirectoryException.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/DirectoryException.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/Directory.java apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/Directory.java --- apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/Directory.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/Directory.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,46 +16,62 @@ */ package brut.directory; -import java.io.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.Map; import java.util.Set; public interface Directory { - public Set getFiles(); - public Set getFiles(boolean recursive); - public Map getDirs(); - public Map getDirs(boolean recursive); - - public boolean containsFile(String path); - public boolean containsDir(String path); - - public InputStream getFileInput(String path) throws DirectoryException; - public OutputStream getFileOutput(String path) throws DirectoryException; - public Directory getDir(String path) throws PathNotExist; - public Directory createDir(String path) throws DirectoryException; - - public boolean removeFile(String path); - - public void copyToDir(Directory out) throws DirectoryException; - public void copyToDir(Directory out, String[] fileNames) - throws DirectoryException; - public void copyToDir(Directory out, String fileName) - throws DirectoryException; - public void copyToDir(File out) throws DirectoryException; - public void copyToDir(File out, String[] fileNames) - throws DirectoryException; - public void copyToDir(File out, String fileName) - throws DirectoryException; - - public long getSize(String fileName) - throws DirectoryException; - public long getCompressedSize(String fileName) - throws DirectoryException; - public int getCompressionLevel(String fileName) - throws DirectoryException; - - - public void close() throws IOException; - - public final char separator = '/'; + Set getFiles(); + + Set getFiles(boolean recursive); + + Map getDirs(); + + Map getDirs(boolean recursive); + + boolean containsFile(String path); + + boolean containsDir(String path); + + InputStream getFileInput(String path) throws DirectoryException; + + OutputStream getFileOutput(String path) throws DirectoryException; + + Directory getDir(String path) throws PathNotExist; + + Directory createDir(String path) throws DirectoryException; + + boolean removeFile(String path); + + void copyToDir(Directory out) throws DirectoryException; + + void copyToDir(Directory out, String[] fileNames) + throws DirectoryException; + + void copyToDir(Directory out, String fileName) + throws DirectoryException; + + void copyToDir(File out) throws DirectoryException; + + void copyToDir(File out, String[] fileNames) + throws DirectoryException; + + void copyToDir(File out, String fileName) + throws DirectoryException; + + long getSize(String fileName) + throws DirectoryException; + + long getCompressedSize(String fileName) + throws DirectoryException; + + int getCompressionLevel(String fileName) + throws DirectoryException; + + void close() throws IOException; + + char separator = '/'; } diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/DirUtil.java apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/DirUtil.java --- apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/DirUtil.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/DirUtil.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,14 +17,21 @@ package brut.directory; import brut.common.BrutException; +import brut.common.InvalidUnknownFileException; +import brut.common.RootUnknownFileException; +import brut.common.TraversalUnknownFileException; import brut.util.BrutIO; import brut.util.OS; import java.io.*; +import java.util.logging.Logger; -/** - * @author Ryszard Wiśniewski - */ public class DirUtil { + private static final Logger LOGGER = Logger.getLogger(""); + + private DirUtil() { + // Private constructor for utility class + } + public static void copyToDir(Directory in, Directory out) throws DirectoryException { for (String fileName : in.getFiles(true)) { @@ -34,8 +41,8 @@ public static void copyToDir(Directory in, Directory out, String[] fileNames) throws DirectoryException { - for (int i = 0; i < fileNames.length; i++) { - copyToDir(in, out, fileNames[i]); + for (String fileName : fileNames) { + copyToDir(in, out, fileName); } } @@ -66,8 +73,8 @@ public static void copyToDir(Directory in, File out, String[] fileNames) throws DirectoryException { - for (int i = 0; i < fileNames.length; i++) { - copyToDir(in, out, fileNames[i]); + for (String fileName : fileNames) { + copyToDir(in, out, fileName); } } @@ -84,15 +91,12 @@ String cleanedFilename = BrutIO.sanitizeUnknownFile(out, fileName); File outFile = new File(out, cleanedFilename); outFile.getParentFile().mkdirs(); - BrutIO.copyAndClose(in.getFileInput(fileName), - new FileOutputStream(outFile)); + BrutIO.copyAndClose(in.getFileInput(fileName), new FileOutputStream(outFile)); } - } catch (IOException ex) { - throw new DirectoryException( - "Error copying file: " + fileName, ex); - } catch (BrutException ex) { - throw new DirectoryException( - "Error copying file: " + fileName, ex); + } catch (RootUnknownFileException | InvalidUnknownFileException | TraversalUnknownFileException exception) { + LOGGER.warning(String.format("Skipping file %s (%s)", fileName, exception.getMessage())); + } catch (IOException | BrutException ex) { + throw new DirectoryException("Error copying file: " + fileName, ex); } } } diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/ExtFile.java apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/ExtFile.java --- apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/ExtFile.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/ExtFile.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,9 +20,6 @@ import java.io.IOException; import java.net.URI; -/** - * @author Ryszard Wiśniewski - */ public class ExtFile extends File { public ExtFile(File file) { super(file.getPath()); diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/FileDirectory.java apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/FileDirectory.java --- apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/FileDirectory.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/FileDirectory.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -22,9 +22,9 @@ import java.util.LinkedHashSet; public class FileDirectory extends AbstractDirectory { - private File mDir; + private final File mDir; - public FileDirectory(ExtFile dir, String folder) throws DirectoryException, UnsupportedEncodingException { + public FileDirectory(ExtFile dir, String folder) throws DirectoryException { this(new File(dir.toString().replaceAll("%20", " "), folder)); } @@ -101,19 +101,18 @@ } private void loadAll() { - mFiles = new LinkedHashSet(); - mDirs = new LinkedHashMap(); + mFiles = new LinkedHashSet<>(); + mDirs = new LinkedHashMap<>(); File[] files = getDir().listFiles(); - for (int i = 0; i < files.length; i++) { - File file = files[i]; + for (File file : files) { if (file.isFile()) { mFiles.add(file.getName()); } else { // IMPOSSIBLE_EXCEPTION try { mDirs.put(file.getName(), new FileDirectory(file)); - } catch (DirectoryException e) {} + } catch (DirectoryException ignored) {} } } } diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/PathAlreadyExists.java apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/PathAlreadyExists.java --- apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/PathAlreadyExists.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/PathAlreadyExists.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/PathNotExist.java apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/PathNotExist.java --- apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/PathNotExist.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/PathNotExist.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/ZipRODirectory.java apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/ZipRODirectory.java --- apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/ZipRODirectory.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/ZipRODirectory.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -27,8 +27,8 @@ import java.util.zip.ZipFile; public class ZipRODirectory extends AbstractDirectory { - private ZipFile mZipFile; - private String mPath; + private final ZipFile mZipFile; + private final String mPath; public ZipRODirectory(String zipFileName) throws DirectoryException { this(zipFileName, ""); @@ -64,8 +64,7 @@ } @Override - protected AbstractDirectory createDirLocal(String name) - throws DirectoryException { + protected AbstractDirectory createDirLocal(String name) { throw new UnsupportedOperationException(); } @@ -80,8 +79,7 @@ } @Override - protected OutputStream getFileOutputLocal(String name) - throws DirectoryException { + protected OutputStream getFileOutputLocal(String name) { throw new UnsupportedOperationException(); } @@ -131,21 +129,21 @@ } private void loadAll() { - mFiles = new LinkedHashSet(); - mDirs = new LinkedHashMap(); - + mFiles = new LinkedHashSet<>(); + mDirs = new LinkedHashMap<>(); + int prefixLen = getPath().length(); Enumeration entries = getZipFile().entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); String name = entry.getName(); - + if (name.equals(getPath()) || ! name.startsWith(getPath()) || name.contains(".." + separator)) { continue; } - + String subname = name.substring(prefixLen); - + int pos = subname.indexOf(separator); if (pos == -1) { if (! entry.isDirectory()) { @@ -155,10 +153,10 @@ } else { subname = subname.substring(0, pos); } - + if (! mDirs.containsKey(subname)) { AbstractDirectory dir = new ZipRODirectory(getZipFile(), getPath() + subname + separator); - mDirs.put(subname, dir); + mDirs.put(subname, dir); } } } diff -Nru apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/ZipUtils.java apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/ZipUtils.java --- apktool-2.5.0+dfsg.1/brut.j.dir/src/main/java/brut/directory/ZipUtils.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.dir/src/main/java/brut/directory/ZipUtils.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -31,6 +31,10 @@ private static Collection mDoNotCompress; + private ZipUtils() { + // Private constructor for utility class + } + public static void zipFolders(final File folder, final File zip, final File assets, final Collection doNotCompress) throws BrutException, IOException { diff -Nru apktool-2.5.0+dfsg.1/brut.j.util/build.gradle apktool-2.6.1+dfsg.1/brut.j.util/build.gradle --- apktool-2.5.0+dfsg.1/brut.j.util/build.gradle 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.util/build.gradle 2022-04-11 21:08:20.000000000 +0000 @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff -Nru apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/AaptManager.java apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/AaptManager.java --- apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/AaptManager.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/AaptManager.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -23,15 +23,15 @@ public class AaptManager { - public static File getAppt2() throws BrutException { - return getAppt(2); + public static File getAapt2() throws BrutException { + return getAapt(2); } - public static File getAppt1() throws BrutException { - return getAppt(1); + public static File getAapt1() throws BrutException { + return getAapt(1); } - private static File getAppt(Integer version) throws BrutException { + private static File getAapt(Integer version) throws BrutException { File aaptBinary; String aaptVersion = getAaptBinaryName(version); @@ -78,7 +78,7 @@ } public static int getAaptVersion(String aaptLocation) throws BrutException { - return getApptVersion(new File(aaptLocation)); + return getAaptVersion(new File(aaptLocation)); } public static String getAaptBinaryName(Integer version) { @@ -97,7 +97,7 @@ throw new BrutException("aapt version could not be identified: " + version); } - public static int getApptVersion(File aapt) throws BrutException { + public static int getAaptVersion(File aapt) throws BrutException { if (!aapt.isFile()) { throw new BrutException("Could not identify aapt binary as executable."); } diff -Nru apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/BrutIO.java apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/BrutIO.java --- apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/BrutIO.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/BrutIO.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,21 +16,18 @@ */ package brut.util; -import java.io.*; -import java.util.zip.CRC32; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - import brut.common.BrutException; import brut.common.InvalidUnknownFileException; import brut.common.RootUnknownFileException; import brut.common.TraversalUnknownFileException; import org.apache.commons.io.IOUtils; -/** - * @author Ryszard Wiśniewski - */ +import java.io.*; +import java.util.zip.CRC32; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + public class BrutIO { public static void copyAndClose(InputStream in, OutputStream out) throws IOException { @@ -44,8 +41,8 @@ public static long recursiveModifiedTime(File[] files) { long modified = 0; - for (int i = 0; i < files.length; i++) { - long submodified = recursiveModifiedTime(files[i]); + for (File file : files) { + long submodified = recursiveModifiedTime(file); if (submodified > modified) { modified = submodified; } @@ -57,8 +54,8 @@ long modified = file.lastModified(); if (file.isDirectory()) { File[] subfiles = file.listFiles(); - for (int i = 0; i < subfiles.length; i++) { - long submodified = recursiveModifiedTime(subfiles[i]); + for (File subfile : subfiles) { + long submodified = recursiveModifiedTime(subfile); if (submodified > modified) { modified = submodified; } @@ -79,18 +76,18 @@ public static String sanitizeUnknownFile(final File directory, final String entry) throws IOException, BrutException { if (entry.length() == 0) { - throw new InvalidUnknownFileException("Invalid Unknown File - " + entry); + throw new InvalidUnknownFileException("Invalid Unknown File"); } if (new File(entry).isAbsolute()) { - throw new RootUnknownFileException("Absolute Unknown Files is not allowed - " + entry); + throw new RootUnknownFileException("Absolute Unknown Files is not allowed"); } final String canonicalDirPath = directory.getCanonicalPath() + File.separator; final String canonicalEntryPath = new File(directory, entry).getCanonicalPath(); if (!canonicalEntryPath.startsWith(canonicalDirPath)) { - throw new TraversalUnknownFileException("Directory Traversal is not allowed - " + entry); + throw new TraversalUnknownFileException("Directory Traversal is not allowed"); } // https://stackoverflow.com/q/2375903/455008 diff -Nru apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/DataInputDelegate.java apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/DataInputDelegate.java --- apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/DataInputDelegate.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/DataInputDelegate.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,10 +19,7 @@ import java.io.DataInput; import java.io.IOException; -/** - * @author Ryszard Wiśniewski - */ -abstract public class DataInputDelegate implements DataInput { +public abstract class DataInputDelegate implements DataInput { protected final DataInput mDelegate; public DataInputDelegate(DataInput delegate) { diff -Nru apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/Duo.java apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/Duo.java --- apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/Duo.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/Duo.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,8 @@ */ package brut.util; -/** - * @author Ryszard Wiśniewski - */ +import java.util.Objects; + public class Duo { public final T1 m1; public final T2 m2; @@ -37,13 +36,10 @@ return false; } final Duo other = (Duo) obj; - if (this.m1 != other.m1 && (this.m1 == null || !this.m1.equals(other.m1))) { - return false; - } - if (this.m2 != other.m2 && (this.m2 == null || !this.m2.equals(other.m2))) { + if (!Objects.equals(this.m1, other.m1)) { return false; } - return true; + return Objects.equals(this.m2, other.m2); } @Override diff -Nru apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/ExtDataInput.java apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/ExtDataInput.java --- apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/ExtDataInput.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/ExtDataInput.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,9 +18,6 @@ import java.io.*; -/** - * @author Ryszard Wiśniewski - */ public class ExtDataInput extends DataInputDelegate { public ExtDataInput(InputStream in) { this((DataInput) new DataInputStream(in)); @@ -83,9 +80,9 @@ */ public final int skipBytes(int n) throws IOException { int total = 0; - int cur = 0; + int cur; - while ((total < n) && ((cur = (int) super.skipBytes(n - total)) > 0)) { + while ((total < n) && ((cur = super.skipBytes(n - total)) > 0)) { total += cur; } diff -Nru apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/Jar.java apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/Jar.java --- apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/Jar.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/Jar.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,30 +16,18 @@ */ package brut.util; +import brut.common.BrutException; import org.apache.commons.io.IOUtils; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import java.util.concurrent.ThreadLocalRandom; -import brut.common.BrutException; +public abstract class Jar { + private static final Map mExtracted = new HashMap<>(); -/** - * @author Ryszard Wiśniewski - */ -abstract public class Jar { - private final static Set mLoaded = new HashSet(); - private final static Map mExtracted = new HashMap(); - - public static File getResourceAsFile(String name, Class clazz) throws BrutException { + public static File getResourceAsFile(String name, Class clazz) throws BrutException { File file = mExtracted.get(name); if (file == null) { file = extractToTmp(name, clazz); @@ -48,38 +36,11 @@ return file; } - public static File getResourceAsFile(String name) throws BrutException { - return getResourceAsFile(name, Class.class); - } - - public static void load(String libPath) { - if (mLoaded.contains(libPath)) { - return; - } - - File libFile; - try { - libFile = getResourceAsFile(libPath); - } catch (BrutException ex) { - throw new UnsatisfiedLinkError(ex.getMessage()); - } - - System.load(libFile.getAbsolutePath()); - } - - public static File extractToTmp(String resourcePath) throws BrutException { - return extractToTmp(resourcePath, Class.class); - } - - public static File extractToTmp(String resourcePath, Class clazz) throws BrutException { + public static File extractToTmp(String resourcePath, Class clazz) throws BrutException { return extractToTmp(resourcePath, "brut_util_Jar_", clazz); } - public static File extractToTmp(String resourcePath, String tmpPrefix) throws BrutException { - return extractToTmp(resourcePath, tmpPrefix, Class.class); - } - - public static File extractToTmp(String resourcePath, String tmpPrefix, Class clazz) throws BrutException { + public static File extractToTmp(String resourcePath, String tmpPrefix, Class clazz) throws BrutException { try { InputStream in = clazz.getResourceAsStream(resourcePath); if (in == null) { diff -Nru apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/OSDetection.java apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/OSDetection.java --- apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/OSDetection.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/OSDetection.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,8 +17,8 @@ package brut.util; public class OSDetection { - private static String OS = System.getProperty("os.name").toLowerCase(); - private static String Bit = System.getProperty("sun.arch.data.model").toLowerCase(); + private static final String OS = System.getProperty("os.name").toLowerCase(); + private static final String BIT = System.getProperty("sun.arch.data.model").toLowerCase(); public static boolean isWindows() { return (OS.contains("win")); @@ -39,7 +39,7 @@ return arch != null && arch.endsWith("64") || wow64Arch != null && wow64Arch.endsWith("64"); } - return Bit.equalsIgnoreCase("64"); + return BIT.equalsIgnoreCase("64"); } public static String returnOS() { diff -Nru apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/OS.java apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/OS.java --- apktool-2.5.0+dfsg.1/brut.j.util/src/main/java/brut/util/OS.java 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/brut.j.util/src/main/java/brut/util/OS.java 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,6 +17,8 @@ package brut.util; import brut.common.BrutException; +import org.apache.commons.io.IOUtils; + import java.io.*; import java.util.Arrays; import java.util.concurrent.ExecutorService; @@ -24,11 +26,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Logger; -import org.apache.commons.io.IOUtils; - -/** - * @author Ryszard Wiśniewski - */ public class OS { private static final Logger LOGGER = Logger.getLogger(""); @@ -38,8 +35,11 @@ return; } File[] files = dir.listFiles(); - for (int i = 0; i < files.length; i++) { - File file = files[i]; + if (files == null) { + return; + } + + for (File file : files) { if (file.isDirectory()) { rmdir(file); } else { @@ -48,8 +48,8 @@ } dir.delete(); } - - public static void rmfile(String file) throws BrutException { + + public static void rmfile(String file) { File del = new File(file); del.delete(); } @@ -61,41 +61,43 @@ public static void cpdir(File src, File dest) throws BrutException { dest.mkdirs(); File[] files = src.listFiles(); - for (int i = 0; i < files.length; i++) { - File file = files[i]; - File destFile = new File(dest.getPath() + File.separatorChar - + file.getName()); + if (files == null) { + return; + } + + for (File file : files) { + File destFile = new File(dest.getPath() + File.separatorChar + file.getName()); if (file.isDirectory()) { cpdir(file, destFile); continue; } try { - InputStream in = new FileInputStream(file); - OutputStream out = new FileOutputStream(destFile); - IOUtils.copy(in, out); - in.close(); - out.close(); + try (InputStream in = new FileInputStream(file)) { + try (OutputStream out = new FileOutputStream(destFile)) { + IOUtils.copy(in, out); + } + } } catch (IOException ex) { throw new BrutException("Could not copy file: " + file, ex); } } } - public static void cpdir(String src, String dest) throws BrutException { - cpdir(new File(src), new File(dest)); - } - public static void exec(String[] cmd) throws BrutException { - Process ps = null; - int exitValue = -99; + Process ps; + int exitValue; + try { ProcessBuilder builder = new ProcessBuilder(cmd); ps = builder.start(); + new StreamForwarder(ps.getErrorStream(), "ERROR").start(); new StreamForwarder(ps.getInputStream(), "OUTPUT").start(); + exitValue = ps.waitFor(); - if (exitValue != 0) + if (exitValue != 0) { throw new BrutException("could not exec (exit code = " + exitValue + "): " + Arrays.toString(cmd)); + } } catch (IOException ex) { throw new BrutException("could not exec: " + Arrays.toString(cmd), ex); } catch (InterruptedException ex) { @@ -171,7 +173,7 @@ } static class StreamCollector implements Runnable { - private final StringBuffer buffer = new StringBuffer(); + private final StringBuilder buffer = new StringBuilder(); private final InputStream inputStream; public StreamCollector(InputStream inputStream) { diff -Nru apktool-2.5.0+dfsg.1/build.gradle apktool-2.6.1+dfsg.1/build.gradle --- apktool-2.5.0+dfsg.1/build.gradle 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/build.gradle 2022-04-11 21:08:20.000000000 +0000 @@ -1,3 +1,5 @@ +import java.nio.charset.StandardCharsets + /** * Copyright 2014 Ryszard Wiśniewski * @@ -5,7 +7,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,31 +16,44 @@ * limitations under the License. */ buildscript { - repositories { - jcenter() + ext { + depends = [ + baksmali : 'org.smali:baksmali:2.5.2', + commons_cli : 'commons-cli:commons-cli:1.5.0', + commons_io : 'commons-io:commons-io:2.11.0', + commons_lang : 'org.apache.commons:commons-lang3:3.12.0', + commons_text : 'org.apache.commons:commons-text:1.9', + guava : 'com.google.guava:guava:31.0.1-jre', + junit : 'junit:junit:4.13.2', + proguard_gradle: 'com.guardsquare:proguard-gradle:7.1.1', + snakeyaml : 'org.yaml:snakeyaml:1.29:android', + smali : 'org.smali:smali:2.5.2', + xmlpull : 'xpp3:xpp3:1.1.4c', + xmlunit : 'xmlunit:xmlunit:1.6', + ] } - tasks.withType(JavaCompile) { - options.encoding = "UTF-8" + + repositories { + mavenCentral() + gradlePluginPortal() } dependencies { - classpath 'com.github.jengelman.gradle.plugins:shadow:6.1.0' + classpath "gradle.plugin.com.github.johnrengelman:shadow:7.1.0" + classpath "gradle.plugin.com.hierynomus.gradle.plugins:license-gradle-plugin:0.16.1" } } -plugins { - id 'com.github.hierynomus.license' version '0.15.0' -} - apply from: 'gradle/functions.gradle' -def apktoolversion_major = '2.5.0' -def apktoolversion_minor = '' +version = '2.6.1' +def suffix = '' defaultTasks 'build', 'shadowJar', 'proguard' allprojects { apply plugin: 'java' - apply plugin: 'license' + apply plugin: 'com.github.hierynomus.license' + sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 @@ -50,44 +65,51 @@ mapping { java = 'SLASHSTAR_STYLE' } + ext { + year = '2010' + brut = 'Ryszard Wiśniewski' + brutEmail = 'brut.alll@gmail.com' + ibot = 'Connor Tumbleson' + ibotEmail = 'connor.tumbleson@gmail.com' + } strictCheck true - - ext.year = '2010' - ext.brut = 'Ryszard Wiśniewski' - ext.brutEmail = 'brut.alll@gmail.com' - ext.ibot = 'Connor Tumbleson' - ext.ibotEmail = 'connor.tumbleson@gmail.com' - } - - tasks.withType(JavaCompile) { - options.compilerArgs += ["-Xlint:-options"] } // license plugin automatically fires these tasks, disable them and run them during releases - gradle.startParameter.excludedTaskNames += "licenseMain" - gradle.startParameter.excludedTaskNames += "licenseTest" + gradle.startParameter.excludedTaskNames += [ + "licenseMain", + "licenseTest" + ] +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = StandardCharsets.UTF_8.toString() + options.compilerArgs += ["-Xlint:-options"] } +def mavenVersion = 'unspecified' if (!('release' in gradle.startParameter.taskNames)) { - def hash = getCheckedOutGitCommitHash(); + def hash = getCheckedOutGitCommitHash() if (hash == null) { project.ext.set("hash", "dirty") - project.ext.set("apktool_version", apktoolversion_major + "-dirty") - println "Building SNAPSHOT (no .git folder found)"; + project.ext.set("apktool_version", version + "-dirty") + println "Building SNAPSHOT (no .git folder found)" } else { - project.ext.set("hash", hash); - project.ext.set("apktool_version", apktoolversion_major + "-" + hash + "-SNAPSHOT"); - println "Building SNAPSHOT (" + getCheckedOutBranch() + "): " + hash; + project.ext.set("hash", hash) + project.ext.set("apktool_version", version + "-" + hash + "-SNAPSHOT") + mavenVersion = version + "-SNAPSHOT" + println "Building SNAPSHOT (${getCheckedOutBranch()}): $hash" } } else { project.ext.set("hash", "") - if (apktoolversion_minor.length() > 0) { - project.ext.set("apktool_version", apktoolversion_major + "-" + apktoolversion_minor); + if (suffix.length() > 0) { + project.ext.set("apktool_version", version + "-" + suffix) } else { - project.ext.set("apktool_version", apktoolversion_major); + project.ext.set("apktool_version", version) } - println "Building RELEASE (" + getCheckedOutBranch() + "): " + project.ext.apktool_version; + mavenVersion = version + println "Building RELEASE (${getCheckedOutBranch()}): $project.ext.apktool_version" } build.doFirst { @@ -99,7 +121,7 @@ "We found a " + javaVersion + " JDK\n" + "Please update JAVA_HOME to use at least a 1.8 JDK\n" + "Currently it is set to: " + System.getProperty("java.home") - ); + ) } } @@ -107,25 +129,13 @@ task release { } +// used for publishing snapshot builds to maven. +task snapshot { +} + subprojects { apply plugin: 'java' - ext { - depends = [ - baksmali: 'org.smali:baksmali:2.4.0', - commons_cli: 'commons-cli:commons-cli:1.4', - commons_io: 'commons-io:commons-io:2.4', - commons_lang: 'org.apache.commons:commons-lang3:3.1', - guava: 'com.google.guava:guava:14.0', - junit: 'junit:junit:4.12', - proguard_gradle: 'com.guardsquare:proguard-gradle:7.0.0', - snakeyaml: 'org.yaml:snakeyaml:1.18:android', - smali: 'org.smali:smali:2.4.0', - xmlpull: 'xpp3:xpp3:1.1.4c', - xmlunit: 'xmlunit:xmlunit:1.6', - ] - } - repositories { mavenCentral() } @@ -135,4 +145,81 @@ exceptionFormat = 'full' } } + + def mavenProjects = ['apktool-lib', 'apktool-cli', 'brut.j.common', 'brut.j.util', 'brut.j.dir'] + + if (project.name in mavenProjects) { + apply plugin: 'maven-publish' + apply plugin: 'signing' + + publishing { + publications { + maven(MavenPublication) { + from project.components.java + + groupId = 'org.apktool' + artifactId = project.name + version = mavenVersion + + pom { + name = 'Apktool' + description = 'A tool for reverse engineering Android apk files.' + url = 'https://apktool.org' + + licenses { + license { + name = 'The Apache License 2.0' + url = 'https://opensource.org/licenses/Apache-2.0' + } + } + developers { + developer { + id = 'iBotPeaches' + name = 'Connor Tumbleson' + email = 'connor.tumbleson@gmail.com' + } + developer { + id = 'brutall' + name = 'Ryszard Wiśniewski' + email = 'brut.alll@gmail.com' + } + } + scm { + connection = 'scm:git:git://github.com/iBotPeaches/Apktool.git' + developerConnection = 'scm:git:git@github.com:iBotPeaches/Apktool.git' + url = 'https://github.com/iBotPeaches/Apktool' + } + } + } + } + if (rootProject.hasProperty('ossrhUsername') && rootProject.hasProperty('ossrhPassword')) { + repositories { + maven { + if (mavenVersion.endsWith('-SNAPSHOT')) { + url = 'https://s01.oss.sonatype.org/content/repositories/snapshots/' + } else { + url = 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/' + } + credentials { + username ossrhUsername + password ossrhPassword + } + } + } + } + } + + signing { + required { gradle.taskGraph.hasTask('publish') } + sign(publishing.publications["maven"]) + } + + java { + withJavadocJar() + withSourcesJar() + } + + tasks.getByPath(':release').dependsOn(publish) + tasks.getByPath(':snapshot').dependsOn(publish) + } } diff -Nru apktool-2.5.0+dfsg.1/CONTRIBUTORS.md apktool-2.6.1+dfsg.1/CONTRIBUTORS.md --- apktool-2.5.0+dfsg.1/CONTRIBUTORS.md 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/CONTRIBUTORS.md 2022-04-11 21:08:20.000000000 +0000 @@ -9,4 +9,4 @@ * Tahseen Ur Rehman (http://code.google.com/p/radixtree/) * Connor Tumbleson (connor.tumbleson@gmail.com) * Android Open Source Project (http://source.android.com/) - * The Apache Software Foundation (http://www.apache.org/) + * The Apache Software Foundation (https://www.apache.org/) diff -Nru apktool-2.5.0+dfsg.1/debian/changelog apktool-2.6.1+dfsg.1/debian/changelog --- apktool-2.5.0+dfsg.1/debian/changelog 2021-02-16 15:09:47.000000000 +0000 +++ apktool-2.6.1+dfsg.1/debian/changelog 2022-05-05 22:00:28.000000000 +0000 @@ -1,8 +1,19 @@ -apktool (2.5.0+dfsg.1-2build1) hirsute; urgency=medium +apktool (2.6.1+dfsg.1-2) unstable; urgency=medium - * No change rebuild with fixed ownership. + * Team upload. + * Add missing dependency - -- Dimitri John Ledkov Tue, 16 Feb 2021 15:09:47 +0000 + -- Jochen Sprickerhof Fri, 06 May 2022 00:00:28 +0200 + +apktool (2.6.1+dfsg.1-1) unstable; urgency=medium + + * Team upload. + * New upstream version 2.6.1+dfsg.1 + * refresh and update patches + * add "libcommons-text-java" to Build-Depends + * exclude build outputs + + -- Sunday Nkwuda Mon, 11 Apr 2022 21:16:02 +0000 apktool (2.5.0+dfsg.1-2) unstable; urgency=medium diff -Nru apktool-2.5.0+dfsg.1/debian/clean apktool-2.6.1+dfsg.1/debian/clean --- apktool-2.5.0+dfsg.1/debian/clean 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/debian/clean 2022-05-05 21:54:02.000000000 +0000 @@ -0,0 +1,4 @@ +build/ +brut.apktool/build +brut.apktool/apktool-cli/build/ +brut.apktool/apktool-lib/build/ diff -Nru apktool-2.5.0+dfsg.1/debian/control apktool-2.6.1+dfsg.1/debian/control --- apktool-2.5.0+dfsg.1/debian/control 2021-02-16 15:09:47.000000000 +0000 +++ apktool-2.6.1+dfsg.1/debian/control 2022-05-05 21:54:21.000000000 +0000 @@ -1,8 +1,7 @@ Source: apktool Section: devel Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Android Tools Maintainers +Maintainer: Android Tools Maintainers Uploaders: Markus Koschany Build-Depends: @@ -15,6 +14,7 @@ libcommons-cli-java, libcommons-io-java, libcommons-lang3-java, + libcommons-text-java (>= 1.9), libguava-java, libjgit-java, libsmali-java (>= 2.4.0), @@ -38,6 +38,7 @@ libcommons-cli-java, libcommons-io-java, libcommons-lang3-java, + libcommons-text-java, libguava-java, libsmali-java (>= 2.4.0), libstringtemplate-java, diff -Nru apktool-2.5.0+dfsg.1/debian/links apktool-2.6.1+dfsg.1/debian/links --- apktool-2.5.0+dfsg.1/debian/links 2021-02-15 22:31:34.000000000 +0000 +++ apktool-2.6.1+dfsg.1/debian/links 2022-05-05 21:54:02.000000000 +0000 @@ -2,6 +2,7 @@ usr/share/java/commons-cli.jar usr/share/apktool/commons-cli.jar usr/share/java/commons-io.jar usr/share/apktool/commons-io.jar usr/share/java/commons-lang3.jar usr/share/apktool/commons-lang3.jar +usr/share/java/commons-text-1.9.jar usr/share/apktool/commons-text-1.9.jar usr/share/java/guava.jar usr/share/apktool/guava.jar usr/share/java/snakeyaml.jar usr/share/apktool/snakeyaml.jar usr/share/java/stringtemplate.jar usr/share/apktool/stringtemplate.jar diff -Nru apktool-2.5.0+dfsg.1/debian/patches/build.patch apktool-2.6.1+dfsg.1/debian/patches/build.patch --- apktool-2.5.0+dfsg.1/debian/patches/build.patch 2021-02-15 22:31:34.000000000 +0000 +++ apktool-2.6.1+dfsg.1/debian/patches/build.patch 2022-05-05 21:54:02.000000000 +0000 @@ -3,39 +3,34 @@ Subject: build --- - brut.apktool/apktool-cli/build.gradle | 12 ++++-------- - build.gradle | 34 ++-------------------------------- - 2 files changed, 6 insertions(+), 40 deletions(-) - -diff --git a/brut.apktool/apktool-cli/build.gradle b/brut.apktool/apktool-cli/build.gradle -index ce8947b..793332d 100644 + --- a/brut.apktool/apktool-cli/build.gradle +++ b/brut.apktool/apktool-cli/build.gradle -@@ -13,7 +13,6 @@ - * See the License for the specific language governing permissions and - * limitations under the License. +@@ -15,7 +15,6 @@ */ + import proguard.gradle.ProGuardTask + -apply plugin: 'com.github.johnrengelman.shadow' dependencies { implementation depends.commons_cli -@@ -40,11 +39,10 @@ jar { +@@ -41,11 +40,10 @@ } task cleanOutputDirectory(type: Delete) { - delete fileTree(dir: jar.getDestinationDirectory().getAsFile(), exclude: "apktool-cli-all.jar") } --task proguard(type: proguard.gradle.ProGuardTask, dependsOn: shadowJar) { +-task proguard(type: ProGuardTask, dependsOn: shadowJar) { - injars shadowJar.getArchiveFile() -+task proguard(type: proguard.gradle.ProGuardTask) { ++task proguard(type: ProGuardTask) { + injars jar.archivePath // Java 9 and prior uses merged package for runtime, later uses split jmod files. if (JavaVersion.current() <= JavaVersion.VERSION_1_8) { -@@ -72,11 +70,9 @@ task proguard(type: proguard.gradle.ProGuardTask, dependsOn: shadowJar) { - dontwarn 'javax.xml.xpath.**' - dontnote '**' +@@ -76,9 +74,7 @@ + // 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() @@ -44,41 +39,44 @@ outjars outFile } - proguard.dependsOn cleanOutputDirectory --tasks.getByPath(':release').dependsOn(proguard) -\ No newline at end of file -+tasks.getByPath(':release').dependsOn(proguard) -diff --git a/build.gradle b/build.gradle -index 04feefa..0a1ee1b 100644 --- a/build.gradle +++ b/build.gradle -@@ -20,13 +20,6 @@ buildscript { - tasks.withType(JavaCompile) { - options.encoding = "UTF-8" +@@ -25,8 +25,8 @@ + commons_text : 'org.apache.commons:commons-text:1.9', + guava : 'com.google.guava:guava:31.0.1-jre', + junit : 'junit:junit:4.13.2', +- proguard_gradle: 'com.guardsquare:proguard-gradle:7.1.1', +- snakeyaml : 'org.yaml:snakeyaml:1.29:android', ++ proguard_gradle: 'net.sf.proguard:proguard-gradle:6.1.1', ++ snakeyaml : 'org.yaml:snakeyaml:1.29', + smali : 'org.smali:smali:2.5.2', + xmlpull : 'xpp3:xpp3:1.1.4c', + xmlunit : 'xmlunit:xmlunit:1.6', +@@ -37,10 +37,6 @@ + mavenCentral() + gradlePluginPortal() } - dependencies { -- classpath 'com.github.jengelman.gradle.plugins:shadow:6.1.0' +- classpath "gradle.plugin.com.github.johnrengelman:shadow:7.1.0" +- classpath "gradle.plugin.com.hierynomus.gradle.plugins:license-gradle-plugin:0.16.1" - } --} -- --plugins { -- id 'com.github.hierynomus.license' version '0.15.0' } apply from: 'gradle/functions.gradle' -@@ -34,38 +27,12 @@ apply from: 'gradle/functions.gradle' - def apktoolversion_major = '2.5.0' - def apktoolversion_minor = '' +@@ -48,44 +44,16 @@ + version = '2.6.1' + def suffix = '' -defaultTasks 'build', 'shadowJar', 'proguard' +defaultTasks 'build', 'proguard' allprojects { apply plugin: 'java' -- apply plugin: 'license' +- apply plugin: 'com.github.hierynomus.license' + sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 -- + - license { - header rootProject.file("brut.j.common/src/templates/apache2.0-header.txt") - exclude "**/android/content/res/*.java" @@ -87,32 +85,90 @@ - mapping { - java = 'SLASHSTAR_STYLE' - } +- ext { +- year = '2010' +- brut = 'Ryszard Wiśniewski' +- brutEmail = 'brut.alll@gmail.com' +- ibot = 'Connor Tumbleson' +- ibotEmail = 'connor.tumbleson@gmail.com' +- } - strictCheck true -- -- ext.year = '2010' -- ext.brut = 'Ryszard Wiśniewski' -- ext.brutEmail = 'brut.alll@gmail.com' -- ext.ibot = 'Connor Tumbleson' -- ext.ibotEmail = 'connor.tumbleson@gmail.com' -- } -- -- tasks.withType(JavaCompile) { -- options.compilerArgs += ["-Xlint:-options"] - } - - // license plugin automatically fires these tasks, disable them and run them during releases -- gradle.startParameter.excludedTaskNames += "licenseMain" -- gradle.startParameter.excludedTaskNames += "licenseTest" +- gradle.startParameter.excludedTaskNames += [ +- "licenseMain", +- "licenseTest" +- ] } +-tasks.withType(JavaCompile).configureEach { +- options.encoding = StandardCharsets.UTF_8.toString() +- options.compilerArgs += ["-Xlint:-options"] +-} + + def mavenVersion = 'unspecified' if (!('release' in gradle.startParameter.taskNames)) { -@@ -119,7 +86,7 @@ subprojects { - guava: 'com.google.guava:guava:14.0', - junit: 'junit:junit:4.12', -- proguard_gradle: 'com.guardsquare:proguard-gradle:7.0.0', -- snakeyaml: 'org.yaml:snakeyaml:1.18:android', -+ proguard_gradle: 'net.sf.proguard:proguard-gradle:6.1.1', -+ snakeyaml: 'org.yaml:snakeyaml:1.18', - smali: 'org.smali:smali:2.4.0', - xmlpull: 'xpp3:xpp3:1.1.4c', - xmlunit: 'xmlunit:xmlunit:1.6', +@@ -161,62 +129,8 @@ + artifactId = project.name + version = mavenVersion + +- pom { +- name = 'Apktool' +- description = 'A tool for reverse engineering Android apk files.' +- url = 'https://apktool.org' +- +- licenses { +- license { +- name = 'The Apache License 2.0' +- url = 'https://opensource.org/licenses/Apache-2.0' +- } +- } +- developers { +- developer { +- id = 'iBotPeaches' +- name = 'Connor Tumbleson' +- email = 'connor.tumbleson@gmail.com' +- } +- developer { +- id = 'brutall' +- name = 'Ryszard Wiśniewski' +- email = 'brut.alll@gmail.com' +- } +- } +- scm { +- connection = 'scm:git:git://github.com/iBotPeaches/Apktool.git' +- developerConnection = 'scm:git:git@github.com:iBotPeaches/Apktool.git' +- url = 'https://github.com/iBotPeaches/Apktool' +- } +- } + } + } +- if (rootProject.hasProperty('ossrhUsername') && rootProject.hasProperty('ossrhPassword')) { +- repositories { +- maven { +- if (mavenVersion.endsWith('-SNAPSHOT')) { +- url = 'https://s01.oss.sonatype.org/content/repositories/snapshots/' +- } else { +- url = 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/' +- } +- credentials { +- username ossrhUsername +- password ossrhPassword +- } +- } +- } +- } +- } +- +- signing { +- required { gradle.taskGraph.hasTask('publish') } +- sign(publishing.publications["maven"]) +- } +- +- java { +- withJavadocJar() +- withSourcesJar() + } + + tasks.getByPath(':release').dependsOn(publish) diff -Nru apktool-2.5.0+dfsg.1/debian/patches/debian-wrapper.patch apktool-2.6.1+dfsg.1/debian/patches/debian-wrapper.patch --- apktool-2.5.0+dfsg.1/debian/patches/debian-wrapper.patch 2021-02-15 22:31:34.000000000 +0000 +++ apktool-2.6.1+dfsg.1/debian/patches/debian-wrapper.patch 2022-05-05 21:54:02.000000000 +0000 @@ -6,8 +6,6 @@ scripts/linux/apktool | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) -diff --git a/scripts/linux/apktool b/scripts/linux/apktool -index e99086b..827e580 100755 --- a/scripts/linux/apktool +++ b/scripts/linux/apktool @@ -20,6 +20,16 @@ @@ -27,12 +25,14 @@ prog="$0" while [ -h "${prog}" ]; do newProg=`/bin/ls -ld "${prog}"` -@@ -35,24 +45,15 @@ done +@@ -33,19 +43,12 @@ + fi + done oldwd=`pwd` - progdir=`dirname "${prog}"` - cd "${progdir}" --progdir=`pwd` +-progdir=`dirname "${prog}"` +progdir="/usr/share/apktool" + cd "${progdir}" + progdir=`pwd` prog="${progdir}"/`basename "${prog}"` cd "${oldwd}" @@ -43,17 +43,10 @@ - echo `basename "$prog"`": can't find $jarfile" - exit 1 -fi -- - javaOpts="" - # If you want DX to have more memory when executing, uncomment the following - # line and adjust the value accordingly. Use "java -X" for a list of options - # you can pass here. --# - javaOpts="-Xmx512M -Dfile.encoding=utf-8" + javaOpts="" - # Alternatively, this will extract any parameter "-Jxxx" from the command line -@@ -65,13 +66,7 @@ while expr "x$1" : 'x-J' >/dev/null; do +@@ -65,13 +68,8 @@ shift done @@ -62,10 +55,9 @@ -else - jarpath="$libdir/$jarfile" -fi -- + # add current location to path for aapt PATH=$PATH:`pwd`; export PATH; -exec java $javaOpts -jar "$jarpath" "$@" -\ No newline at end of file +exec java $javaOpts -cp "/usr/share/apktool/*" brut.apktool.Main "$@" diff -Nru apktool-2.5.0+dfsg.1/debian/patches/series apktool-2.6.1+dfsg.1/debian/patches/series --- apktool-2.5.0+dfsg.1/debian/patches/series 2021-02-15 22:31:34.000000000 +0000 +++ apktool-2.6.1+dfsg.1/debian/patches/series 2022-05-05 21:54:02.000000000 +0000 @@ -1,5 +1,4 @@ debian-wrapper.patch use_system_framework.patch use_system_aapt.patch -snakeyaml-1.21.patch build.patch diff -Nru apktool-2.5.0+dfsg.1/debian/patches/snakeyaml-1.21.patch apktool-2.6.1+dfsg.1/debian/patches/snakeyaml-1.21.patch --- apktool-2.5.0+dfsg.1/debian/patches/snakeyaml-1.21.patch 2021-02-15 22:31:34.000000000 +0000 +++ apktool-2.6.1+dfsg.1/debian/patches/snakeyaml-1.21.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -From: Markus Koschany -Date: Fri, 29 Jun 2018 19:33:59 +0200 -Subject: snakeyaml 1.21 - -Do not cast constructScalar to String anymore because in snakeyaml 1.21 the -type changed from Object to String. - -Debian-Bug: https://bugs.debian.org/902666 ---- - .../src/main/java/brut/androlib/meta/StringExConstructor.java | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExConstructor.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExConstructor.java -index 79e750e..408b2b1 100644 ---- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExConstructor.java -+++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/StringExConstructor.java -@@ -29,8 +29,8 @@ public class StringExConstructor extends Constructor { - - private class ConstructStringEx extends AbstractConstruct { - public Object construct(Node node) { -- String val = (String) constructScalar((ScalarNode) node); -+ String val = constructScalar((ScalarNode) node); - return YamlStringEscapeUtils.unescapeString(val); - } - } --} -\ No newline at end of file -+} diff -Nru apktool-2.5.0+dfsg.1/debian/patches/use_system_aapt.patch apktool-2.6.1+dfsg.1/debian/patches/use_system_aapt.patch --- apktool-2.5.0+dfsg.1/debian/patches/use_system_aapt.patch 2021-02-15 22:31:34.000000000 +0000 +++ apktool-2.6.1+dfsg.1/debian/patches/use_system_aapt.patch 2022-05-05 21:54:02.000000000 +0000 @@ -3,14 +3,9 @@ Subject: use_system_aapt --- - brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java -index 3c3ca88..12a9d60 100644 ---- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java -+++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java -@@ -34,7 +34,7 @@ public class ApkOptions { +--- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/options/BuildOptions.java ++++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/options/BuildOptions.java +@@ -34,7 +34,7 @@ public String frameworkFolderLocation = null; public String frameworkTag = null; diff -Nru apktool-2.5.0+dfsg.1/debian/patches/use_system_framework.patch apktool-2.6.1+dfsg.1/debian/patches/use_system_framework.patch --- apktool-2.5.0+dfsg.1/debian/patches/use_system_framework.patch 2021-02-15 22:31:34.000000000 +0000 +++ apktool-2.6.1+dfsg.1/debian/patches/use_system_framework.patch 2022-05-05 21:54:02.000000000 +0000 @@ -5,34 +5,20 @@ Rather than including a package provided apk in the jar, just read it directly from where it gets installed. --- - .../src/main/java/brut/androlib/res/AndrolibResources.java | 10 +++------- - 1 file changed, 3 insertions(+), 7 deletions(-) - -diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java -index 49a5a3a..7944d8d 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java -@@ -812,7 +812,7 @@ final public class AndrolibResources { - } - - if (id == 1) { -- try (InputStream in = AndrolibResources.class.getResourceAsStream("/brut/androlib/android-framework.jar"); -+ try (InputStream in = new FileInputStream("/usr/share/android-framework-res/framework-res.apk"); - OutputStream out = new FileOutputStream(apk)) { - IOUtils.copy(in, out); - return apk; -@@ -1013,12 +1013,8 @@ final public class AndrolibResources { - return apkOptions.isAapt2() ? 2 : 1; +@@ -1023,7 +1023,13 @@ } -- public File getAndroidResourcesFile() throws AndrolibException { -- try { -- return Jar.getResourceAsFile("/brut/androlib/android-framework.jar"); -- } catch (BrutException ex) { -- throw new AndrolibException(ex); -- } -+ public File getAndroidResourcesFile() { -+ return new File("/usr/share/android-framework-res/framework-res.apk"); + public InputStream getAndroidFrameworkResourcesAsStream() { +- return Jar.class.getResourceAsStream("/brut/androlib/android-framework.jar"); ++ String resourcePath = "/usr/share/android-framework-res/framework-res.apk"; ++ try { ++ return new FileInputStream(resourcePath); ++ } catch (IOException ex) { ++ System.out.println("Could not extract resource: " + resourcePath); ++ return null; ++ } } public void close() throws IOException { diff -Nru apktool-2.5.0+dfsg.1/.editorconfig apktool-2.6.1+dfsg.1/.editorconfig --- apktool-2.5.0+dfsg.1/.editorconfig 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/.editorconfig 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,14 @@ +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.java] +ij_java_use_single_class_imports = true + +[*.yml] +indent_size = 2 diff -Nru apktool-2.5.0+dfsg.1/.gitattributes apktool-2.6.1+dfsg.1/.gitattributes --- apktool-2.5.0+dfsg.1/.gitattributes 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/.gitattributes 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,7 @@ +* text=auto eol=lf + +*.bat text eol=crlf +*.jar binary +/brut.apktool/apktool-lib/src/main/resources/prebuilt/windows/* binary +/brut.apktool/apktool-lib/src/main/resources/prebuilt/macosx/* binary +/brut.apktool/apktool-lib/src/main/resources/prebuilt/linux/* binary diff -Nru apktool-2.5.0+dfsg.1/.github/FUNDING.yml apktool-2.6.1+dfsg.1/.github/FUNDING.yml --- apktool-2.5.0+dfsg.1/.github/FUNDING.yml 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/.github/FUNDING.yml 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1 @@ +custom: ['https://buymeacoffee.com/iBotPeaches'] Binary files /tmp/tmppx8b2jgk/fCNYn8NsWd/apktool-2.5.0+dfsg.1/.github/intellij.png and /tmp/tmppx8b2jgk/1p2o6NjBNX/apktool-2.6.1+dfsg.1/.github/intellij.png differ diff -Nru apktool-2.5.0+dfsg.1/.github/workflows/build.yml apktool-2.6.1+dfsg.1/.github/workflows/build.yml --- apktool-2.5.0+dfsg.1/.github/workflows/build.yml 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/.github/workflows/build.yml 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,154 @@ +name: CI +env: + BINARY_PATH: brut.apktool/apktool-lib/src/main/resources/prebuilt +on: + push: + branches: + - master + pull_request: + paths: + - '**.java' + - '**.gradle' + - 'brut.apktool/apktool-lib/src/main/resources/**' + - '.github/workflows/**' + +jobs: + analyze-mac-aapt: + runs-on: macos-latest + strategy: + matrix: + file: [aapt_64, aapt2_64] + + steps: + - uses: actions/checkout@v2 + + - name: Verify Executable + run: ${{ env.BINARY_PATH }}/macosx/${{ matrix.file }} version + + - name: Output Static + run: otool -L ${{ env.BINARY_PATH }}/macosx/${{ matrix.file }} || true + + analyze-linux-aapt: + runs-on: ubuntu-latest + strategy: + matrix: + file: [aapt, aapt_64, aapt2, aapt2_64] + + steps: + - uses: actions/checkout@v2 + + - name: Verify Executable + run: ${{ env.BINARY_PATH }}/linux/${{ matrix.file }} version + + - name: Output Static + run: ldd ${{ env.BINARY_PATH }}/linux/${{ matrix.file }} || true + + analyze-windows-aapt: + runs-on: windows-latest + strategy: + matrix: + file: [aapt.exe, aapt_64.exe, aapt2.exe, aapt2_64.exe] + + steps: + - uses: actions/checkout@v2 + + - name: Verify Executable + run: ${{ env.BINARY_PATH }}/windows/${{ matrix.file }} version + + - name: Output Static + run: ldd ${{ env.BINARY_PATH }}/windows/${{ matrix.file }} || true + + build-and-test-with-Java-8-and-later: + runs-on: ${{ matrix.os }} + needs: + - analyze-mac-aapt + - analyze-linux-aapt + - analyze-windows-aapt + name: Build/Test (JDK ${{ matrix.java }}, ${{ matrix.os }}) + strategy: + fail-fast: true + matrix: + os: [ ubuntu-latest, macOS-latest, windows-latest ] + java: [ 8, 9, 10, 11, 12, 13, 14, 15, 16 ] + + steps: + - uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ matrix.java }}-${{ hashFiles('**/*.gradle*') }} + restore-keys: ${{ runner.os }}-${{ matrix.java }}-gradle- + + - uses: actions/checkout@v2 + + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v2 + with: + distribution: 'zulu' + java-version: ${{ matrix.java }} + + - name: Build and test + if: startsWith(matrix.os, 'windows') == true + run: ./gradlew.bat build shadowJar proguard + + - name: Build and test + if: startsWith(matrix.os, 'windows') != true + run: ./gradlew build shadowJar proguard + + upload-artifact: + runs-on: ubuntu-latest + name: Build apktool.jar + if: github.repository == 'iBotPeaches/Apktool' && github.ref == 'refs/heads/master' + needs: + - build-and-test-with-Java-8-and-later + + steps: + - uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ matrix.java }}-${{ hashFiles('**/*.gradle*') }} + restore-keys: ${{ runner.os }}-${{ matrix.java }}-gradle- + + - uses: actions/checkout@v2 + + - name: Set up JDK 10 + uses: actions/setup-java@v2 + with: + distribution: 'zulu' + java-version: 10 + + - name: Build + run: ./gradlew build shadowJar proguard + + - name: Upload + uses: actions/upload-artifact@v2 + with: + name: apktool.jar + path: brut.apktool/apktool-cli/build/libs/apktool-*-small.jar + + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'java' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff -Nru apktool-2.5.0+dfsg.1/.github/workflows/codeql-analysis.yml apktool-2.6.1+dfsg.1/.github/workflows/codeql-analysis.yml --- apktool-2.5.0+dfsg.1/.github/workflows/codeql-analysis.yml 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/.github/workflows/codeql-analysis.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [ master ] - paths: - - '**.java' - - '**.gradle' - - 'brut.apktool/apktool-lib/src/main/resources/**' - pull_request: - branches: [ master ] - paths: - - '**.java' - - '**.gradle' - - 'brut.apktool/apktool-lib/src/main/resources/**' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - language: [ 'java' ] - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 diff -Nru apktool-2.5.0+dfsg.1/.github/workflows/test.yml apktool-2.6.1+dfsg.1/.github/workflows/test.yml --- apktool-2.5.0+dfsg.1/.github/workflows/test.yml 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/.github/workflows/test.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -name: CI -on: - push: - paths: - - '**.java' - - '**.gradle' - - 'brut.apktool/apktool-lib/src/main/resources/**' - -jobs: - build-and-test-with-Java-8-and-later: - name: Build/Test (JDK ${{ matrix.java }}, ${{ matrix.os }}) - strategy: - fail-fast: false - max-parallel: 10 - matrix: - os: [ubuntu-latest, macOS-latest, windows-latest] - java: [8, 9, 10, 11, 12, 13, 14] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/cache@v2 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} - restore-keys: | - ${{ runner.os }}-gradle- - - uses: actions/checkout@v2 - - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.java }} - - name: Build and test - run: ./gradlew.bat build shadowJar proguard - if: startsWith(matrix.os, 'windows') == true - - name: Build and test - run: ./gradlew build shadowJar proguard - if: startsWith(matrix.os, 'windows') != true \ No newline at end of file diff -Nru apktool-2.5.0+dfsg.1/.gitignore apktool-2.6.1+dfsg.1/.gitignore --- apktool-2.5.0+dfsg.1/.gitignore 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/.gitignore 2022-04-11 21:08:20.000000000 +0000 @@ -1,6 +1,7 @@ # Gradle .gradle/ bin/ +gradle.properties # Build **/build/ diff -Nru apktool-2.5.0+dfsg.1/gradle/functions.gradle apktool-2.6.1+dfsg.1/gradle/functions.gradle --- apktool-2.5.0+dfsg.1/gradle/functions.gradle 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/gradle/functions.gradle 2022-04-11 21:08:20.000000000 +0000 @@ -1,3 +1,5 @@ +import org.codehaus.groovy.runtime.MethodClosure + /** * Copyright 2014 Ryszard Wiśniewski * @@ -5,7 +7,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,8 +23,8 @@ def head try { head = new File(gitFolder + "HEAD").text.split(":") - } catch(Exception e) { - return null; + } catch(Exception ignored) { + return null } def isCommit = head.length == 1 @@ -38,13 +40,13 @@ def head try { head = new File(gitFolder + "HEAD").text.split("/") - return head[2].trim(); - } catch(Exception e) { - return "SNAPSHOT"; + return head[2].trim() + } catch(Exception ignored) { + return "SNAPSHOT" } } ext { - getCheckedOutGitCommitHash = this.&getCheckedOutGitCommitHash - getCheckedOutBranch = this.&getCheckedOutBranch -} \ No newline at end of file + getCheckedOutGitCommitHash = this.&getCheckedOutGitCommitHash as MethodClosure + getCheckedOutBranch = this.&getCheckedOutBranch as MethodClosure +} diff -Nru apktool-2.5.0+dfsg.1/gradle/wrapper/gradle-wrapper.properties apktool-2.6.1+dfsg.1/gradle/wrapper/gradle-wrapper.properties --- apktool-2.5.0+dfsg.1/gradle/wrapper/gradle-wrapper.properties 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/gradle/wrapper/gradle-wrapper.properties 2022-04-11 21:08:20.000000000 +0000 @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff -Nru apktool-2.5.0+dfsg.1/gradlew apktool-2.6.1+dfsg.1/gradlew --- apktool-2.5.0+dfsg.1/gradlew 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/gradlew 2022-04-11 21:08:20.000000000 +0000 @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,78 +17,113 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -97,7 +132,7 @@ location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -105,84 +140,95 @@ fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff -Nru apktool-2.5.0+dfsg.1/gradlew.bat apktool-2.6.1+dfsg.1/gradlew.bat --- apktool-2.5.0+dfsg.1/gradlew.bat 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/gradlew.bat 2022-04-11 21:08:20.000000000 +0000 @@ -29,6 +29,9 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @@ -37,7 +40,7 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -51,7 +54,7 @@ set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -61,28 +64,14 @@ goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff -Nru apktool-2.5.0+dfsg.1/INTERNAL.md apktool-2.6.1+dfsg.1/INTERNAL.md --- apktool-2.5.0+dfsg.1/INTERNAL.md 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/INTERNAL.md 2022-04-11 21:08:20.000000000 +0000 @@ -42,6 +42,22 @@ git tag -a v2.2.1 -m "changed version to v2.2.1" +### Prepare for publishing. + +New to Apktool is publishing releases to Maven, so plugin authors can directly integrate. You +need a `gradle.properties` file in root with the structure: + +``` +signing.keyId={gpgKeyId} +signing.password={gpgPassphrase} +signing.secretKeyRingFile={gpgSecretKingRingLocation} + +ossrhUsername={sonatypeUsername} +ossrhPassword={sonatypePassword} +``` + +If `release` or `snapshot` is used publishing will be automatically attempted. + ### Building the binary. In order to maintain a clean slate. Run `gradlew clean` to start from a clean slate. Now lets build @@ -93,7 +109,7 @@ 1. [Bitbucket Downloads](https://bitbucket.org/iBotPeaches/apktool/downloads) 2. [Github Releases](https://github.com/iBotPeaches/Apktool/releases) - Since `2.2.1`. -3. [Backup Mirror](http://connortumbleson.com/apktool/) +3. [Backup Mirror](https://connortumbleson.com/apktool/) #### Bitbucket @@ -229,7 +245,7 @@ After that, you need to build AOSP via this [documentation](https://source.android.com/source/building.html) guide. Now we aren't building the entire AOSP package, the initial build is to just see if you are capable of building it. -We check out a certain tag or branch. Currently we use +We check out a certain tag or branch. Currently we use * aapt2 - `master`. * aapt1 - `master`. @@ -250,7 +266,7 @@ #### Linux / Windows 1. `source build/envsetup.sh` 2. `lunch sdk-eng` -3. `make LOCAL_MULTILIB=64 USE_NINJA=false aapt` +3. `m aapt` 4. `strip out/host/linux-x86/bin/aapt` 5. `strip out/host/linux-x86/bin/aapt_64` 6. `strip out/host/windows-x86/bin/aapt.exe` @@ -258,9 +274,8 @@ #### Mac 1. `source build/envsetup.sh` -2. `lunch sdk-eng` -3. `make LOCAL_MULTILIB=64 USE_NINJA=false aapt` -4. `strip out/host/darwin-x86/bin/aapt_64` +2. `m aapt` +3. `strip out/host/darwin-x86/bin/aapt_64` 32/64 bit binaries will be built for Linux and Windows. @@ -269,7 +284,7 @@ The steps below are different per flavor and operating system. #### Linux / Windows -1. `make LOCAL_MULTILIB=64 USE_NINJA=false aapt2` +1. `m aapt2` 2. `strip out/host/linux-x86/bin/aapt2` 3. `strip out/host/linux-x86/bin/aapt2_64` 4. `strip out/host/windows-x86/bin/aapt2.exe` @@ -278,7 +293,7 @@ #### Mac 1. `export ANDROID_JAVA_HOME=/Path/To/Jdk` 2. `source build/envsetup.sh` -3. `make LOCAL_MULTILIB=64 USE_NINJA=false aapt2` +3. `m aapt2` 4. `strip out/host/darwin-x86/bin/aapt2_64` #### Confirming aapt/aapt2 builds are static diff -Nru apktool-2.5.0+dfsg.1/LICENSE apktool-2.6.1+dfsg.1/LICENSE --- apktool-2.5.0+dfsg.1/LICENSE 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/LICENSE 1970-01-01 00:00:00.000000000 +0000 @@ -1,207 +0,0 @@ -Sub projects brut.apktool, brut.j.common, brut.dir and brut.j.util are -released under the following license: - -******************************************************************************* - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -******************************************************************************* \ No newline at end of file diff -Nru apktool-2.5.0+dfsg.1/LICENSE.md apktool-2.6.1+dfsg.1/LICENSE.md --- apktool-2.5.0+dfsg.1/LICENSE.md 1970-01-01 00:00:00.000000000 +0000 +++ apktool-2.6.1+dfsg.1/LICENSE.md 2022-04-11 21:08:20.000000000 +0000 @@ -0,0 +1,190 @@ + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2010 Ryszard Wiśniewski + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff -Nru apktool-2.5.0+dfsg.1/README.md apktool-2.6.1+dfsg.1/README.md --- apktool-2.5.0+dfsg.1/README.md 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/README.md 2022-04-11 21:08:20.000000000 +0000 @@ -2,7 +2,7 @@ **This is the repository for Apktool. If you are looking for the Apktool website. Click [here](https://github.com/iBotPeaches/Apktool/tree/gh-pages).** [![Join the chat at https://gitter.im/iBotPeaches/Apktool](https://badges.gitter.im/iBotPeaches/Apktool.svg)](https://gitter.im/iBotPeaches/Apktool?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://travis-ci.org/iBotPeaches/Apktool.svg?branch=master)](https://travis-ci.org/iBotPeaches/Apktool) +[![CI](https://github.com/iBotPeaches/Apktool/actions/workflows/build.yml/badge.svg)](https://github.com/iBotPeaches/Apktool/actions/workflows/test.yml) [![Software License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](https://github.com/iBotPeaches/Apktool/blob/master/LICENSE) It is a tool for reverse engineering 3rd party, closed, binary Android apps. It can decode resources to nearly original form and rebuild them after making some modifications; it makes possible to debug smali code step by step. Also it makes working with app easier because of project-like files structure and automation of some repetitive tasks like building apk, etc. @@ -10,8 +10,8 @@ It is NOT intended for piracy and other non-legal uses. It could be used for localizing, adding some features or support for custom platforms and other GOOD purposes. Just try to be fair with authors of an app, that you use and probably like. #### Support -- [Project Page](http://ibotpeaches.github.io/Apktool/) -- [#apktool on freenode](http://webchat.freenode.net/?channels=apktool) +- [Project Page](https://ibotpeaches.github.io/Apktool/) +- [#apktool on libera.chat](https://web.libera.chat/) #### Sponsored by @@ -19,7 +19,7 @@ #### IDE of Choice -[![JetBrains IntelliJ](.github/intellij.png?raw=true)](https://www.jetbrains.com/idea/) +* [JetBrains IntelliJ](https://www.jetbrains.com/idea/) #### Security Vulnerabilities @@ -27,13 +27,13 @@ #### Links - [Downloads](https://bitbucket.org/iBotPeaches/apktool/downloads) -- [Downloads Mirror](http://connortumbleson.com/apktool/) -- [How to Build](http://ibotpeaches.github.io/Apktool/build/) -- [Documentation](http://ibotpeaches.github.io/Apktool/documentation/) +- [Downloads Mirror](https://connortumbleson.com/apktool/) +- [How to Build](https://ibotpeaches.github.io/Apktool/build/) +- [Documentation](https://ibotpeaches.github.io/Apktool/documentation/) - [Bug Reports](https://github.com/iBotPeaches/Apktool/issues) - [Chat on Gitter](https://gitter.im/iBotPeaches/Apktool) -- [Changelog/Information](http://ibotpeaches.github.io/Apktool/changes/) -- [XDA Post](http://forum.xda-developers.com/showthread.php?p=28366939) +- [Changelog/Information](https://ibotpeaches.github.io/Apktool/changes/) +- [XDA Post](https://forum.xda-developers.com/t/util-dec-2-2020-apktool-tool-for-reverse-engineering-apk-files.1755243/) - [Source (Github)](https://github.com/iBotPeaches/Apktool) - [Source (Bitbucket)](https://bitbucket.org/iBotPeaches/apktool/) diff -Nru apktool-2.5.0+dfsg.1/ROADMAP.md apktool-2.6.1+dfsg.1/ROADMAP.md --- apktool-2.5.0+dfsg.1/ROADMAP.md 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/ROADMAP.md 2022-04-11 21:08:20.000000000 +0000 @@ -23,20 +23,12 @@ ## Qualifier Plugin System For some OEMs, past and present. They re-use qualifiers that AOSP ends up using. This with CTS is becoming very rare and pretty much a problem of the past, but now custom modifications and more "off the cuff" OEMs are doing -it. +it. Apktool can't do anything because it stays true to AOSP. It would need a plugin system that controls how to read the qualifiers. Or even an override file. -Suggestions: [#1420](https://github.com/iBotPeaches/Apktool/issues/1420) - -## Library System -May like using Apktool outside of the cli tool. We should make it easier to consume, whether via -maven, jitpack, etc. - -Additionally, some documentation on how to do this. - -Suggestions: [#1301](https://github.com/iBotPeaches/Apktool/issues/1301), [#2102](https://github.com/iBotPeaches/Apktool/issues/2102) +Suggestions: [#1420](https://github.com/iBotPeaches/Apktool/issues/1420), [#2474](https://github.com/iBotPeaches/Apktool/issues/2474) ## Non-reference Resources Some applications may shove resources into the /res folder, but have no references to them. Apktool follows @@ -45,4 +37,9 @@ Crawling the filesystem for non-checked files would be slow especially having to cross check with already parsed files. -Suggestions: [#1366](https://github.com/iBotPeaches/Apktool/issues/1366) \ No newline at end of file +Suggestions: [#1366](https://github.com/iBotPeaches/Apktool/issues/1366) + +## Multi-threaded +Applications are getting larger as well as frameworks, but Apktool is getting slower. + +Suggestions: [#2685](https://github.com/iBotPeaches/Apktool/issues/2685) diff -Nru apktool-2.5.0+dfsg.1/scripts/linux/apktool apktool-2.6.1+dfsg.1/scripts/linux/apktool --- apktool-2.5.0+dfsg.1/scripts/linux/apktool 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/scripts/linux/apktool 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -52,7 +52,7 @@ # If you want DX to have more memory when executing, uncomment the following # line and adjust the value accordingly. Use "java -X" for a list of options # you can pass here. -# +# javaOpts="-Xmx512M -Dfile.encoding=utf-8" # Alternatively, this will extract any parameter "-Jxxx" from the command line @@ -74,4 +74,4 @@ # add current location to path for aapt PATH=$PATH:`pwd`; export PATH; -exec java $javaOpts -jar "$jarpath" "$@" \ No newline at end of file +exec java $javaOpts -jar "$jarpath" "$@" diff -Nru apktool-2.5.0+dfsg.1/scripts/osx/apktool apktool-2.6.1+dfsg.1/scripts/osx/apktool --- apktool-2.5.0+dfsg.1/scripts/osx/apktool 2020-12-02 00:04:44.000000000 +0000 +++ apktool-2.6.1+dfsg.1/scripts/osx/apktool 2022-04-11 21:08:20.000000000 +0000 @@ -6,7 +6,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -52,7 +52,7 @@ # If you want DX to have more memory when executing, uncomment the following # line and adjust the value accordingly. Use "java -X" for a list of options # you can pass here. -# +# javaOpts="-Xmx512M -Dfile.encoding=utf-8" # Alternatively, this will extract any parameter "-Jxxx" from the command line @@ -74,4 +74,4 @@ # add current location to path for aapt PATH=$PATH:`pwd`; export PATH; -exec java $javaOpts -Djava.awt.headless=true -jar "$jarpath" "$@" \ No newline at end of file +exec java $javaOpts -Djava.awt.headless=true -jar "$jarpath" "$@"