From ca07a0a56cd0ce3418151c8ddc296625f7200026 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 20 Jul 2023 05:37:46 -0400 Subject: [PATCH] Fix regressions towards apktool.yml generation (#3172) * fix: prevent blowing out minSdkVersion * fix: correct naming regression with apk name and sdk info * chore: comment for why we double up minSdkVersion * fix: deprecate compressionType * test: assert apktool format isn't regressed --- .../main/java/brut/androlib/ApkDecoder.java | 10 +-- .../main/java/brut/androlib/apk/ApkInfo.java | 27 +++++--- .../androlib/yaml/ConsistentPropertyTest.java | 66 +++++++++++++++++++ .../resources/decode/yaml/basic/apktool.yml | 26 ++++++++ 4 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/ConsistentPropertyTest.java create mode 100644 brut.apktool/apktool-lib/src/test/resources/decode/yaml/basic/apktool.yml diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java index bbd59f89f2..36070cf302 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java @@ -132,9 +132,11 @@ public void decode(File outDir) throws AndrolibException, IOException, Directory } } } + + // In case we have no resources. We should store the minSdk we pulled from the source opcode api level ApkInfo apkInfo = resourcesDecoder.getApkInfo(); if (mMinSdkVersion > 0) { - apkInfo.setSdkInfo(getMinSdkInfo()); + apkInfo.setSdkInfoField("minSdkVersion", Integer.toString(mMinSdkVersion)); } copyRawFiles(outDir); @@ -183,12 +185,6 @@ private void writeApkInfo(ApkInfo apkInfo, File outDir) throws AndrolibException } } - private Map getMinSdkInfo() { - Map sdkInfo = new LinkedHashMap<>(); - sdkInfo.put("minSdkVersion", Integer.toString(mMinSdkVersion)); - return sdkInfo; - } - private void copySourcesRaw(File outDir, String filename) throws AndrolibException { try { diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java index d2abbac687..4ec70c23eb 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java @@ -35,10 +35,10 @@ public class ApkInfo { public String version; - private String mApkFileName; + private String apkFileName; public boolean isFrameworkApk; public UsesFramework usesFramework; - private Map mSdkInfo = new LinkedHashMap<>(); + private Map sdkInfo = new LinkedHashMap<>(); public PackageInfo packageInfo = new PackageInfo(); public VersionInfo versionInfo = new VersionInfo(); public boolean resourcesAreCompressed; @@ -47,6 +47,9 @@ public class ApkInfo { public Map unknownFiles; public Collection doNotCompress; + /** @deprecated use {@link #resourcesAreCompressed} */ + public boolean compressionType; + public ApkInfo() { this.version = ApktoolProperties.getVersion(); } @@ -83,38 +86,42 @@ public String checkTargetSdkVersionBounds() { } public String getApkFileName() { - return mApkFileName; + return apkFileName; } public void setApkFileName(String apkFileName) { - mApkFileName = apkFileName; + this.apkFileName = apkFileName; } public Map getSdkInfo() { - return mSdkInfo; + return sdkInfo; } public void setSdkInfo(Map sdkInfo) { - mSdkInfo = sdkInfo; + this.sdkInfo = sdkInfo; + } + + public void setSdkInfoField(String key, String value) { + sdkInfo.put(key, value); } public String getMinSdkVersion() { - return mSdkInfo.get("minSdkVersion"); + return sdkInfo.get("minSdkVersion"); } public String getMaxSdkVersion() { - return mSdkInfo.get("maxSdkVersion"); + return sdkInfo.get("maxSdkVersion"); } public String getTargetSdkVersion() { - return mSdkInfo.get("targetSdkVersion"); + return sdkInfo.get("targetSdkVersion"); } public int getMinSdkVersionFromAndroidCodename(String sdkVersion) { int sdkNumber = mapSdkShorthandToVersion(sdkVersion); if (sdkNumber == ResConfigFlags.SDK_BASE) { - return Integer.parseInt(mSdkInfo.get("minSdkVersion")); + return Integer.parseInt(sdkInfo.get("minSdkVersion")); } return sdkNumber; } diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/ConsistentPropertyTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/ConsistentPropertyTest.java new file mode 100644 index 0000000000..618b5ba75c --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/ConsistentPropertyTest.java @@ -0,0 +1,66 @@ +/* + * 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.BaseTest; +import brut.androlib.TestUtils; +import brut.androlib.apk.ApkInfo; +import brut.common.BrutException; +import brut.directory.ExtFile; +import brut.util.OS; +import org.junit.BeforeClass; +import org.junit.Test; +import java.io.File; + +import static org.junit.Assert.*; + +public class ConsistentPropertyTest extends BaseTest { + + @BeforeClass + public static void beforeClass() throws Exception { + TestUtils.cleanFrameworkFile(); + + sTmpDir = new ExtFile(OS.createTempDirectory()); + sTestNewDir = new ExtFile(sTmpDir, "yaml"); + LOGGER.info("Unpacking yaml files..."); + TestUtils.copyResourceDir(ConsistentPropertyTest.class, "decode/yaml/", sTestNewDir); + } + + @Test + public void testAssertingAllKnownApkInfoProperties() throws BrutException { + ApkInfo apkInfo = ApkInfo.load(new File(sTestNewDir, "basic")); + + assertEquals("2.8.0", apkInfo.version); + assertEquals("basic.apk", apkInfo.getApkFileName()); + assertFalse(apkInfo.isFrameworkApk); + assertEquals(1, apkInfo.usesFramework.ids.size()); + assertEquals("tag", apkInfo.usesFramework.tag); + assertEquals("4", apkInfo.getMinSdkVersion()); + assertEquals("22", apkInfo.getTargetSdkVersion()); + assertEquals("30", apkInfo.getMaxSdkVersion()); + assertEquals("127", apkInfo.packageInfo.forcedPackageId); + assertEquals("com.test.basic", apkInfo.packageInfo.renameManifestPackage); + assertEquals("71", apkInfo.versionInfo.versionCode); + assertEquals("1.0.70", apkInfo.versionInfo.versionName); + assertFalse(apkInfo.resourcesAreCompressed); + assertFalse(apkInfo.sharedLibrary); + assertTrue(apkInfo.sparseResources); + assertEquals(1, apkInfo.unknownFiles.size()); + assertEquals(2, apkInfo.doNotCompress.size()); + assertFalse(apkInfo.compressionType); + } +} diff --git a/brut.apktool/apktool-lib/src/test/resources/decode/yaml/basic/apktool.yml b/brut.apktool/apktool-lib/src/test/resources/decode/yaml/basic/apktool.yml new file mode 100644 index 0000000000..b51612c6bd --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/decode/yaml/basic/apktool.yml @@ -0,0 +1,26 @@ +!!brut.androlib.meta.MetaInfo +apkFileName: basic.apk +compressionType: false +doNotCompress: + - resources.arsc + - png +isFrameworkApk: false +packageInfo: + forcedPackageId: '127' + renameManifestPackage: 'com.test.basic' +sdkInfo: + minSdkVersion: '4' + maxSdkVersion: '30' + targetSdkVersion: '22' +sharedLibrary: false +sparseResources: true +unknownFiles: + hidden.file: 1 +usesFramework: + ids: + - 1 + tag: 'tag' +version: 2.8.0 +versionInfo: + versionCode: '71' + versionName: 1.0.70