-
Notifications
You must be signed in to change notification settings - Fork 20
Description
1. Description
JavaSlicer crashes with an IndexOutOfBoundsException when attempting to slice code that includes varargs (variable arguments) method calls. The crash occurs during the slicing process, specifically when the tool parses the parameters of the varargs method invocation.
2. Steps to Reproduce
Create a Java file named VarargsCrashExample.java with the following code:
import java.util.*;
class Example {
public static void main(String[] args) {
int a = 5, b = 8, c = 12;
int total = sumVarargs(a, b, c); // Varargs method call (3 input arguments)
System.out.println(total); // Slicing Criterion: Track the value of "total"
}
// Varargs method (internally represented as an int[] array)
static int sumVarargs(int... nums) {
int sum = 0;
for (int num : nums) sum += num; // Iterate over the varargs array
return sum;
}
}
Launch JavaSlicer and configure the slicing criterion to the line System.out.println(total) (to track dependencies related to the total variable).
Execute the slicing process.
3. Expected Behavior
The tool should complete slicing without crashing.
The generated slice should include all critical code required to compute the value of total:
Declarations of variables a, b, and c (since they are passed to the varargs method),
The varargs method call sumVarargs(a, b, c),
The full implementation of sumVarargs(int... nums) (including the for-loop that calculates the sum),
The slicing criterion line System.out.println(total).
4. Actual Behavior
JavaSlicer crashes immediately after initiating the slicing process. No slice is generated. The crash is triggered by an IndexOutOfBoundsException, which occurs when the tool tries to access a parameter index that does not exist in the method’s parameter list.
5. Exception Stack Trace
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:458)
at com.github.javaparser.ast.NodeList.get(NodeList.java:131)
at com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParameter(NodeWithParameters.java:40)
at es.upv.mist.slicing.nodes.VariableVisitor.visitCall(VariableVisitor.java:564)
at es.upv.mist.slicing.nodes.VariableVisitor.visit(VariableVisitor.java:527)
at es.upv.mist.slicing.nodes.VariableVisitor.visit(VariableVisitor.java:38)
at com.github.javaparser.ast.expr.MethodCallExpr.accept(MethodCallExpr.java:122)
at es.upv.mist.slicing.nodes.VariableVisitor.lambda$visit$0(VariableVisitor.java:433)
at java.base/java.util.Optional.ifPresent(Optional.java:183)
at es.upv.mist.slicing.nodes.VariableVisitor.visit(VariableVisitor.java:432)
at es.upv.mist.slicing.nodes.VariableVisitor.visit(VariableVisitor.java:38)
at com.github.javaparser.ast.expr.VariableDeclarationExpr.accept(VariableDeclarationExpr.java:118)
at com.github.javaparser.ast.visitor.VoidVisitorAdapter.visit(VoidVisitorAdapter.java:259)
at es.upv.mist.slicing.graphs.GraphNodeContentVisitor.visit(GraphNodeContentVisitor.java:91)
at com.github.javaparser.ast.stmt.ExpressionStmt.accept(ExpressionStmt.java:77)
at es.upv.mist.slicing.graphs.GraphNodeContentVisitor.startVisit(GraphNodeContentVisitor.java:21)
at es.upv.mist.slicing.nodes.VariableVisitor.startVisit(VariableVisitor.java:113)
at es.upv.mist.slicing.nodes.GraphNode.extractVariables(GraphNode.java:66)
at es.upv.mist.slicing.nodes.GraphNode.<init>(GraphNode.java:49)
at es.upv.mist.slicing.nodes.GraphNode.<init>(GraphNode.java:43)
at es.upv.mist.slicing.graphs.jsysdg.JSysCFG$Builder.connectTo(JSysCFG.java:185)
at es.upv.mist.slicing.graphs.cfg.CFGBuilder.connectTo(CFGBuilder.java:72)
at es.upv.mist.slicing.graphs.cfg.CFGBuilder.visit(CFGBuilder.java:132)
at es.upv.mist.slicing.graphs.exceptionsensitive.ESCFG$Builder.visit(ESCFG.java:398)
at es.upv.mist.slicing.graphs.exceptionsensitive.ESCFG$Builder.visit(ESCFG.java:91)
at com.github.javaparser.ast.stmt.ExpressionStmt.accept(ExpressionStmt.java:77)
at com.github.javaparser.ast.visitor.VoidVisitorAdapter.lambda$visit$19(VoidVisitorAdapter.java:109)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at com.github.javaparser.ast.NodeList.forEach(NodeList.java:290)
at com.github.javaparser.ast.visitor.VoidVisitorAdapter.visit(VoidVisitorAdapter.java:109)
at com.github.javaparser.ast.stmt.BlockStmt.accept(BlockStmt.java:76)
at es.upv.mist.slicing.graphs.cfg.CFGBuilder.visitCallableDeclarationBody(CFGBuilder.java:383)
at es.upv.mist.slicing.graphs.cfg.CFGBuilder.visitCallableDeclaration(CFGBuilder.java:371)
at es.upv.mist.slicing.graphs.cfg.CFGBuilder.visit(CFGBuilder.java:355)
at es.upv.mist.slicing.graphs.cfg.CFGBuilder.visit(CFGBuilder.java:37)
at com.github.javaparser.ast.body.MethodDeclaration.accept(MethodDeclaration.java:104)
at es.upv.mist.slicing.graphs.jsysdg.JSysCFG.build(JSysCFG.java:50)
at es.upv.mist.slicing.graphs.jsysdg.JSysDG$Builder.buildCFG(JSysDG.java:74)
at es.upv.mist.slicing.graphs.sdg.SDG$Builder$1.visit(SDG.java:144)
at es.upv.mist.slicing.graphs.sdg.SDG$Builder$1.visit(SDG.java:136)
at com.github.javaparser.ast.body.MethodDeclaration.accept(MethodDeclaration.java:104)
at com.github.javaparser.ast.visitor.VoidVisitorAdapter.lambda$visit$31(VoidVisitorAdapter.java:154)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at com.github.javaparser.ast.NodeList.forEach(NodeList.java:290)
at com.github.javaparser.ast.visitor.VoidVisitorAdapter.visit(VoidVisitorAdapter.java:154)
at com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.accept(ClassOrInterfaceDeclaration.java:98)
at com.github.javaparser.ast.visitor.VoidVisitorAdapter.lambda$visit$43(VoidVisitorAdapter.java:175)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at com.github.javaparser.ast.NodeList.forEach(NodeList.java:290)
at com.github.javaparser.ast.visitor.VoidVisitorAdapter.visit(VoidVisitorAdapter.java:175)
at com.github.javaparser.ast.CompilationUnit.accept(CompilationUnit.java:133)
at com.github.javaparser.ast.visitor.VoidVisitorAdapter.visit(VoidVisitorAdapter.java:630)
at com.github.javaparser.ast.NodeList.accept(NodeList.java:282)
at es.upv.mist.slicing.graphs.sdg.SDG$Builder.buildCFGs(SDG.java:136)
at es.upv.mist.slicing.graphs.sdg.SDG$Builder.build(SDG.java:126)
at es.upv.mist.slicing.graphs.jsysdg.JSysDG$Builder.build(JSysDG.java:44)
at es.upv.mist.slicing.graphs.sdg.SDG.build(SDG.java:73)
at es.upv.mist.slicing.cli.Slicer.slice(Slicer.java:208)
at es.upv.mist.slicing.cli.Slicer.main(Slicer.java:286)
6. Root Cause of IndexOutOfBoundsException
The crash stems from incomplete handling of Java varargs by JavaParser. Varargs (e.g., int... nums) are syntactic sugar for single array parameters, but JavaParser’s AST incorrectly mismatches the method’s actual parameter count (1 array) with the number of call arguments (3 in the example).
JavaSlicer, relying on this flawed AST, tries to access parameter indices matching the call arguments (e.g., index 1 for a 1-element parameter list), triggering the IndexOutOfBoundsException.