Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

input locations: check if specified path exists #740

Merged
merged 41 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
31ef68f
progress
swissiety Nov 3, 2023
22e9691
restructure if-else tree
swissiety Nov 3, 2023
5fb0649
path check for JavaSourcePathAnalysisInputLocation
swissiety Nov 3, 2023
18fa111
propagate SourceType into ModuleFinder and where it would flow from t…
swissiety Nov 3, 2023
ce7cd38
fix warFile path
swissiety Nov 3, 2023
10f26ba
revert / fix already existing temp dir
swissiety Nov 3, 2023
7fdba82
add recurring helper methods to MethodSubSignature
swissiety Nov 3, 2023
5f01499
add more info to exception
swissiety Nov 3, 2023
c259fe0
doc
swissiety Nov 6, 2023
e6311a8
Merge branch 'develop' into PathBasedAnalysisInputLocation_path_exist…
swissiety Nov 9, 2023
944e345
fix creating temp dir for warfiles
swissiety Nov 9, 2023
c8c8160
adapt testcases to DefaultRTJarAnalysisInputLocation; made it public
swissiety Nov 22, 2023
7c9ca1b
adapt isMain(...)
swissiety Nov 22, 2023
8cc7cfb
Merge branch 'develop' into PathBasedAnalysisInputLocation_path_exist…
swissiety Nov 22, 2023
a95e7e7
add license
swissiety Nov 22, 2023
6a8f0d7
adapt leftovers
swissiety Nov 22, 2023
303e04c
fix link to doc in auto comment
swissiety Nov 22, 2023
c24d88c
fix test
swissiety Nov 23, 2023
3321a68
fix test; remove method draft
swissiety Nov 23, 2023
6b4434b
make use of autoclosable
swissiety Nov 23, 2023
1e98066
sanitize branch name for doc
swissiety Nov 23, 2023
b1b9d58
sanitize all non alphanumeric branch/tag names
swissiety Nov 23, 2023
94eff49
trigger on config change
swissiety Nov 23, 2023
3975689
again
swissiety Nov 23, 2023
708cdfb
aaand again
swissiety Nov 23, 2023
20a1f0a
trigger ci
swissiety Nov 23, 2023
a8c0b80
trigger ci
swissiety Nov 23, 2023
3f4d842
trigger ci
swissiety Nov 23, 2023
81f28c0
trigger ci
swissiety Nov 23, 2023
2fc5e90
trigger ci
swissiety Nov 23, 2023
f399f15
trigger ci
swissiety Nov 23, 2023
c1e78dc
trigger ci
swissiety Nov 23, 2023
4921740
trigger ci
swissiety Nov 23, 2023
0a06a38
trigger ci
swissiety Nov 23, 2023
a6ea22d
cleanup typo
swissiety Nov 23, 2023
95cac41
not anymore
swissiety Nov 23, 2023
b6f1486
not anymore; refactored the java specifics froms sootclass
swissiety Nov 23, 2023
272762b
fix exception type
swissiety Nov 23, 2023
dcc2ac5
fixed tests
swissiety Nov 23, 2023
1b96a41
enable hiding pr previews in the version selector
swissiety Nov 23, 2023
888358e
title for preview
swissiety Nov 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
* @author Ben Hermann
* @author Linghui Luo
*/
public interface AnalysisInputLocation<T extends AbstractClass> {
public interface AnalysisInputLocation<T extends AbstractClass<?>> {
/**
* Create or find a class source for a given type.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,22 @@ public void toString(StmtPrinter printer) {

printer.literal(")");
}

boolean isMainSignature() {
swissiety marked this conversation as resolved.
Show resolved Hide resolved
if (getName().equals("main")) {
if (getParameterTypes().size() == 1) {
// FIXME: handle modules with 'java.base' in the signature as well
return getParameterTypes().get(0).toString().equals("java.lang.String[]");
}
}
return false;
}

boolean isStaticInitializerSignature() {
return getName().equals("<clinit>");
}

boolean isConstructor() {
return getName().equals("<init>");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ public JavaClassPathAnalysisInputLocation(
@Nonnull String classPath, @Nonnull SourceType srcType) {
this.srcType = srcType;
if (classPath.length() <= 0) {
throw new IllegalStateException("Empty class path given");
throw new IllegalArgumentException("Empty class path given");
}
cpEntries = explodeClassPath(classPath);

if (cpEntries.isEmpty()) {
throw new IllegalStateException("Empty class path is given.");
throw new IllegalArgumentException("Empty class path is given.");
}
}

Expand Down Expand Up @@ -213,14 +213,9 @@ private List<AnalysisInputLocation<JavaSootClass>> explodeClassPath(@Nonnull Str
*/
private List<AnalysisInputLocation<JavaSootClass>> explodeClassPath(
@Nonnull String jarPath, @Nonnull FileSystem fileSystem) {
try {
return explode(jarPath, fileSystem)
.flatMap(cp -> StreamUtils.optionalToStream(inputLocationForPath(cp)))
.collect(Collectors.toList());

} catch (IllegalArgumentException e) {
throw new IllegalStateException("Malformed class path given: " + jarPath, e);
}
return explode(jarPath, fileSystem)
.flatMap(cp -> StreamUtils.optionalToStream(inputLocationForPath(cp)))
.collect(Collectors.toList());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public JavaModulePathAnalysisInputLocation(
public JavaModulePathAnalysisInputLocation(
@Nonnull String modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourcetype) {
this.sourcetype = sourcetype;
moduleFinder = new ModuleFinder(modulePath, fileSystem);
moduleFinder = new ModuleFinder(modulePath, fileSystem, sourcetype);
}

@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public class ModuleFinder {
private int next = 0;

@Nonnull private final List<Path> modulePathEntries;
private SourceType sourceType = null; // FIXME !
private final SourceType sourceType;

public boolean hasMoreToResolve() {
return next < modulePathEntries.size();
Expand All @@ -75,8 +75,11 @@ public boolean hasMoreToResolve() {
* Helper Class to discover modules in a given module path.
*
* @param modulePath the module path
* @param sourceType
*/
public ModuleFinder(@Nonnull String modulePath, @Nonnull FileSystem fileSystem) {
public ModuleFinder(
@Nonnull String modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourceType) {
this.sourceType = sourceType;
this.modulePathEntries =
JavaClassPathAnalysisInputLocation.explode(modulePath, fileSystem)
.collect(Collectors.toList());
Expand All @@ -92,8 +95,12 @@ public ModuleFinder(@Nonnull String modulePath, @Nonnull FileSystem fileSystem)
}
}

public ModuleFinder(@Nonnull String modulePath, @Nonnull SourceType sourceType) {
this(modulePath, FileSystems.getDefault(), sourceType);
}

public ModuleFinder(@Nonnull String modulePath) {
this(modulePath, FileSystems.getDefault());
this(modulePath, FileSystems.getDefault(), SourceType.Application);
}

@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,13 @@ public abstract class PathBasedAnalysisInputLocation
private final SourceType sourceType;
protected Path path;

protected PathBasedAnalysisInputLocation(Path path, SourceType srcType) {
protected PathBasedAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) {
this.path = path;
this.sourceType = srcType;

if (!Files.exists(path)) {
throw new IllegalArgumentException("The provided path '" + path + "' does not exist.");
}
}

@Nullable
Expand All @@ -96,14 +100,25 @@ public static PathBasedAnalysisInputLocation create(
if (Files.isDirectory(path)) {
inputLocation = new DirectoryBasedAnalysisInputLocation(path, srcType);
} else if (PathUtils.isArchive(path)) {
if (PathUtils.hasExtension(path, FileType.WAR)) {
inputLocation = new WarArchiveAnalysisInputLocation(path, srcType);
} else if (isMultiReleaseJar(path)) { // check if mainfest contains multi release flag
inputLocation = new MultiReleaseJarAnalysisInputLocation(path, srcType);
if (PathUtils.hasExtension(path, FileType.JAR)) {
if (isMultiReleaseJar(path)) {
inputLocation = new MultiReleaseJarAnalysisInputLocation(path, srcType);
} else {
inputLocation = new ArchiveBasedAnalysisInputLocation(path, srcType);
}
} else if (PathUtils.hasExtension(path, FileType.APK)) {
inputLocation = new ApkAnalysisInputLocation(path, srcType);
} else if (PathUtils.hasExtension(path, FileType.WAR)) {
try {
inputLocation = new WarArchiveAnalysisInputLocation(path, srcType);
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
inputLocation = new ArchiveBasedAnalysisInputLocation(path, srcType);
throw new IllegalArgumentException(
"Path '"
+ path.toAbsolutePath()
+ "' has to be pointing to the root of a class container, e.g. directory, jar, zip, apk, war etc.");
}
} else if (PathUtils.hasExtension(path, FileType.CLASS)) {
inputLocation = new ClassFileBasedAnalysisInputLocation(path, srcType);
Expand Down Expand Up @@ -199,11 +214,8 @@ protected Optional<? extends AbstractClassSource<JavaSootClass>> getSingleClass(

private static class ClassFileBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation {
public ClassFileBasedAnalysisInputLocation(
@Nonnull Path classPath, @Nonnull SourceType srcType) {
super(classPath, srcType);
if (!Files.exists(classPath)) {
throw new IllegalArgumentException("The provided .class file does not exist.");
}
@Nonnull Path classFilePath, @Nonnull SourceType srcType) {
super(classFilePath, srcType);
}

@Override
Expand All @@ -228,7 +240,7 @@ public Collection<? extends AbstractClassSource<JavaSootClass>> getClassSources(

private static class DirectoryBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation {

private DirectoryBasedAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) {
private DirectoryBasedAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) {
super(path, srcType);
}

Expand Down Expand Up @@ -265,7 +277,7 @@ public static class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAna

boolean isResolved = false;

private MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) {
private MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) {
super(path, srcType);

int[] tmp;
Expand All @@ -288,7 +300,7 @@ private MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nullable Sourc
}

/** Discovers all input locations for different java versions in this multi release jar */
private void discoverInputLocations(@Nullable SourceType srcType) {
private void discoverInputLocations(@Nonnull SourceType srcType) {
FileSystem fs = null;
try {
fs = fileSystemCache.get(path);
Expand Down Expand Up @@ -523,7 +535,7 @@ public int hashCode() {

private static class ApkAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation {

private ApkAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) {
private ApkAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) {
super(path, srcType);
String jarPath = dex2jar(path);
this.path = Paths.get(jarPath);
Expand Down Expand Up @@ -568,7 +580,7 @@ private static class ArchiveBasedAnalysisInputLocation extends PathBasedAnalysis
}
}));

private ArchiveBasedAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) {
private ArchiveBasedAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) {
super(path, srcType);
}

Expand Down Expand Up @@ -608,16 +620,11 @@ private static final class WarArchiveAnalysisInputLocation
public static int maxAllowedBytesToExtract =
1024 * 1024 * 500; // limit of extracted file size to protect against archive bombs

private WarArchiveAnalysisInputLocation(@Nonnull Path warPath, @Nullable SourceType srcType) {
private WarArchiveAnalysisInputLocation(@Nonnull Path warPath, @Nonnull SourceType srcType)
throws IOException {
super(
Paths.get(
System.getProperty("java.io.tmpdir")
+ File.separator
+ "sootOutput"
+ "-war"
+ warPath.hashCode()
+ "/"),
srcType);
Files.createTempDirectory("sootUp-war-" + warPath.hashCode()).toAbsolutePath(), srcType);

extractWarFile(warPath, path);

Path webInfPath = path.resolve("WEB-INF");
Expand Down Expand Up @@ -789,4 +796,20 @@ public List<String> retrieveServletClasses(String extractedWARPath) {
return classesInXML;
}
}

/**
* Refers to the rt.jar from <=Java8 as an AnalysisInputLocation requires: JAVA_HOME to be set and
* expects the jar in the "lib/" subdirectory. If you need to include the rt.jar from a custom
* Location please make use of JavaClassPathAnalysisInputLocation.
*/
private static class DefaultRTJarAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation {
swissiety marked this conversation as resolved.
Show resolved Hide resolved

private DefaultRTJarAnalysisInputLocation() {
this(SourceType.Library);
}

private DefaultRTJarAnalysisInputLocation(@Nonnull SourceType srcType) {
super(Paths.get(System.getProperty("java.home") + "/lib/rt.jar"), srcType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,17 @@ public void getClassSources() {
final ClassType sig2 =
JavaModuleIdentifierFactory.getInstance().getClassType("System", "java.lang", "java.base");

final JavaView view = project.createView();
final Collection<? extends AbstractClassSource<?>> classSources =
inputLocation.getClassSources(project.createView());
assertTrue(classSources.size() > 26000);
inputLocation.getClassSources(view);
assertTrue(
classSources.size()
> 20000); // not precise as this amount can differ depending on the included runtime
// library
assertTrue(classSources.stream().anyMatch(cs -> cs.getClassType().equals(sig1)));
assertTrue(view.getClass(sig1).isPresent());
assertTrue(classSources.stream().anyMatch(cs -> cs.getClassType().equals(sig2)));
assertTrue(view.getClass(sig2).isPresent());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,30 @@
public class ModuleFinderTest extends AnalysisInputLocationTest {

@Test
public void discoverModuleByName() {
public void discoverJarModuleByName() {
ModuleFinder moduleFinder = new ModuleFinder(jar.toString());
AnalysisInputLocation<JavaSootClass> inputLocation =
moduleFinder.getModule(JavaModuleIdentifierFactory.getModuleSignature("MiniApp"));
assertTrue(inputLocation instanceof PathBasedAnalysisInputLocation);
}

@Test
public void discoverJarModuleInAllModules() {
ModuleFinder moduleFinder = new ModuleFinder(jar.toString());
Collection<ModuleSignature> modules = moduleFinder.getAllModules();
assertTrue(modules.contains(JavaModuleIdentifierFactory.getModuleSignature("MiniApp")));
}

@Test
public void discoverWarModuleByName() {
ModuleFinder moduleFinder = new ModuleFinder(war.toString());
AnalysisInputLocation<JavaSootClass> inputLocation =
moduleFinder.getModule(JavaModuleIdentifierFactory.getModuleSignature("dummyWarApp"));
assertTrue(inputLocation instanceof PathBasedAnalysisInputLocation);
}

@Test
public void discoverModuleInAllModules() {
public void discoverWarModuleInAllModules() {
ModuleFinder moduleFinder = new ModuleFinder(war.toString());
Collection<ModuleSignature> modules = moduleFinder.getAllModules();
assertTrue(modules.contains(JavaModuleIdentifierFactory.getModuleSignature("dummyWarApp")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,6 @@ private Body.BodyBuilder createTrapBody() {

graph.setStartingStmt(startingStmt);

System.out.println(graph);

return builder;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* #L%
*/

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import javax.annotation.Nonnull;
Expand Down Expand Up @@ -84,6 +85,13 @@ public JavaSourcePathAnalysisInputLocation(
this.sourcePaths = sourcePaths;
this.exclusionFilePath = exclusionFilePath;
this.classProvider = new WalaJavaClassProvider(sourcePaths, exclusionFilePath);

final Optional<String> any =
sourcePaths.stream().filter(path -> !Files.exists(Paths.get(path))).findAny();
any.ifPresent(
s -> {
throw new IllegalArgumentException("The provided path " + any.get() + " does not exist.");
});
}

/**
Expand Down