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

[Bug]: A flaw in the implementation of the Class Hierarchy Algorithm #1101

Open
p4d0rn opened this issue Oct 8, 2024 · 0 comments
Open

[Bug]: A flaw in the implementation of the Class Hierarchy Algorithm #1101

p4d0rn opened this issue Oct 8, 2024 · 0 comments
Assignees
Labels
bug Something isn't working

Comments

@p4d0rn
Copy link

p4d0rn commented Oct 8, 2024

What happened?

Some cases in the Class Hierarchy Algorithm are not considered.
The program for inputting into the CHA is as follows:

package org.demo;

class A {
    public void foo(){}
}

class B extends A {
}

class C extends B{
    @Override
    public void foo() {
        super.foo();
    }
}

The Call Graph result is <org.demo.C: void foo()> -> <org.demo.B: void foo()>
But the expected result should be <org.demo.C: void foo()> -> <org.demo.A: void foo()>

In class C, the foo method contains a call to the parent class's foo method. (super.foo(); is a specialinvoke)
However, it is clear that class B's foo method inherits from the parent class A.

let's examine the resolveCall method of the ClassHierarchyAnalysisAlgorithm class.

  SootMethod targetMethod = findConcreteMethod(view, targetMethodSignature).orElse(null);

  if (targetMethod == null
      || MethodModifier.isStatic(targetMethod.getModifiers())
      || (invokeExpr instanceof JSpecialInvokeExpr)) {
    return Stream.of(targetMethodSignature);
  }

If the invocation statement is a JSpecialInvokeExpr, return the method signature of the current invocation expression which is the variable targetMethodSignature.
In the above case, if targetMethod is not null, resolveCall should return targetMethod.getSignature() for JSpecialInvokeExpr.
This is because when calling a method from the parent class, the callee method could be a method that was inherited (not overridden) from its parent class.
For the two other cases of JSpecialInvokeExpr, which are the invocation of constructor methods and private methods, this issue does not exist.
Additionally, static methods can also be inherited, so looking at the method signature alone cannot determine the class where the target method resides.

Therefore, it is recommended to make the following modifications:

SootMethod targetMethod = findConcreteMethod(view, targetMethodSignature).orElse(null);

if (targetMethod == null) {
    return Stream.of(targetMethodSignature);
}

if(MethodModifier.isStatic(targetMethod.getModifiers())
        || (invokeExpr instanceof JSpecialInvokeExpr)){
    return Stream.of(targetMethod.getSignature());
}

Version

Latest develop branch

Relevant log output

see above.
@p4d0rn p4d0rn added the bug Something isn't working label Oct 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants