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

Chore: Fix failing test #39

Merged
merged 10 commits into from
Dec 6, 2024
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.tum.cit.ase</groupId>
<artifactId>ares</artifactId>
<version>2.0.0-Beta-1</version>
<version>2.0.0-Beta-2</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<arch.unit.version>1.3.0</arch.unit.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@
import de.tum.cit.ase.ares.api.architecture.java.wala.ReachabilityChecker;
import de.tum.cit.ase.ares.api.util.FileTools;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -57,7 +54,7 @@ private CallGraphBuilderUtils() {
scope = Java9AnalysisScopeReader.instance.makeJavaBinaryAnalysisScope(
System.getProperty("java.class.path"),
// File translates the path name for Windows and Unix
new File("src/main/java/de/tum/cit/ase/ares/api/architecture/java/wala/exclusions.txt")
FileTools.getResourceAsFile("de/tum/cit/ase/ares/api/templates/architecture/java/exclusions.txt")
);

// Build the class hierarchy
Expand Down Expand Up @@ -149,7 +146,7 @@ public static CallGraph buildCallGraph(String classPathToAnalyze) {
AnalysisOptions options = new AnalysisOptions(scope, customEntryPoints);

// Create call graph builder (n-CFA, context-sensitive, etc.)
CallGraphBuilder<InstanceKey> builder = Util.makeZeroCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), classHierarchy);
CallGraphBuilder<InstanceKey> builder = Util.makeZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), classHierarchy);

