Skip to content

Commit 55e79fb

Browse files
committed
fix(res): use safe number parsing for android manifest, refactor params object (skylot#2857)
1 parent 044c75a commit 55e79fb

4 files changed

Lines changed: 112 additions & 76 deletions

File tree

jadx-core/src/main/java/jadx/core/export/gen/AndroidGradleGenerator.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ public class AndroidGradleGenerator implements IExportGradleGenerator {
3131
private static final Logger LOG = LoggerFactory.getLogger(AndroidGradleGenerator.class);
3232
private static final Pattern ILLEGAL_GRADLE_CHARS = Pattern.compile("[/\\\\:>\"?*|]");
3333

34-
private static final ApplicationParams UNKNOWN_APP_PARAMS =
35-
new ApplicationParams("UNKNOWN", 0, 0, 0, 0, "UNKNOWN", "UNKNOWN", "UNKNOWN");
36-
3734
private final RootNode root;
3835
private final File projectDir;
3936
private final List<ResourceFile> resources;
@@ -83,8 +80,8 @@ private ApplicationParams parseApplicationParams() {
8380
try {
8481
ResourceFile androidManifest = AndroidManifestParser.getAndroidManifest(resources);
8582
if (androidManifest == null) {
86-
LOG.warn("AndroidManifest.xml not found, exported files will contains 'UNKNOWN' fields");
87-
return UNKNOWN_APP_PARAMS;
83+
LOG.warn("AndroidManifest.xml not found, exported files will contains 'null' fields");
84+
return new ApplicationParams();
8885
}
8986
ResContainer strings = null;
9087
if (exportApp) {
@@ -118,7 +115,7 @@ private ApplicationParams parseApplicationParams() {
118115
return parser.parse();
119116
} catch (Exception t) {
120117
LOG.warn("Failed to parse AndroidManifest.xml", t);
121-
return UNKNOWN_APP_PARAMS;
118+
return new ApplicationParams();
122119
}
123120
}
124121

@@ -143,7 +140,7 @@ private void saveProjectBuildGradle() throws IOException {
143140

144141
private void saveSettingsGradle() throws IOException {
145142
TemplateFile tmpl = TemplateFile.fromResources("/export/android/settings.gradle.tmpl");
146-
String appName = applicationParams.getApplicationName();
143+
String appName = applicationParams.getApplicationLabel();
147144
String projectName;
148145
if (appName != null) {
149146
projectName = ILLEGAL_GRADLE_CHARS.matcher(appName).replaceAll("");

jadx-core/src/main/java/jadx/core/utils/Utils.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,4 +672,26 @@ public static int getEnvVarInt(String varName, int defValue) {
672672
}
673673
return Integer.parseInt(strValue);
674674
}
675+
676+
public static int safeParseInt(String value, int defValue) {
677+
if (value == null || value.isEmpty()) {
678+
return defValue;
679+
}
680+
try {
681+
return Integer.parseInt(value);
682+
} catch (Exception e) {
683+
return defValue;
684+
}
685+
}
686+
687+
public static @Nullable Integer safeParseInteger(@Nullable String value) {
688+
if (value == null || value.isEmpty()) {
689+
return null;
690+
}
691+
try {
692+
return Integer.parseInt(value);
693+
} catch (Exception e) {
694+
return null;
695+
}
696+
}
675697
}

jadx-core/src/main/java/jadx/core/utils/android/AndroidManifestParser.java

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import jadx.core.utils.exceptions.JadxRuntimeException;
1919
import jadx.core.xmlgen.ResContainer;
2020

21+
import static jadx.core.utils.Utils.safeParseInteger;
22+
2123
public class AndroidManifestParser {
2224
private final Document androidManifest;
2325
private final @Nullable Document appStrings;
@@ -41,8 +43,7 @@ public boolean isManifestFound() {
4143
return androidManifest != null;
4244
}
4345

44-
@Nullable
45-
public static ResourceFile getAndroidManifest(List<ResourceFile> resources) {
46+
public static @Nullable ResourceFile getAndroidManifest(List<ResourceFile> resources) {
4647
return resources.stream()
4748
.filter(resourceFile -> resourceFile.getType() == ResourceType.MANIFEST)
4849
.findFirst()
@@ -53,69 +54,59 @@ public ApplicationParams parse() {
5354
if (!isManifestFound()) {
5455
throw new JadxRuntimeException("AndroidManifest.xml is missing");
5556
}
56-
5757
return parseAttributes();
5858
}
5959

6060
private ApplicationParams parseAttributes() {
61-
String applicationLabel = null;
62-
Integer minSdkVersion = null;
63-
Integer targetSdkVersion = null;
64-
Integer compileSdkVersion = null;
65-
Integer versionCode = null;
66-
String versionName = null;
67-
String mainActivity = null;
68-
String application = null;
61+
ApplicationParams appParams = new ApplicationParams();
6962

7063
@Nullable
7164
Element manifest = (Element) androidManifest.getElementsByTagName("manifest").item(0);
7265
@Nullable
7366
Element usesSdk = (Element) androidManifest.getElementsByTagName("uses-sdk").item(0);
7467

7568
if (parseAttrs.contains(AppAttribute.APPLICATION_LABEL)) {
76-
applicationLabel = getApplicationLabel();
69+
appParams.setApplicationLabel(getApplicationLabel());
7770
}
7871
if (usesSdk != null) {
7972
if (parseAttrs.contains(AppAttribute.MIN_SDK_VERSION)) {
80-
minSdkVersion = Integer.valueOf(usesSdk.getAttribute("android:minSdkVersion"));
73+
appParams.setMinSdkVersion(safeParseInteger(usesSdk.getAttribute("android:minSdkVersion")));
8174
}
8275
if (parseAttrs.contains(AppAttribute.TARGET_SDK_VERSION)) {
8376
String stringTargetSdk = usesSdk.getAttribute("android:targetSdkVersion");
8477
if (!stringTargetSdk.isEmpty()) {
85-
targetSdkVersion = Integer.valueOf(stringTargetSdk);
78+
appParams.setTargetSdkVersion(safeParseInteger(stringTargetSdk));
8679
} else {
87-
if (minSdkVersion == null) {
88-
minSdkVersion = Integer.valueOf(usesSdk.getAttribute("android:minSdkVersion"));
80+
if (appParams.getMinSdkVersion() == null) {
81+
appParams.setMinSdkVersion(safeParseInteger(usesSdk.getAttribute("android:minSdkVersion")));
8982
}
90-
targetSdkVersion = minSdkVersion;
83+
appParams.setTargetSdkVersion(appParams.getMinSdkVersion());
9184
}
9285
}
9386
if (parseAttrs.contains(AppAttribute.COMPILE_SDK_VERSION)) {
9487
String stringCompileSdk = usesSdk.getAttribute("android:compileSdkVersion");
9588
if (!stringCompileSdk.isEmpty()) {
96-
compileSdkVersion = Integer.valueOf(stringCompileSdk);
89+
appParams.setCompileSdkVersion(safeParseInteger(stringCompileSdk));
9790
} else {
98-
compileSdkVersion = targetSdkVersion;
91+
appParams.setCompileSdkVersion(appParams.getTargetSdkVersion());
9992
}
10093
}
10194
}
10295
if (manifest != null) {
10396
if (parseAttrs.contains(AppAttribute.VERSION_CODE)) {
104-
versionCode = Integer.valueOf(manifest.getAttribute("android:versionCode"));
97+
appParams.setVersionCode(safeParseInteger(manifest.getAttribute("android:versionCode")));
10598
}
10699
if (parseAttrs.contains(AppAttribute.VERSION_NAME)) {
107-
versionName = manifest.getAttribute("android:versionName");
100+
appParams.setVersionName(manifest.getAttribute("android:versionName"));
108101
}
109102
}
110103
if (parseAttrs.contains(AppAttribute.MAIN_ACTIVITY)) {
111-
mainActivity = getMainActivityName();
104+
appParams.setMainActivity(getMainActivityName());
112105
}
113106
if (parseAttrs.contains(AppAttribute.APPLICATION)) {
114-
application = getApplicationName();
107+
appParams.setApplication(getApplicationName());
115108
}
116-
117-
return new ApplicationParams(applicationLabel, minSdkVersion, targetSdkVersion, compileSdkVersion,
118-
versionCode, versionName, mainActivity, application);
109+
return appParams;
119110
}
120111

121112
private String getApplicationLabel() {
@@ -143,27 +134,26 @@ private String getApplicationLabel() {
143134
return appLabelName;
144135
}
145136
}
146-
147137
return "UNKNOWN";
148138
}
149139

150-
private String getMainActivityName() {
140+
private @Nullable String getMainActivityName() {
151141
String mainActivityName = getMainActivityNameThroughActivityTag();
152142
if (mainActivityName == null) {
153143
mainActivityName = getMainActivityNameThroughActivityAliasTag();
154144
}
155145
return mainActivityName;
156146
}
157147

158-
private String getApplicationName() {
148+
private @Nullable String getApplicationName() {
159149
Element application = (Element) androidManifest.getElementsByTagName("application").item(0);
160150
if (application.hasAttribute("android:name")) {
161151
return application.getAttribute("android:name");
162152
}
163153
return null;
164154
}
165155

166-
private String getMainActivityNameThroughActivityAliasTag() {
156+
private @Nullable String getMainActivityNameThroughActivityAliasTag() {
167157
NodeList activityAliasNodes = androidManifest.getElementsByTagName("activity-alias");
168158
for (int i = 0; i < activityAliasNodes.getLength(); i++) {
169159
Element activityElement = (Element) activityAliasNodes.item(i);
@@ -174,7 +164,7 @@ private String getMainActivityNameThroughActivityAliasTag() {
174164
return null;
175165
}
176166

177-
private String getMainActivityNameThroughActivityTag() {
167+
private @Nullable String getMainActivityNameThroughActivityTag() {
178168
NodeList activityNodes = androidManifest.getElementsByTagName("activity");
179169
for (int i = 0; i < activityNodes.getLength(); i++) {
180170
Element activityElement = (Element) activityNodes.item(i);
@@ -230,15 +220,15 @@ private Document parseXml(String xmlContent) {
230220
}
231221
}
232222

233-
private Document parseAppStrings(ResContainer appStrings) {
223+
private @Nullable Document parseAppStrings(@Nullable ResContainer appStrings) {
234224
if (appStrings == null) {
235225
return null;
236226
}
237227
String content = appStrings.getText().getCodeStr();
238228
return parseXml(content);
239229
}
240230

241-
private Document parseAndroidManifest(ResourceFile androidManifest) {
231+
private @Nullable Document parseAndroidManifest(ResourceFile androidManifest) {
242232
if (androidManifest == null) {
243233
return null;
244234
}
Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,95 @@
11
package jadx.core.utils.android;
22

3+
import org.jetbrains.annotations.Nullable;
4+
35
import jadx.api.JadxDecompiler;
46
import jadx.api.JavaClass;
57

68
public class ApplicationParams {
9+
private @Nullable String applicationLabel;
10+
private @Nullable Integer minSdkVersion;
11+
private @Nullable Integer targetSdkVersion;
12+
private @Nullable Integer compileSdkVersion;
13+
private @Nullable Integer versionCode;
14+
private @Nullable String versionName;
15+
private @Nullable String mainActivity;
16+
private @Nullable String application;
717

8-
private final String applicationLabel;
9-
private final Integer minSdkVersion;
10-
private final Integer targetSdkVersion;
11-
private final Integer compileSdkVersion;
12-
private final Integer versionCode;
13-
private final String versionName;
14-
private final String mainActivity;
15-
private final String application;
16-
17-
public ApplicationParams(String applicationLabel, Integer minSdkVersion, Integer targetSdkVersion, Integer compileSdkVersion,
18-
Integer versionCode, String versionName, String mainActivity, String application) {
19-
this.applicationLabel = applicationLabel;
20-
this.minSdkVersion = minSdkVersion;
21-
this.targetSdkVersion = targetSdkVersion;
22-
this.compileSdkVersion = compileSdkVersion;
23-
this.versionCode = versionCode;
24-
this.versionName = versionName;
25-
this.mainActivity = mainActivity;
18+
public @Nullable String getApplication() {
19+
return application;
20+
}
21+
22+
public void setApplication(@Nullable String application) {
2623
this.application = application;
2724
}
2825

29-
public String getApplicationName() {
26+
public @Nullable JavaClass getApplicationJavaClass(JadxDecompiler decompiler) {
27+
if (application == null) {
28+
return null;
29+
}
30+
return decompiler.searchJavaClassByAliasFullName(application);
31+
}
32+
33+
public @Nullable String getApplicationLabel() {
3034
return applicationLabel;
3135
}
3236

33-
public Integer getMinSdkVersion() {
34-
return minSdkVersion;
37+
public void setApplicationLabel(@Nullable String applicationLabel) {
38+
this.applicationLabel = applicationLabel;
3539
}
3640

37-
public Integer getTargetSdkVersion() {
38-
return targetSdkVersion;
41+
public @Nullable String getMainActivity() {
42+
return mainActivity;
3943
}
4044

41-
public Integer getCompileSdkVersion() {
45+
public void setMainActivity(@Nullable String mainActivity) {
46+
this.mainActivity = mainActivity;
47+
}
48+
49+
public @Nullable JavaClass getMainActivityJavaClass(JadxDecompiler decompiler) {
50+
if (mainActivity == null) {
51+
return null;
52+
}
53+
return decompiler.searchJavaClassByAliasFullName(mainActivity);
54+
}
55+
56+
public @Nullable Integer getCompileSdkVersion() {
4257
return compileSdkVersion;
4358
}
4459

45-
public Integer getVersionCode() {
46-
return versionCode;
60+
public void setCompileSdkVersion(@Nullable Integer compileSdkVersion) {
61+
this.compileSdkVersion = compileSdkVersion;
4762
}
4863

49-
public String getVersionName() {
50-
return versionName;
64+
public @Nullable Integer getMinSdkVersion() {
65+
return minSdkVersion;
5166
}
5267

53-
public String getMainActivity() {
54-
return mainActivity;
68+
public void setMinSdkVersion(@Nullable Integer minSdkVersion) {
69+
this.minSdkVersion = minSdkVersion;
5570
}
5671

57-
public JavaClass getMainActivityJavaClass(JadxDecompiler decompiler) {
58-
return decompiler.searchJavaClassByAliasFullName(mainActivity);
72+
public @Nullable Integer getTargetSdkVersion() {
73+
return targetSdkVersion;
5974
}
6075

61-
public String getApplication() {
62-
return application;
76+
public void setTargetSdkVersion(@Nullable Integer targetSdkVersion) {
77+
this.targetSdkVersion = targetSdkVersion;
6378
}
6479

65-
public JavaClass getApplicationJavaClass(JadxDecompiler decompiler) {
66-
return decompiler.searchJavaClassByAliasFullName(application);
80+
public @Nullable Integer getVersionCode() {
81+
return versionCode;
82+
}
83+
84+
public void setVersionCode(@Nullable Integer versionCode) {
85+
this.versionCode = versionCode;
86+
}
87+
88+
public @Nullable String getVersionName() {
89+
return versionName;
90+
}
91+
92+
public void setVersionName(@Nullable String versionName) {
93+
this.versionName = versionName;
6794
}
6895
}

0 commit comments

Comments
 (0)