Skip to content
This repository has been archived by the owner on Sep 21, 2020. It is now read-only.

Bug: when parsing APK that requires split APKs, it doesn't set "isSplitRequired" to true #119

Open
AndroidDeveloperLB opened this issue Apr 10, 2020 · 1 comment

Comments

@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Apr 10, 2020

v2.6.10

I've now tested YouTube APK, and it seems that even though in the manifest XML content that it gets, I can see android:isSplitRequired="true" , when checking the apkMeta instance, it's actually false.

If you wish, this is the manifest XML content taken from it:

youtube manifest.zip

And attached here the APK that I've tested on:

youtube base.zip

Tested on Android 9, library v 2.6.10

@AndroidDeveloperLB
Copy link
Author

AndroidDeveloperLB commented Apr 10, 2020

Took me time, but I think I know where it occurs. Just don't know why.

Seems that in BinaryXmlParser.readXmlNodeStartTag , it goes over the attributes of the "manifest" tag to search for "isSplitRequired", but the library actually puts this attribute into the "application" tag instead:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1511902656" android:versionName="15.14.33" android:compileSdkVersion="29" android:compileSdkVersionCodename="R" package="com.google.android.youtube" platformBuildVersionCode="29" platformBuildVersionName="R">
	<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29" />
...
	<application android:theme="resourceId:0x7f140408" android:label="YouTube" android:icon="res/CGK.png" android:name="com.google.android.apps.youtube.app.YouTubeApplication" android:backupAgent="com.google.android.apps.youtube.app.application.backup.YouTubeBackupAgent" android:allowBackup="true" android:restoreAnyVersion="true" android:logo="res/d8V.png" android:hardwareAccelerated="true" android:largeHeap="true" android:supportsRtl="true" android:networkSecurityConfig="res/4uC.xml" android:roundIcon="res/C9M.png" android:isSplitRequired="true" android:requestLegacyExternalStorage="true">

For comparison, this is the whole manifest of a split APK file, that I get from the library:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1511902656" configForSplit="" package="com.google.android.youtube" split="config.armeabi_v7a">
	<application android:hasCode="false">
		<meta-data android:name="com.android.vending.derived.apk.id" android:value="1" />
	</application>
</manifest>

Here I can see the "split" attribute in the "manifest" tag.

The parsing is correct : it's supposed to be in the "manifest" tag. But for some reason it didn't get there, but into the "application" tag instead.
Seems there might be other such attributes to moved from one place to another, too.
So, either the parsing need to be flexible and check on both, or that before, there is some bug causing it.

However, if you run these online tools, for example, you will notice that it's going into the "application" tag, too:
https://www.sisik.eu/apk-tool
http://www.javadecompilers.com/

So, for now, a workaround is as such:

        switch (xmlNodeStartTag.getName()) {
            case "application":
                if (apkMetaBuilder.split == null)
                    apkMetaBuilder.setSplit(attributes.getString("split"));
                if (apkMetaBuilder.configForSplit == null)
                    apkMetaBuilder.setConfigForSplit(attributes.getString("configForSplit"));
                if (!apkMetaBuilder.isFeatureSplit)
                    apkMetaBuilder.setIsFeatureSplit(attributes.getBoolean("isFeatureSplit", false));
                if (!apkMetaBuilder.isSplitRequired)
                    apkMetaBuilder.setIsSplitRequired(attributes.getBoolean("isSplitRequired", false));
                if (!apkMetaBuilder.isolatedSplits)
                    apkMetaBuilder.setIsolatedSplits(attributes.getBoolean("isolatedSplits", false));
...
            case "manifest":
                apkMetaBuilder.setPackageName(attributes.getString("package"));
                apkMetaBuilder.setVersionName(attributes.getString("versionName"));
                apkMetaBuilder.setRevisionCode(attributes.getLong("revisionCode"));
                apkMetaBuilder.setSharedUserId(attributes.getString("sharedUserId"));
                apkMetaBuilder.setSharedUserLabel(attributes.getString("sharedUserLabel"));
                if (apkMetaBuilder.split == null)
                    apkMetaBuilder.setSplit(attributes.getString("split"));
                if (apkMetaBuilder.configForSplit == null)
                    apkMetaBuilder.setConfigForSplit(attributes.getString("configForSplit"));
                if (!apkMetaBuilder.isFeatureSplit)
                    apkMetaBuilder.setIsFeatureSplit(attributes.getBoolean("isFeatureSplit", false));
                if (!apkMetaBuilder.isSplitRequired)
                    apkMetaBuilder.setIsSplitRequired(attributes.getBoolean("isSplitRequired", false));
                if (!apkMetaBuilder.isolatedSplits)
                    apkMetaBuilder.setIsolatedSplits(attributes.getBoolean("isolatedSplits", false));

The reason is that I suspect the split attributes might appear in either of those.

Here's a sample project to test on Android with the workaround :

https://github.com/AndroidDeveloperLB/apk-parser

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant