fix(res): use safe number parsing for android manifest, refactor params object (#2857)
This commit is contained in:
@@ -31,9 +31,6 @@ public class AndroidGradleGenerator implements IExportGradleGenerator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AndroidGradleGenerator.class);
|
||||
private static final Pattern ILLEGAL_GRADLE_CHARS = Pattern.compile("[/\\\\:>\"?*|]");
|
||||
|
||||
private static final ApplicationParams UNKNOWN_APP_PARAMS =
|
||||
new ApplicationParams("UNKNOWN", 0, 0, 0, 0, "UNKNOWN", "UNKNOWN", "UNKNOWN");
|
||||
|
||||
private final RootNode root;
|
||||
private final File projectDir;
|
||||
private final List<ResourceFile> resources;
|
||||
@@ -83,8 +80,8 @@ public class AndroidGradleGenerator implements IExportGradleGenerator {
|
||||
try {
|
||||
ResourceFile androidManifest = AndroidManifestParser.getAndroidManifest(resources);
|
||||
if (androidManifest == null) {
|
||||
LOG.warn("AndroidManifest.xml not found, exported files will contains 'UNKNOWN' fields");
|
||||
return UNKNOWN_APP_PARAMS;
|
||||
LOG.warn("AndroidManifest.xml not found, exported files will contains 'null' fields");
|
||||
return new ApplicationParams();
|
||||
}
|
||||
ResContainer strings = null;
|
||||
if (exportApp) {
|
||||
@@ -118,7 +115,7 @@ public class AndroidGradleGenerator implements IExportGradleGenerator {
|
||||
return parser.parse();
|
||||
} catch (Exception t) {
|
||||
LOG.warn("Failed to parse AndroidManifest.xml", t);
|
||||
return UNKNOWN_APP_PARAMS;
|
||||
return new ApplicationParams();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +140,7 @@ public class AndroidGradleGenerator implements IExportGradleGenerator {
|
||||
|
||||
private void saveSettingsGradle() throws IOException {
|
||||
TemplateFile tmpl = TemplateFile.fromResources("/export/android/settings.gradle.tmpl");
|
||||
String appName = applicationParams.getApplicationName();
|
||||
String appName = applicationParams.getApplicationLabel();
|
||||
String projectName;
|
||||
if (appName != null) {
|
||||
projectName = ILLEGAL_GRADLE_CHARS.matcher(appName).replaceAll("");
|
||||
|
||||
@@ -672,4 +672,26 @@ public class Utils {
|
||||
}
|
||||
return Integer.parseInt(strValue);
|
||||
}
|
||||
|
||||
public static int safeParseInt(String value, int defValue) {
|
||||
if (value == null || value.isEmpty()) {
|
||||
return defValue;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (Exception e) {
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable Integer safeParseInteger(@Nullable String value) {
|
||||
if (value == null || value.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ import jadx.api.security.IJadxSecurity;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
import jadx.core.xmlgen.ResContainer;
|
||||
|
||||
import static jadx.core.utils.Utils.safeParseInteger;
|
||||
|
||||
public class AndroidManifestParser {
|
||||
private final Document androidManifest;
|
||||
private final @Nullable Document appStrings;
|
||||
@@ -41,8 +43,7 @@ public class AndroidManifestParser {
|
||||
return androidManifest != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ResourceFile getAndroidManifest(List<ResourceFile> resources) {
|
||||
public static @Nullable ResourceFile getAndroidManifest(List<ResourceFile> resources) {
|
||||
return resources.stream()
|
||||
.filter(resourceFile -> resourceFile.getType() == ResourceType.MANIFEST)
|
||||
.findFirst()
|
||||
@@ -53,19 +54,11 @@ public class AndroidManifestParser {
|
||||
if (!isManifestFound()) {
|
||||
throw new JadxRuntimeException("AndroidManifest.xml is missing");
|
||||
}
|
||||
|
||||
return parseAttributes();
|
||||
}
|
||||
|
||||
private ApplicationParams parseAttributes() {
|
||||
String applicationLabel = null;
|
||||
Integer minSdkVersion = null;
|
||||
Integer targetSdkVersion = null;
|
||||
Integer compileSdkVersion = null;
|
||||
Integer versionCode = null;
|
||||
String versionName = null;
|
||||
String mainActivity = null;
|
||||
String application = null;
|
||||
ApplicationParams appParams = new ApplicationParams();
|
||||
|
||||
@Nullable
|
||||
Element manifest = (Element) androidManifest.getElementsByTagName("manifest").item(0);
|
||||
@@ -73,49 +66,47 @@ public class AndroidManifestParser {
|
||||
Element usesSdk = (Element) androidManifest.getElementsByTagName("uses-sdk").item(0);
|
||||
|
||||
if (parseAttrs.contains(AppAttribute.APPLICATION_LABEL)) {
|
||||
applicationLabel = getApplicationLabel();
|
||||
appParams.setApplicationLabel(getApplicationLabel());
|
||||
}
|
||||
if (usesSdk != null) {
|
||||
if (parseAttrs.contains(AppAttribute.MIN_SDK_VERSION)) {
|
||||
minSdkVersion = Integer.valueOf(usesSdk.getAttribute("android:minSdkVersion"));
|
||||
appParams.setMinSdkVersion(safeParseInteger(usesSdk.getAttribute("android:minSdkVersion")));
|
||||
}
|
||||
if (parseAttrs.contains(AppAttribute.TARGET_SDK_VERSION)) {
|
||||
String stringTargetSdk = usesSdk.getAttribute("android:targetSdkVersion");
|
||||
if (!stringTargetSdk.isEmpty()) {
|
||||
targetSdkVersion = Integer.valueOf(stringTargetSdk);
|
||||
appParams.setTargetSdkVersion(safeParseInteger(stringTargetSdk));
|
||||
} else {
|
||||
if (minSdkVersion == null) {
|
||||
minSdkVersion = Integer.valueOf(usesSdk.getAttribute("android:minSdkVersion"));
|
||||
if (appParams.getMinSdkVersion() == null) {
|
||||
appParams.setMinSdkVersion(safeParseInteger(usesSdk.getAttribute("android:minSdkVersion")));
|
||||
}
|
||||
targetSdkVersion = minSdkVersion;
|
||||
appParams.setTargetSdkVersion(appParams.getMinSdkVersion());
|
||||
}
|
||||
}
|
||||
if (parseAttrs.contains(AppAttribute.COMPILE_SDK_VERSION)) {
|
||||
String stringCompileSdk = usesSdk.getAttribute("android:compileSdkVersion");
|
||||
if (!stringCompileSdk.isEmpty()) {
|
||||
compileSdkVersion = Integer.valueOf(stringCompileSdk);
|
||||
appParams.setCompileSdkVersion(safeParseInteger(stringCompileSdk));
|
||||
} else {
|
||||
compileSdkVersion = targetSdkVersion;
|
||||
appParams.setCompileSdkVersion(appParams.getTargetSdkVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (manifest != null) {
|
||||
if (parseAttrs.contains(AppAttribute.VERSION_CODE)) {
|
||||
versionCode = Integer.valueOf(manifest.getAttribute("android:versionCode"));
|
||||
appParams.setVersionCode(safeParseInteger(manifest.getAttribute("android:versionCode")));
|
||||
}
|
||||
if (parseAttrs.contains(AppAttribute.VERSION_NAME)) {
|
||||
versionName = manifest.getAttribute("android:versionName");
|
||||
appParams.setVersionName(manifest.getAttribute("android:versionName"));
|
||||
}
|
||||
}
|
||||
if (parseAttrs.contains(AppAttribute.MAIN_ACTIVITY)) {
|
||||
mainActivity = getMainActivityName();
|
||||
appParams.setMainActivity(getMainActivityName());
|
||||
}
|
||||
if (parseAttrs.contains(AppAttribute.APPLICATION)) {
|
||||
application = getApplicationName();
|
||||
appParams.setApplication(getApplicationName());
|
||||
}
|
||||
|
||||
return new ApplicationParams(applicationLabel, minSdkVersion, targetSdkVersion, compileSdkVersion,
|
||||
versionCode, versionName, mainActivity, application);
|
||||
return appParams;
|
||||
}
|
||||
|
||||
private String getApplicationLabel() {
|
||||
@@ -143,11 +134,10 @@ public class AndroidManifestParser {
|
||||
return appLabelName;
|
||||
}
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
private String getMainActivityName() {
|
||||
private @Nullable String getMainActivityName() {
|
||||
String mainActivityName = getMainActivityNameThroughActivityTag();
|
||||
if (mainActivityName == null) {
|
||||
mainActivityName = getMainActivityNameThroughActivityAliasTag();
|
||||
@@ -155,7 +145,7 @@ public class AndroidManifestParser {
|
||||
return mainActivityName;
|
||||
}
|
||||
|
||||
private String getApplicationName() {
|
||||
private @Nullable String getApplicationName() {
|
||||
Element application = (Element) androidManifest.getElementsByTagName("application").item(0);
|
||||
if (application.hasAttribute("android:name")) {
|
||||
return application.getAttribute("android:name");
|
||||
@@ -163,7 +153,7 @@ public class AndroidManifestParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getMainActivityNameThroughActivityAliasTag() {
|
||||
private @Nullable String getMainActivityNameThroughActivityAliasTag() {
|
||||
NodeList activityAliasNodes = androidManifest.getElementsByTagName("activity-alias");
|
||||
for (int i = 0; i < activityAliasNodes.getLength(); i++) {
|
||||
Element activityElement = (Element) activityAliasNodes.item(i);
|
||||
@@ -174,7 +164,7 @@ public class AndroidManifestParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getMainActivityNameThroughActivityTag() {
|
||||
private @Nullable String getMainActivityNameThroughActivityTag() {
|
||||
NodeList activityNodes = androidManifest.getElementsByTagName("activity");
|
||||
for (int i = 0; i < activityNodes.getLength(); i++) {
|
||||
Element activityElement = (Element) activityNodes.item(i);
|
||||
@@ -230,7 +220,7 @@ public class AndroidManifestParser {
|
||||
}
|
||||
}
|
||||
|
||||
private Document parseAppStrings(ResContainer appStrings) {
|
||||
private @Nullable Document parseAppStrings(@Nullable ResContainer appStrings) {
|
||||
if (appStrings == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -238,7 +228,7 @@ public class AndroidManifestParser {
|
||||
return parseXml(content);
|
||||
}
|
||||
|
||||
private Document parseAndroidManifest(ResourceFile androidManifest) {
|
||||
private @Nullable Document parseAndroidManifest(ResourceFile androidManifest) {
|
||||
if (androidManifest == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,68 +1,95 @@
|
||||
package jadx.core.utils.android;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.JadxDecompiler;
|
||||
import jadx.api.JavaClass;
|
||||
|
||||
public class ApplicationParams {
|
||||
private @Nullable String applicationLabel;
|
||||
private @Nullable Integer minSdkVersion;
|
||||
private @Nullable Integer targetSdkVersion;
|
||||
private @Nullable Integer compileSdkVersion;
|
||||
private @Nullable Integer versionCode;
|
||||
private @Nullable String versionName;
|
||||
private @Nullable String mainActivity;
|
||||
private @Nullable String application;
|
||||
|
||||
private final String applicationLabel;
|
||||
private final Integer minSdkVersion;
|
||||
private final Integer targetSdkVersion;
|
||||
private final Integer compileSdkVersion;
|
||||
private final Integer versionCode;
|
||||
private final String versionName;
|
||||
private final String mainActivity;
|
||||
private final String application;
|
||||
|
||||
public ApplicationParams(String applicationLabel, Integer minSdkVersion, Integer targetSdkVersion, Integer compileSdkVersion,
|
||||
Integer versionCode, String versionName, String mainActivity, String application) {
|
||||
this.applicationLabel = applicationLabel;
|
||||
this.minSdkVersion = minSdkVersion;
|
||||
this.targetSdkVersion = targetSdkVersion;
|
||||
this.compileSdkVersion = compileSdkVersion;
|
||||
this.versionCode = versionCode;
|
||||
this.versionName = versionName;
|
||||
this.mainActivity = mainActivity;
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
public String getApplicationName() {
|
||||
return applicationLabel;
|
||||
}
|
||||
|
||||
public Integer getMinSdkVersion() {
|
||||
return minSdkVersion;
|
||||
}
|
||||
|
||||
public Integer getTargetSdkVersion() {
|
||||
return targetSdkVersion;
|
||||
}
|
||||
|
||||
public Integer getCompileSdkVersion() {
|
||||
return compileSdkVersion;
|
||||
}
|
||||
|
||||
public Integer getVersionCode() {
|
||||
return versionCode;
|
||||
}
|
||||
|
||||
public String getVersionName() {
|
||||
return versionName;
|
||||
}
|
||||
|
||||
public String getMainActivity() {
|
||||
return mainActivity;
|
||||
}
|
||||
|
||||
public JavaClass getMainActivityJavaClass(JadxDecompiler decompiler) {
|
||||
return decompiler.searchJavaClassByAliasFullName(mainActivity);
|
||||
}
|
||||
|
||||
public String getApplication() {
|
||||
public @Nullable String getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
public JavaClass getApplicationJavaClass(JadxDecompiler decompiler) {
|
||||
public void setApplication(@Nullable String application) {
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
public @Nullable JavaClass getApplicationJavaClass(JadxDecompiler decompiler) {
|
||||
if (application == null) {
|
||||
return null;
|
||||
}
|
||||
return decompiler.searchJavaClassByAliasFullName(application);
|
||||
}
|
||||
|
||||
public @Nullable String getApplicationLabel() {
|
||||
return applicationLabel;
|
||||
}
|
||||
|
||||
public void setApplicationLabel(@Nullable String applicationLabel) {
|
||||
this.applicationLabel = applicationLabel;
|
||||
}
|
||||
|
||||
public @Nullable String getMainActivity() {
|
||||
return mainActivity;
|
||||
}
|
||||
|
||||
public void setMainActivity(@Nullable String mainActivity) {
|
||||
this.mainActivity = mainActivity;
|
||||
}
|
||||
|
||||
public @Nullable JavaClass getMainActivityJavaClass(JadxDecompiler decompiler) {
|
||||
if (mainActivity == null) {
|
||||
return null;
|
||||
}
|
||||
return decompiler.searchJavaClassByAliasFullName(mainActivity);
|
||||
}
|
||||
|
||||
public @Nullable Integer getCompileSdkVersion() {
|
||||
return compileSdkVersion;
|
||||
}
|
||||
|
||||
public void setCompileSdkVersion(@Nullable Integer compileSdkVersion) {
|
||||
this.compileSdkVersion = compileSdkVersion;
|
||||
}
|
||||
|
||||
public @Nullable Integer getMinSdkVersion() {
|
||||
return minSdkVersion;
|
||||
}
|
||||
|
||||
public void setMinSdkVersion(@Nullable Integer minSdkVersion) {
|
||||
this.minSdkVersion = minSdkVersion;
|
||||
}
|
||||
|
||||
public @Nullable Integer getTargetSdkVersion() {
|
||||
return targetSdkVersion;
|
||||
}
|
||||
|
||||
public void setTargetSdkVersion(@Nullable Integer targetSdkVersion) {
|
||||
this.targetSdkVersion = targetSdkVersion;
|
||||
}
|
||||
|
||||
public @Nullable Integer getVersionCode() {
|
||||
return versionCode;
|
||||
}
|
||||
|
||||
public void setVersionCode(@Nullable Integer versionCode) {
|
||||
this.versionCode = versionCode;
|
||||
}
|
||||
|
||||
public @Nullable String getVersionName() {
|
||||
return versionName;
|
||||
}
|
||||
|
||||
public void setVersionName(@Nullable String versionName) {
|
||||
this.versionName = versionName;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user