From 42b42e796dc4158e6a5b8a95e32b13105877f270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Pluta?= Date: Tue, 2 Apr 2019 17:47:27 +0200 Subject: [PATCH 1/5] 6: Create Analyser --- src/main/java/com/bartek/esa/EsaMain.java | 8 +- .../bartek/esa/core/analyser/Analyser.java | 83 +++++++++++++++++++ .../com/bartek/esa/core/di/CoreModule.java | 10 +++ .../com/bartek/esa/core/di/PluginModule.java | 19 +++++ .../esa/core/executor/PluginExecutor.java | 5 +- .../com/bartek/esa/di/DependencyInjector.java | 4 +- .../dispatcher/MethodDispatcher.java | 19 ++++- .../bartek/esa/dispatcher/model/Action.java | 12 +++ .../dispatcher/model/DispatcherActions.java | 6 +- 9 files changed, 152 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/bartek/esa/core/analyser/Analyser.java create mode 100644 src/main/java/com/bartek/esa/core/di/PluginModule.java create mode 100644 src/main/java/com/bartek/esa/dispatcher/model/Action.java diff --git a/src/main/java/com/bartek/esa/EsaMain.java b/src/main/java/com/bartek/esa/EsaMain.java index 781496d..c3a9461 100644 --- a/src/main/java/com/bartek/esa/EsaMain.java +++ b/src/main/java/com/bartek/esa/EsaMain.java @@ -2,11 +2,13 @@ package com.bartek.esa; import com.bartek.esa.cli.model.CliArgsOptions; import com.bartek.esa.cli.parser.CliArgsParser; +import com.bartek.esa.core.model.object.Issue; import com.bartek.esa.di.DaggerDependencyInjector; import com.bartek.esa.dispatcher.dispatcher.MethodDispatcher; import com.bartek.esa.dispatcher.model.DispatcherActions; import javax.inject.Inject; +import java.util.List; public class EsaMain { private final CliArgsParser cliArgsParser; @@ -20,13 +22,13 @@ public class EsaMain { private void run(String[] args) { DispatcherActions dispatcherActions = DispatcherActions.builder() - .sourceAnalysis(source -> {}) - .apkAudit(source -> {}) + .sourceAnalysis((source, plugins, excludes) -> null) + .apkAudit((source, plugins, excludes) -> null) .build(); CliArgsOptions options = cliArgsParser.parse(args); - methodDispatcher.dispatchMethod(options, dispatcherActions); + List issues = methodDispatcher.dispatchMethod(options, dispatcherActions); } public static void main(String[] args) { diff --git a/src/main/java/com/bartek/esa/core/analyser/Analyser.java b/src/main/java/com/bartek/esa/core/analyser/Analyser.java new file mode 100644 index 0000000..6a0fa99 --- /dev/null +++ b/src/main/java/com/bartek/esa/core/analyser/Analyser.java @@ -0,0 +1,83 @@ +package com.bartek.esa.core.analyser; + +import com.bartek.esa.core.archetype.Plugin; +import com.bartek.esa.core.executor.PluginExecutor; +import com.bartek.esa.core.model.object.Issue; +import com.bartek.esa.error.EsaException; +import com.bartek.esa.file.provider.FileProvider; + +import javax.inject.Inject; +import java.io.File; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class Analyser { + private final FileProvider fileProvider; + private final PluginExecutor pluginExecutor; + private final Set plugins; + + @Inject + public Analyser(FileProvider fileProvider, PluginExecutor pluginExecutor, Set plugins) { + this.fileProvider = fileProvider; + + this.pluginExecutor = pluginExecutor; + this.plugins = plugins; + } + + public List analyse(String source, Set pluginCodes, Set excludeCodes) { + File manifest = getManifest(source); + Set files = getFiles(source); + Set selectedPlugins = getPlugins(pluginCodes, excludeCodes); + + return pluginExecutor.executeForFiles(manifest, files, selectedPlugins); + } + + private File getManifest(String source) { + Set manifests = fileProvider.getGlobMatchedFiles(source, "**/AndroidManifest.xml"); + if (manifests.isEmpty()) { + throw new EsaException("No AndroidManifest.xml file found. Interrupting..."); + } + + if (manifests.size() > 1) { + throw new EsaException("Found multiple AndroidManifest.xml files. Interrupting..."); + } + + return (File) (manifests.toArray())[0]; + } + + private Set getFiles(String source) { + Set javaFiles = fileProvider.getGlobMatchedFiles(source, "**/*.java"); + Set androidManifest = fileProvider.getGlobMatchedFiles(source, "**/AndroidManifest.xml"); + Set layoutFiles = fileProvider.getGlobMatchedFiles(source, "**/res/layout*/**.xml"); + + return Stream.of(javaFiles, androidManifest, layoutFiles) + .flatMap(Set::stream) + .collect(Collectors.toSet()); + } + + private Set getPlugins(Set pluginCodes, Set excludeCodes) { + Set outputPlugins = plugins; + + if (!pluginCodes.isEmpty()) { + outputPlugins = plugins.stream() + .filter(plugin -> pluginCodes + .stream() + .anyMatch(pluginCode -> plugin.getClass().getCanonicalName().equals(pluginCode)) + ) + .collect(Collectors.toSet()); + } + + if(!excludeCodes.isEmpty()) { + outputPlugins = outputPlugins.stream() + .filter(plugin -> excludeCodes + .stream() + .noneMatch(pluginCode -> plugin.getClass().getCanonicalName().equals(pluginCode)) + ) + .collect(Collectors.toSet()); + } + + return outputPlugins; + } +} diff --git a/src/main/java/com/bartek/esa/core/di/CoreModule.java b/src/main/java/com/bartek/esa/core/di/CoreModule.java index 59d666d..2b54b7b 100644 --- a/src/main/java/com/bartek/esa/core/di/CoreModule.java +++ b/src/main/java/com/bartek/esa/core/di/CoreModule.java @@ -1,12 +1,17 @@ package com.bartek.esa.core.di; +import com.bartek.esa.core.analyser.Analyser; +import com.bartek.esa.core.archetype.Plugin; import com.bartek.esa.core.desc.provider.DescriptionProvider; import com.bartek.esa.core.executor.PluginExecutor; import com.bartek.esa.core.java.JavaSyntaxRegexProvider; import com.bartek.esa.core.xml.XmlHelper; +import com.bartek.esa.file.provider.FileProvider; import dagger.Module; import dagger.Provides; +import java.util.Set; + @Module public class CoreModule { @@ -29,4 +34,9 @@ public class CoreModule { public XmlHelper xmlHelper() { return new XmlHelper(); } + + @Provides + public Analyser analyser(FileProvider fileProvider, PluginExecutor pluginExecutor, Set plugins) { + return new Analyser(fileProvider, pluginExecutor, plugins); + } } diff --git a/src/main/java/com/bartek/esa/core/di/PluginModule.java b/src/main/java/com/bartek/esa/core/di/PluginModule.java new file mode 100644 index 0000000..c1474b2 --- /dev/null +++ b/src/main/java/com/bartek/esa/core/di/PluginModule.java @@ -0,0 +1,19 @@ +package com.bartek.esa.core.di; + +import com.bartek.esa.core.archetype.Plugin; +import dagger.Module; +import dagger.Provides; +import dagger.multibindings.ElementsIntoSet; + +import java.util.HashSet; +import java.util.Set; + +@Module +public class PluginModule { + + @Provides + @ElementsIntoSet + public Set plugins() { + return new HashSet<>(); + } +} diff --git a/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java b/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java index e114489..c3b585a 100644 --- a/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java +++ b/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java @@ -8,6 +8,7 @@ import org.w3c.dom.Document; import javax.inject.Inject; import java.io.File; import java.util.List; +import java.util.Set; import static java.util.stream.Collectors.toList; @@ -19,14 +20,14 @@ public class PluginExecutor { this.xmlHelper = xmlHelper; } - public List executeForFiles(File manifest, List files, List plugins) { + public List executeForFiles(File manifest, Set files, Set plugins) { return files.stream() .map(file -> executeForFile(manifest, file, plugins)) .flatMap(List::stream) .collect(toList()); } - private List executeForFile(File manifest, File file, List plugins) { + private List executeForFile(File manifest, File file, Set plugins) { Document xmlManifest = xmlHelper.parseXml(manifest); return plugins.stream() .filter(plugin -> plugin.supports(file)) diff --git a/src/main/java/com/bartek/esa/di/DependencyInjector.java b/src/main/java/com/bartek/esa/di/DependencyInjector.java index b05f447..9793337 100644 --- a/src/main/java/com/bartek/esa/di/DependencyInjector.java +++ b/src/main/java/com/bartek/esa/di/DependencyInjector.java @@ -3,6 +3,7 @@ package com.bartek.esa.di; import com.bartek.esa.EsaMain; import com.bartek.esa.cli.di.CliModule; import com.bartek.esa.core.di.CoreModule; +import com.bartek.esa.core.di.PluginModule; import com.bartek.esa.decompiler.di.DecompilerModule; import com.bartek.esa.dispatcher.di.DispatcherModule; import com.bartek.esa.file.di.FileModule; @@ -13,7 +14,8 @@ import dagger.Component; DispatcherModule.class, FileModule.class, DecompilerModule.class, - CoreModule.class + CoreModule.class, + PluginModule.class }) public interface DependencyInjector { EsaMain esa(); diff --git a/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java b/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java index 306795d..29711ad 100644 --- a/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java +++ b/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java @@ -1,9 +1,12 @@ package com.bartek.esa.dispatcher.dispatcher; import com.bartek.esa.cli.model.CliArgsOptions; +import com.bartek.esa.core.model.object.Issue; import com.bartek.esa.dispatcher.model.DispatcherActions; import javax.inject.Inject; +import java.util.Collections; +import java.util.List; public class MethodDispatcher { @@ -12,14 +15,22 @@ public class MethodDispatcher { } - public void dispatchMethod(CliArgsOptions options, DispatcherActions actions) { + public List dispatchMethod(CliArgsOptions options, DispatcherActions actions) { if(options.isSourceAnalysis()) { - actions.getSourceAnalysis().accept(options.getSourceAnalysisDirectory()); - return; + return actions.getSourceAnalysis().perform( + options.getSourceAnalysisDirectory(), + options.getPlugins(), + options.getExcludes() + ); } if(options.isApkAudit()) { - actions.getApkAudit().accept(options.getApkAuditFile()); + return actions.getApkAudit().perform(options.getApkAuditFile(), + options.getPlugins(), + options.getExcludes() + ); } + + return Collections.emptyList(); } } diff --git a/src/main/java/com/bartek/esa/dispatcher/model/Action.java b/src/main/java/com/bartek/esa/dispatcher/model/Action.java new file mode 100644 index 0000000..b7ba664 --- /dev/null +++ b/src/main/java/com/bartek/esa/dispatcher/model/Action.java @@ -0,0 +1,12 @@ +package com.bartek.esa.dispatcher.model; + +import com.bartek.esa.core.model.object.Issue; + +import java.util.List; +import java.util.Set; + +@FunctionalInterface +public interface Action { + + List perform(String source, Set plugins, Set excludes); +} diff --git a/src/main/java/com/bartek/esa/dispatcher/model/DispatcherActions.java b/src/main/java/com/bartek/esa/dispatcher/model/DispatcherActions.java index a3411c8..28f242f 100644 --- a/src/main/java/com/bartek/esa/dispatcher/model/DispatcherActions.java +++ b/src/main/java/com/bartek/esa/dispatcher/model/DispatcherActions.java @@ -3,11 +3,9 @@ package com.bartek.esa.dispatcher.model; import lombok.Builder; import lombok.Data; -import java.util.function.Consumer; - @Data @Builder public class DispatcherActions { - private Consumer sourceAnalysis; - private Consumer apkAudit; + private Action sourceAnalysis; + private Action apkAudit; } From 2e3029a5d92444c49366387a038cf9d91b5d0f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Pluta?= Date: Tue, 2 Apr 2019 18:20:08 +0200 Subject: [PATCH 2/5] 6: Extract Analyser to another package --- .../analyser => analyser/core}/Analyser.java | 36 ++----------- .../esa/analyser/di/AnalyserModule.java | 19 +++++++ .../esa/analyser/source/SourceAnalyser.java | 52 +++++++++++++++++++ .../com/bartek/esa/core/di/CoreModule.java | 10 ---- .../com/bartek/esa/di/DependencyInjector.java | 4 +- .../esa/file/provider/FileProvider.java | 2 +- 6 files changed, 80 insertions(+), 43 deletions(-) rename src/main/java/com/bartek/esa/{core/analyser => analyser/core}/Analyser.java (54%) create mode 100644 src/main/java/com/bartek/esa/analyser/di/AnalyserModule.java create mode 100644 src/main/java/com/bartek/esa/analyser/source/SourceAnalyser.java diff --git a/src/main/java/com/bartek/esa/core/analyser/Analyser.java b/src/main/java/com/bartek/esa/analyser/core/Analyser.java similarity index 54% rename from src/main/java/com/bartek/esa/core/analyser/Analyser.java rename to src/main/java/com/bartek/esa/analyser/core/Analyser.java index 6a0fa99..14de815 100644 --- a/src/main/java/com/bartek/esa/core/analyser/Analyser.java +++ b/src/main/java/com/bartek/esa/analyser/core/Analyser.java @@ -1,26 +1,19 @@ -package com.bartek.esa.core.analyser; +package com.bartek.esa.analyser.core; import com.bartek.esa.core.archetype.Plugin; import com.bartek.esa.core.executor.PluginExecutor; import com.bartek.esa.core.model.object.Issue; -import com.bartek.esa.error.EsaException; -import com.bartek.esa.file.provider.FileProvider; -import javax.inject.Inject; import java.io.File; import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; -public class Analyser { - private final FileProvider fileProvider; +public abstract class Analyser { private final PluginExecutor pluginExecutor; private final Set plugins; - @Inject - public Analyser(FileProvider fileProvider, PluginExecutor pluginExecutor, Set plugins) { - this.fileProvider = fileProvider; + public Analyser(PluginExecutor pluginExecutor, Set plugins) { this.pluginExecutor = pluginExecutor; this.plugins = plugins; @@ -34,28 +27,9 @@ public class Analyser { return pluginExecutor.executeForFiles(manifest, files, selectedPlugins); } - private File getManifest(String source) { - Set manifests = fileProvider.getGlobMatchedFiles(source, "**/AndroidManifest.xml"); - if (manifests.isEmpty()) { - throw new EsaException("No AndroidManifest.xml file found. Interrupting..."); - } + protected abstract File getManifest(String source); - if (manifests.size() > 1) { - throw new EsaException("Found multiple AndroidManifest.xml files. Interrupting..."); - } - - return (File) (manifests.toArray())[0]; - } - - private Set getFiles(String source) { - Set javaFiles = fileProvider.getGlobMatchedFiles(source, "**/*.java"); - Set androidManifest = fileProvider.getGlobMatchedFiles(source, "**/AndroidManifest.xml"); - Set layoutFiles = fileProvider.getGlobMatchedFiles(source, "**/res/layout*/**.xml"); - - return Stream.of(javaFiles, androidManifest, layoutFiles) - .flatMap(Set::stream) - .collect(Collectors.toSet()); - } + protected abstract Set getFiles(String source); private Set getPlugins(Set pluginCodes, Set excludeCodes) { Set outputPlugins = plugins; diff --git a/src/main/java/com/bartek/esa/analyser/di/AnalyserModule.java b/src/main/java/com/bartek/esa/analyser/di/AnalyserModule.java new file mode 100644 index 0000000..1dac532 --- /dev/null +++ b/src/main/java/com/bartek/esa/analyser/di/AnalyserModule.java @@ -0,0 +1,19 @@ +package com.bartek.esa.analyser.di; + +import com.bartek.esa.analyser.source.SourceAnalyser; +import com.bartek.esa.core.archetype.Plugin; +import com.bartek.esa.core.executor.PluginExecutor; +import com.bartek.esa.file.provider.FileProvider; +import dagger.Module; +import dagger.Provides; + +import java.util.Set; + +@Module +public class AnalyserModule { + + @Provides + public SourceAnalyser sourceAnalyser(PluginExecutor pluginExecutor, Set plugins, FileProvider fileProvider) { + return new SourceAnalyser(pluginExecutor, plugins, fileProvider); + } +} diff --git a/src/main/java/com/bartek/esa/analyser/source/SourceAnalyser.java b/src/main/java/com/bartek/esa/analyser/source/SourceAnalyser.java new file mode 100644 index 0000000..b1093d7 --- /dev/null +++ b/src/main/java/com/bartek/esa/analyser/source/SourceAnalyser.java @@ -0,0 +1,52 @@ +package com.bartek.esa.analyser.source; + +import com.bartek.esa.analyser.core.Analyser; +import com.bartek.esa.core.archetype.Plugin; +import com.bartek.esa.core.executor.PluginExecutor; +import com.bartek.esa.error.EsaException; +import com.bartek.esa.file.provider.FileProvider; + +import javax.inject.Inject; +import java.io.File; +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class SourceAnalyser extends Analyser { + private final FileProvider fileProvider; + + @Inject + public SourceAnalyser(PluginExecutor pluginExecutor, Set plugins, FileProvider fileProvider) { + super(pluginExecutor, plugins); + this.fileProvider = fileProvider; + } + + @Override + protected File getManifest(String source) { + Set manifests = fileProvider.getGlobMatchedFilesRecursively(source, "**/AndroidManifest.xml"); + if (manifests.isEmpty()) { + throw new EsaException("No AndroidManifest.xml file found. Interrupting..."); + } + + if (manifests.size() > 1) { + throw new EsaException("Found multiple AndroidManifest.xml files. Interrupting..."); + } + + return (File) (manifests.toArray())[0]; + } + + @Override + protected Set getFiles(String source) { + Set javaFiles = fileProvider.getGlobMatchedFilesRecursively(source, "**/*.java"); + System.out.println(javaFiles); + Set layoutFiles = fileProvider.getGlobMatchedFilesRecursively(source, "**/res/layout*/**.xml"); + System.out.println(layoutFiles); + Set androidManifest = Collections.singleton(getManifest(source)); + System.out.println(androidManifest); + + return Stream.of(javaFiles, androidManifest, layoutFiles) + .flatMap(Set::stream) + .collect(Collectors.toSet()); + } +} diff --git a/src/main/java/com/bartek/esa/core/di/CoreModule.java b/src/main/java/com/bartek/esa/core/di/CoreModule.java index 2b54b7b..59d666d 100644 --- a/src/main/java/com/bartek/esa/core/di/CoreModule.java +++ b/src/main/java/com/bartek/esa/core/di/CoreModule.java @@ -1,17 +1,12 @@ package com.bartek.esa.core.di; -import com.bartek.esa.core.analyser.Analyser; -import com.bartek.esa.core.archetype.Plugin; import com.bartek.esa.core.desc.provider.DescriptionProvider; import com.bartek.esa.core.executor.PluginExecutor; import com.bartek.esa.core.java.JavaSyntaxRegexProvider; import com.bartek.esa.core.xml.XmlHelper; -import com.bartek.esa.file.provider.FileProvider; import dagger.Module; import dagger.Provides; -import java.util.Set; - @Module public class CoreModule { @@ -34,9 +29,4 @@ public class CoreModule { public XmlHelper xmlHelper() { return new XmlHelper(); } - - @Provides - public Analyser analyser(FileProvider fileProvider, PluginExecutor pluginExecutor, Set plugins) { - return new Analyser(fileProvider, pluginExecutor, plugins); - } } diff --git a/src/main/java/com/bartek/esa/di/DependencyInjector.java b/src/main/java/com/bartek/esa/di/DependencyInjector.java index 9793337..2c78ba4 100644 --- a/src/main/java/com/bartek/esa/di/DependencyInjector.java +++ b/src/main/java/com/bartek/esa/di/DependencyInjector.java @@ -1,6 +1,7 @@ package com.bartek.esa.di; import com.bartek.esa.EsaMain; +import com.bartek.esa.analyser.di.AnalyserModule; import com.bartek.esa.cli.di.CliModule; import com.bartek.esa.core.di.CoreModule; import com.bartek.esa.core.di.PluginModule; @@ -15,7 +16,8 @@ import dagger.Component; FileModule.class, DecompilerModule.class, CoreModule.class, - PluginModule.class + PluginModule.class, + AnalyserModule.class }) public interface DependencyInjector { EsaMain esa(); diff --git a/src/main/java/com/bartek/esa/file/provider/FileProvider.java b/src/main/java/com/bartek/esa/file/provider/FileProvider.java index b058d37..411dc05 100644 --- a/src/main/java/com/bartek/esa/file/provider/FileProvider.java +++ b/src/main/java/com/bartek/esa/file/provider/FileProvider.java @@ -27,7 +27,7 @@ public class FileProvider { .toFile(); } - public Set getGlobMatchedFiles(String path, String globPattern) { + public Set getGlobMatchedFilesRecursively(String path, String globPattern) { return Try.of(() -> Files.walk(Paths.get(path)) .filter(p -> globMatcher.pathMatchesGlobPattern(p, globPattern)) .map(Path::toFile) From 1a435d131d92524e9a2d2aca95640b224a1c1ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Pluta?= Date: Tue, 2 Apr 2019 21:14:18 +0200 Subject: [PATCH 3/5] 6: Improve Analysers --- .../bartek/esa/analyser/apk/ApkAnalyser.java | 43 +++++++++++++++++ .../bartek/esa/analyser/core/Analyser.java | 45 +++++++++++++++-- .../esa/analyser/di/AnalyserModule.java | 7 +++ .../esa/analyser/source/SourceAnalyser.java | 48 +++++++------------ .../esa/file/provider/FileProvider.java | 2 +- 5 files changed, 108 insertions(+), 37 deletions(-) create mode 100644 src/main/java/com/bartek/esa/analyser/apk/ApkAnalyser.java diff --git a/src/main/java/com/bartek/esa/analyser/apk/ApkAnalyser.java b/src/main/java/com/bartek/esa/analyser/apk/ApkAnalyser.java new file mode 100644 index 0000000..2dae5f3 --- /dev/null +++ b/src/main/java/com/bartek/esa/analyser/apk/ApkAnalyser.java @@ -0,0 +1,43 @@ +package com.bartek.esa.analyser.apk; + +import com.bartek.esa.analyser.core.Analyser; +import com.bartek.esa.core.archetype.Plugin; +import com.bartek.esa.core.executor.PluginExecutor; +import com.bartek.esa.decompiler.decompiler.Decompiler; +import com.bartek.esa.file.provider.FileProvider; + +import java.io.File; +import java.util.Set; + +public class ApkAnalyser extends Analyser { + private static final String ANDROID_MANIFEST_GLOB = "**/" + Decompiler.XML_FILES_DIR + "/AndroidManifest.xml"; + private static final String JAVA_GLOB = "**/" + Decompiler.JAVA_FILES_DIR + "/**/*.java"; + private static final String LAYOUT_GLOB = "**/" + Decompiler.XML_FILES_DIR + "/**/layout*/*.xml"; + + private final Decompiler decompiler; + + public ApkAnalyser(PluginExecutor pluginExecutor, Set plugins, FileProvider fileProvider, Decompiler decompiler) { + super(pluginExecutor, plugins, fileProvider); + this.decompiler = decompiler; + } + + @Override + protected String prepareSources(String source) { + return decompiler.decompile(new File(source)).getAbsolutePath(); + } + + @Override + protected String getAndroidManifestGlob() { + return ANDROID_MANIFEST_GLOB; + } + + @Override + protected String getJavaGlob() { + return JAVA_GLOB; + } + + @Override + protected String getLayoutGlob() { + return LAYOUT_GLOB; + } +} diff --git a/src/main/java/com/bartek/esa/analyser/core/Analyser.java b/src/main/java/com/bartek/esa/analyser/core/Analyser.java index 14de815..0f3eb4c 100644 --- a/src/main/java/com/bartek/esa/analyser/core/Analyser.java +++ b/src/main/java/com/bartek/esa/analyser/core/Analyser.java @@ -3,33 +3,68 @@ package com.bartek.esa.analyser.core; import com.bartek.esa.core.archetype.Plugin; import com.bartek.esa.core.executor.PluginExecutor; import com.bartek.esa.core.model.object.Issue; +import com.bartek.esa.error.EsaException; +import com.bartek.esa.file.provider.FileProvider; import java.io.File; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; public abstract class Analyser { private final PluginExecutor pluginExecutor; private final Set plugins; + private final FileProvider fileProvider; - public Analyser(PluginExecutor pluginExecutor, Set plugins) { + public Analyser(PluginExecutor pluginExecutor, Set plugins, FileProvider fileProvider) { this.pluginExecutor = pluginExecutor; this.plugins = plugins; + this.fileProvider = fileProvider; } public List analyse(String source, Set pluginCodes, Set excludeCodes) { - File manifest = getManifest(source); - Set files = getFiles(source); + String newSource = prepareSources(source); + File manifest = getManifest(newSource); + Set files = getFiles(newSource); Set selectedPlugins = getPlugins(pluginCodes, excludeCodes); return pluginExecutor.executeForFiles(manifest, files, selectedPlugins); } - protected abstract File getManifest(String source); + protected abstract String prepareSources(String source); - protected abstract Set getFiles(String source); + protected abstract String getAndroidManifestGlob(); + + protected abstract String getJavaGlob(); + + protected abstract String getLayoutGlob(); + + + private File getManifest(String source) { + Set manifests = fileProvider.getGlobMatchedFiles(source, getAndroidManifestGlob()); + if (manifests.isEmpty()) { + throw new EsaException("No AndroidManifest.xml file found. Interrupting..."); + } + + if (manifests.size() > 1) { + throw new EsaException("Found multiple AndroidManifest.xml files. Interrupting..."); + } + + return (File) (manifests.toArray())[0]; + } + + private Set getFiles(String source) { + Set javaFiles = fileProvider.getGlobMatchedFiles(source, getJavaGlob()); + Set layoutFiles = fileProvider.getGlobMatchedFiles(source, getLayoutGlob()); + Set androidManifest = Collections.singleton(getManifest(source)); + + return Stream.of(javaFiles, androidManifest, layoutFiles) + .flatMap(Set::stream) + .collect(Collectors.toSet()); + } private Set getPlugins(Set pluginCodes, Set excludeCodes) { Set outputPlugins = plugins; diff --git a/src/main/java/com/bartek/esa/analyser/di/AnalyserModule.java b/src/main/java/com/bartek/esa/analyser/di/AnalyserModule.java index 1dac532..3087dd5 100644 --- a/src/main/java/com/bartek/esa/analyser/di/AnalyserModule.java +++ b/src/main/java/com/bartek/esa/analyser/di/AnalyserModule.java @@ -1,8 +1,10 @@ package com.bartek.esa.analyser.di; +import com.bartek.esa.analyser.apk.ApkAnalyser; import com.bartek.esa.analyser.source.SourceAnalyser; import com.bartek.esa.core.archetype.Plugin; import com.bartek.esa.core.executor.PluginExecutor; +import com.bartek.esa.decompiler.decompiler.Decompiler; import com.bartek.esa.file.provider.FileProvider; import dagger.Module; import dagger.Provides; @@ -16,4 +18,9 @@ public class AnalyserModule { public SourceAnalyser sourceAnalyser(PluginExecutor pluginExecutor, Set plugins, FileProvider fileProvider) { return new SourceAnalyser(pluginExecutor, plugins, fileProvider); } + + @Provides + public ApkAnalyser apkAnalyser(PluginExecutor pluginExecutor, Set plugins, FileProvider fileProvider, Decompiler decompiler) { + return new ApkAnalyser(pluginExecutor, plugins, fileProvider, decompiler); + } } diff --git a/src/main/java/com/bartek/esa/analyser/source/SourceAnalyser.java b/src/main/java/com/bartek/esa/analyser/source/SourceAnalyser.java index b1093d7..6374ee9 100644 --- a/src/main/java/com/bartek/esa/analyser/source/SourceAnalyser.java +++ b/src/main/java/com/bartek/esa/analyser/source/SourceAnalyser.java @@ -3,50 +3,36 @@ package com.bartek.esa.analyser.source; import com.bartek.esa.analyser.core.Analyser; import com.bartek.esa.core.archetype.Plugin; import com.bartek.esa.core.executor.PluginExecutor; -import com.bartek.esa.error.EsaException; import com.bartek.esa.file.provider.FileProvider; -import javax.inject.Inject; -import java.io.File; -import java.util.Collections; import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; public class SourceAnalyser extends Analyser { - private final FileProvider fileProvider; + private static final String ANDROID_MANIFEST_GLOB = "**/AndroidManifest.xml"; + private static final String JAVA_GLOB = "**/*.java"; + private static final String LAYOUT_GLOB = "**/res/layout*/*.xml"; - @Inject public SourceAnalyser(PluginExecutor pluginExecutor, Set plugins, FileProvider fileProvider) { - super(pluginExecutor, plugins); - this.fileProvider = fileProvider; + super(pluginExecutor, plugins, fileProvider); } @Override - protected File getManifest(String source) { - Set manifests = fileProvider.getGlobMatchedFilesRecursively(source, "**/AndroidManifest.xml"); - if (manifests.isEmpty()) { - throw new EsaException("No AndroidManifest.xml file found. Interrupting..."); - } - - if (manifests.size() > 1) { - throw new EsaException("Found multiple AndroidManifest.xml files. Interrupting..."); - } - - return (File) (manifests.toArray())[0]; + protected String prepareSources(String source) { + return source; } @Override - protected Set getFiles(String source) { - Set javaFiles = fileProvider.getGlobMatchedFilesRecursively(source, "**/*.java"); - System.out.println(javaFiles); - Set layoutFiles = fileProvider.getGlobMatchedFilesRecursively(source, "**/res/layout*/**.xml"); - System.out.println(layoutFiles); - Set androidManifest = Collections.singleton(getManifest(source)); - System.out.println(androidManifest); + protected String getAndroidManifestGlob() { + return ANDROID_MANIFEST_GLOB; + } - return Stream.of(javaFiles, androidManifest, layoutFiles) - .flatMap(Set::stream) - .collect(Collectors.toSet()); + @Override + protected String getJavaGlob() { + return JAVA_GLOB; + } + + @Override + protected String getLayoutGlob() { + return LAYOUT_GLOB; } } diff --git a/src/main/java/com/bartek/esa/file/provider/FileProvider.java b/src/main/java/com/bartek/esa/file/provider/FileProvider.java index 411dc05..b058d37 100644 --- a/src/main/java/com/bartek/esa/file/provider/FileProvider.java +++ b/src/main/java/com/bartek/esa/file/provider/FileProvider.java @@ -27,7 +27,7 @@ public class FileProvider { .toFile(); } - public Set getGlobMatchedFilesRecursively(String path, String globPattern) { + public Set getGlobMatchedFiles(String path, String globPattern) { return Try.of(() -> Files.walk(Paths.get(path)) .filter(p -> globMatcher.pathMatchesGlobPattern(p, globPattern)) .map(Path::toFile) From 4a70fd1c75171f81eae2382d9c95883f7f22e0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Pluta?= Date: Tue, 2 Apr 2019 22:14:52 +0200 Subject: [PATCH 4/5] 6: Enable checking package of Java files --- .../bartek/esa/core/archetype/JavaPlugin.java | 27 ++++++++++++++++++- .../esa/core/executor/PluginExecutor.java | 6 ++--- src/main/resources/description.properties | 1 + 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/bartek/esa/core/archetype/JavaPlugin.java b/src/main/java/com/bartek/esa/core/archetype/JavaPlugin.java index f735329..d617c13 100644 --- a/src/main/java/com/bartek/esa/core/archetype/JavaPlugin.java +++ b/src/main/java/com/bartek/esa/core/archetype/JavaPlugin.java @@ -1,18 +1,25 @@ package com.bartek.esa.core.archetype; +import com.bartek.esa.core.model.enumeration.Severity; +import com.bartek.esa.core.xml.XmlHelper; import com.bartek.esa.error.EsaException; import com.bartek.esa.file.matcher.GlobMatcher; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import io.vavr.control.Try; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import javax.xml.xpath.XPathConstants; import java.io.File; public abstract class JavaPlugin extends BasePlugin { private final GlobMatcher globMatcher; + private final XmlHelper xmlHelper; - public JavaPlugin(GlobMatcher globMatcher) { + public JavaPlugin(GlobMatcher globMatcher, XmlHelper xmlHelper) { this.globMatcher = globMatcher; + this.xmlHelper = xmlHelper; } @Override @@ -22,9 +29,27 @@ public abstract class JavaPlugin extends BasePlugin { @Override protected void run(File file) { + if(!isApplicationPackageFile(file)) { + return; + } + CompilationUnit compilationUnit = Try.of(() -> StaticJavaParser.parse(file)).getOrElseThrow(EsaException::new); run(compilationUnit); } + private boolean isApplicationPackageFile(File file) { + Document manifest = getManifest(); + Node root = (Node) xmlHelper.xPath(manifest, "/manifest", XPathConstants.NODE); + Node packageValue = root.getAttributes().getNamedItem("package"); + + if(packageValue == null) { + addIssue(Severity.ERROR, ".PACKAGE_LACK", null, null); + return false; + } + + String path = packageValue.getNodeValue().replaceAll("\\.", "/"); + return globMatcher.fileMatchesGlobPattern(file, String.format("**/%s/**", path)); + } + public abstract void run(CompilationUnit compilationUnit); } diff --git a/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java b/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java index c3b585a..10d0041 100644 --- a/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java +++ b/src/main/java/com/bartek/esa/core/executor/PluginExecutor.java @@ -30,11 +30,9 @@ public class PluginExecutor { private List executeForFile(File manifest, File file, Set plugins) { Document xmlManifest = xmlHelper.parseXml(manifest); return plugins.stream() + .peek(plugin -> plugin.update(file, xmlManifest)) .filter(plugin -> plugin.supports(file)) - .map(plugin -> { - plugin.update(file, xmlManifest); - return plugin.runForIssues(); - }) + .map(Plugin::runForIssues) .flatMap(List::stream) .collect(toList()); } diff --git a/src/main/resources/description.properties b/src/main/resources/description.properties index e69de29..39d333c 100644 --- a/src/main/resources/description.properties +++ b/src/main/resources/description.properties @@ -0,0 +1 @@ +com.bartek.esa.core.plugin.JavaPlugin.PACKAGE_LACK=There is no package defined in AndroidManifest.xml file. Please check fix to use this tool. \ No newline at end of file From 30439d16b85cf2356f554b85b711d70c62dd57fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Pluta?= Date: Wed, 3 Apr 2019 10:27:00 +0200 Subject: [PATCH 5/5] 6: Enable analysing in EsaMain --- src/main/java/com/bartek/esa/EsaMain.java | 12 +++++++++--- .../esa/dispatcher/dispatcher/MethodDispatcher.java | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/bartek/esa/EsaMain.java b/src/main/java/com/bartek/esa/EsaMain.java index c3a9461..704a32b 100644 --- a/src/main/java/com/bartek/esa/EsaMain.java +++ b/src/main/java/com/bartek/esa/EsaMain.java @@ -1,5 +1,7 @@ package com.bartek.esa; +import com.bartek.esa.analyser.apk.ApkAnalyser; +import com.bartek.esa.analyser.source.SourceAnalyser; import com.bartek.esa.cli.model.CliArgsOptions; import com.bartek.esa.cli.parser.CliArgsParser; import com.bartek.esa.core.model.object.Issue; @@ -13,17 +15,21 @@ import java.util.List; public class EsaMain { private final CliArgsParser cliArgsParser; private final MethodDispatcher methodDispatcher; + private final SourceAnalyser sourceAnalyser; + private final ApkAnalyser apkAnalyser; @Inject - EsaMain(CliArgsParser cliArgsParser, MethodDispatcher methodDispatcher) { + EsaMain(CliArgsParser cliArgsParser, MethodDispatcher methodDispatcher, SourceAnalyser sourceAnalyser, ApkAnalyser apkAnalyser) { this.cliArgsParser = cliArgsParser; this.methodDispatcher = methodDispatcher; + this.sourceAnalyser = sourceAnalyser; + this.apkAnalyser = apkAnalyser; } private void run(String[] args) { DispatcherActions dispatcherActions = DispatcherActions.builder() - .sourceAnalysis((source, plugins, excludes) -> null) - .apkAudit((source, plugins, excludes) -> null) + .sourceAnalysis(sourceAnalyser::analyse) + .apkAudit(apkAnalyser::analyse) .build(); CliArgsOptions options = cliArgsParser.parse(args); diff --git a/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java b/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java index 29711ad..3dc20b4 100644 --- a/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java +++ b/src/main/java/com/bartek/esa/dispatcher/dispatcher/MethodDispatcher.java @@ -25,7 +25,8 @@ public class MethodDispatcher { } if(options.isApkAudit()) { - return actions.getApkAudit().perform(options.getApkAuditFile(), + return actions.getApkAudit().perform( + options.getApkAuditFile(), options.getPlugins(), options.getExcludes() );