// Generate the call graph
return builder.makeCallGraph(options, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public class FileHandlerConstants {
public static final Path WALA_THREAD_MANIPULATION_METHODS = FileTools.resolveOnResources("templates", "architecture" , "java", "wala", "methods", "thread-manipulation.txt");
//</editor-fold>

//<editor-fold desc="Utility Methods">
public static final Path FALSE_POSITIVES_FILE_SYSTEM_INTERACTIONS = FileTools.resolveOnResources("templates", "architecture" , "java", "wala", "false-positives", "false-positives-file.txt");
//</editor-fold>



private FileHandlerConstants() {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
import com.ibm.wala.util.collections.NonNullSingletonIterator;
import com.ibm.wala.util.graph.Graph;

import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.function.Predicate;

import de.tum.cit.ase.ares.api.architecture.java.FileHandlerConstants;
import de.tum.cit.ase.ares.api.util.FileTools;
import org.jspecify.annotations.Nullable;

/**
Expand Down Expand Up @@ -49,14 +53,7 @@ public class CustomDFSPathFinder extends ArrayList<CGNode> {
/**
* Set of methods to exclude from the path
*/
private static final Set<String> toExcludeMethodsFromPath = Set.of(
"java.io.PrintStream.println",
"sun.net.www.protocol.file.Handler.openConnection",
"java.util.Arrays.stream",
"java.io.PrintStream.format",
"java.lang.Throwable.printStackTrace()",
"java.lang.String"
);
private static final Set<String> toExcludeMethodsFromPath = FileTools.readMethodsFromGivenPath(FileHandlerConstants.FALSE_POSITIVES_FILE_SYSTEM_INTERACTIONS);

/**
* Construct a depth-first enumerator starting with a particular node in a directed graph.
Expand Down
43 changes: 41 additions & 2 deletions src/main/java/de/tum/cit/ase/ares/api/util/FileTools.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.tum.cit.ase.ares.api.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -288,8 +290,8 @@ public static String[] generatePackageNameArray(String packageName, int numberOf

/**
* Reads the content of a file and returns it as a set of strings.
* @param filePath
* @return
* @param filePath The path to the file
* @return a set of strings representing the content of the file
*/
public static Set<String> readMethodsFromGivenPath(Path filePath) {
String fileContent = FileTools.readFile(filePath);
Expand All @@ -300,4 +302,41 @@ public static Set<String> readMethodsFromGivenPath(Path filePath) {
.toList();
return new HashSet<>(methods);
}

/**
* Reads the content of a resource file and returns a File
* @param resourcePath The path to the resource file
* @return The File object representing the resource file
* @implNote This method creates a temporary file that will be deleted when the JVM exits
*/
public static File getResourceAsFile(String resourcePath) throws IOException {
// Load the resource as an InputStream
try (InputStream inputStream = FileTools.class.getClassLoader().getResourceAsStream(resourcePath)) {
if (inputStream == null) {
throw new SecurityException(localize("file.tools.resource.not.found", resourcePath));
}

// Create a temporary file using modern NIO APIs
Path tempFilePath;
try {
tempFilePath = Files.createTempFile("resource-", ".txt");
// Register for deletion on JVM exit
tempFilePath.toFile().deleteOnExit();
} catch (IOException e) {
throw new SecurityException(localize("file.tools.create.temp.file.error", resourcePath));
}

// Write the content of the InputStream to the temp file
try {
Files.copy(inputStream, tempFilePath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new SecurityException(localize("file.tools.resource.not.writeable", tempFilePath.toAbsolutePath()), e);
}

// Return the temporary file
return tempFilePath.toFile();
} catch (IOException e) {
throw new SecurityException(localize("file.tools.io.error", resourcePath), e);
}
}
Comment on lines +312 to +341
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation for resourcePath parameter.

The method should validate the resourcePath parameter before processing to prevent potential security issues.

     public static File getResourceAsFile(String resourcePath) throws IOException {
+        // Validate input
+        if (resourcePath == null || resourcePath.isBlank()) {
+            throw new IllegalArgumentException("Resource path cannot be null or empty");
+        }
+        if (resourcePath.contains("..")) {
+            throw new SecurityException("Resource path cannot contain path traversal sequences");
+        }
+
         // Load the resource as an InputStream
         try (InputStream inputStream = FileTools.class.getClassLoader().getResourceAsStream(resourcePath)) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static File getResourceAsFile(String resourcePath) throws IOException {
// Load the resource as an InputStream
try (InputStream inputStream = FileTools.class.getClassLoader().getResourceAsStream(resourcePath)) {
if (inputStream == null) {
throw new SecurityException(localize("file.tools.resource.not.found", resourcePath));
}
// Create a temporary file using modern NIO APIs
Path tempFilePath;
try {
tempFilePath = Files.createTempFile("resource-", ".txt");
// Register for deletion on JVM exit
tempFilePath.toFile().deleteOnExit();
} catch (IOException e) {
throw new SecurityException(localize("file.tools.create.temp.file.error", resourcePath));
}
// Write the content of the InputStream to the temp file
try {
Files.copy(inputStream, tempFilePath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new SecurityException(localize("file.tools.resource.not.writeable", tempFilePath.toAbsolutePath()), e);
}
// Return the temporary file
return tempFilePath.toFile();
} catch (IOException e) {
throw new SecurityException(localize("file.tools.io.error", resourcePath), e);
}
}
public static File getResourceAsFile(String resourcePath) throws IOException {
// Validate input
if (resourcePath == null || resourcePath.isBlank()) {
throw new IllegalArgumentException("Resource path cannot be null or empty");
}
if (resourcePath.contains("..")) {
throw new SecurityException("Resource path cannot contain path traversal sequences");
}
// Load the resource as an InputStream
try (InputStream inputStream = FileTools.class.getClassLoader().getResourceAsStream(resourcePath)) {
if (inputStream == null) {
throw new SecurityException(localize("file.tools.resource.not.found", resourcePath));
}
// Create a temporary file using modern NIO APIs
Path tempFilePath;
try {
tempFilePath = Files.createTempFile("resource-", ".txt");
// Register for deletion on JVM exit
tempFilePath.toFile().deleteOnExit();
} catch (IOException e) {
throw new SecurityException(localize("file.tools.create.temp.file.error", resourcePath));
}
// Write the content of the InputStream to the temp file
try {
Files.copy(inputStream, tempFilePath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new SecurityException(localize("file.tools.resource.not.writeable", tempFilePath.toAbsolutePath()), e);
}
// Return the temporary file
return tempFilePath.toFile();
} catch (IOException e) {
throw new SecurityException(localize("file.tools.io.error", resourcePath), e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ output_tester.output_closed=output stream was closed
output_tester.line_matching_regex_mismatch=matches regular expression:
abstract_line.numbered_line=number %d: "%s"
abstract_line.plain_line=line: "%s"

# FileTools errors
file.tools.resource.not.found=Ares Security Error (Reason: Ares-Code; Stage: Creation): Resource not found: %s.
file.tools.resource.not.readable=Ares Security Error (Reason: Ares-Code; Stage: Creation): Resource %s is not readable.
file.tools.create.temp.file.error=Ares Security Error (Reason: Ares-Code; Stage: Creation): Failed to create a temporary file for resource: %S.
file.tools.resource.not.writeable=Ares Security Error (Reason: Ares-Code; Stage: Creation): Failed to write resource content to temporary file: %s.
file.tools.io.error=Ares Security Error (Reason: Ares-Code; Stage: Creation): Unexpected error while processing resource: %s


# reporting
reporting.problem_location_hint=/// potential problem location: %s ///
# sanitization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,14 @@ output_tester.output_closed=Ausgabe-Stream wurde geschlossen
output_tester.line_matching_regex_mismatch=entspricht regulärem Ausdruck:
abstract_line.numbered_line=Nummer %d: "%s"
abstract_line.plain_line=Zeile: "%s"

# file tools
file.tools.resource.not.found=Ares Sicherheitsfehler (Grund: Ares-Code; Phase: Erstellung): Ressource nicht gefunden: %s.
file.tools.resource.not.readable=Ares Sicherheitsfehler (Grund: Ares-Code; Phase: Erstellung): Ressource %s ist nicht lesbar.
file.tools.create.temp.file.error=Ares Sicherheitsfehler (Grund: Ares-Code; Phase: Erstellung): Fehler beim Erstellen einer tempor�ren Datei f�r die Ressource: %s.
file.tools.resource.not.writeable=Ares Sicherheitsfehler (Grund: Ares-Code; Phase: Erstellung): Fehler beim Schreiben des Ressourceninhalts in die tempor�re Datei: %s.
file.tools.io.error=Ares Sicherheitsfehler (Grund: Ares-Code; Phase: Erstellung): Unerwarteter Fehler bei der Verarbeitung der Ressource: %s.

# reporting
reporting.problem_location_hint=/// Mögliche Problemstelle: %s ///
# sanitization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,7 @@ jdk.internal.reflect.ReflectionFactory.writeObjectForSerialization(java.lang.Cla
sun.reflect.ReflectionFactory.newOptionalDataExceptionForSerialization(boolean)
sun.reflect.ReflectionFactory.writeObjectForSerialization(java.lang.Class)
sun.reflect.ReflectionFactory.newConstructorForSerialization(java.lang.Class)
sun.reflect.ReflectionFactory.hasStaticInitializerForSerialization(java.lang.Class)
sun.reflect.ReflectionFactory.hasStaticInitializerForSerialization(java.lang.Class)
java.lang.System.setErr
java.lang.System.setIn
java.lang.System.setOut
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# The following are excluded from the classpath to make the analysis faster, as they are not relevant for the analysis
jdk/.*
java/time/.*
java/security/.*
java/lang/ProcessImpl.*
java/util/WeakHashMap.*
java/io/BufferedWriter.*
java/util/stream/.*
java/util/concurrent/locks/.*
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
java.io.PrintStream.println
sun.net.www.protocol.file.Handler.openConnection
java.util.Arrays.stream
java.io.PrintStream.format
java.lang.Throwable.printStackTrace()
java.lang.String
org.aspectj.lang.reflect
java.awt.color
java.math.BigInteger
de.tum.cit.ase.ares.api.aop.java.aspectj.adviceandpointcut.JavaAspectJFileSystemAdviceDefinitions
java.lang.Long
sun.swing.SwingUtilities2
javax.swing.UIDefaults
java.nio.charset.CharsetDecoder
sun.nio.cs.StreamEncoder
sun.nio.ch.NativeThreadSet
java.io.PrintWriter.impl
java.util.Objects
java.nio.ByteBuffer
sun.reflect.generics.reflectiveObjects.TypeVariableImpl
java.util.regex.Pattern
java.io.BufferedReader
sun.nio.cs.StreamDecoder
sun.nio.cs.StandardCharsets
sun.awt.image.ImageFetcher
java.io.PrintStream.write
java.io.PrintStream.impl
java.text.NumberFormat
java.lang.ClassValue
java.io.FilterInputStream
java.io.DataOutputStream
java.util.Collections
java.util.HashSet
sun.reflect.generics.factory.CoreReflectionFactory
java.util.logging.Handler.initLocking
org.aspectj.runtime.reflect.Factory
java.awt.Component.checkCoalescing
java.util.KeyValueHolder
sun.security.action.GetPropertyAction
java.io.ObjectOutputStream.writeProxyDesc
java.io.DataInputStream
sun.util.locale.provider.LocaleProviderAdapter
java.lang.Enum
java.util.Hashtable
sun.font.FreetypeFontScaler
java.util.Arrays
java.io.ObjectInputStream.readObject0
java.io.ObjectOutputStream.writeObject0
java.awt.AWTKeyStroke
java.awt.Toolkit
java.util.concurrent.ThreadPoolExecutor.toString()
sun.java2d.loops.GraphicsPrimitive
java.util.AbstractSet
java.lang.invoke.LambdaForm$NamedFunction.equals
java.lang.invoke.LambdaForm$NamedFunction.hashCode
java.util.AbstractList
java.util.ImmutableCollections
java.lang.invoke.MemberName.hashCode()
java.lang.invoke.MemberName.equals
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ java.lang.System.getProperty(Ljava/lang/String;Ljava/lang/String;)
java.beans.PropertyEditorManager.registerEditor(Ljava/lang/Class;Ljava/lang/Class;)
java.beans.PropertyEditorManager.setEditorSearchPath([Ljava/lang/String;)
java.lang.System.getProperties()
java.lang.System.setProperties(Ljava/util/Properties;)
java.lang.System.setProperties(Ljava/util/Properties;)
java.util.ResourceBundle.getBundle
java.lang.System.setErr
java.lang.System.setIn
java.lang.System.setOut
Loading