Skip to content

Crash with IndexOutOfBoundsException When Slicing Code Containing Varargs Method Calls #56

@bystc

Description

@bystc

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions