Skip to content

Commit

Permalink
Revert context receivers for Traits
Browse files Browse the repository at this point in the history
  • Loading branch information
Lipen committed Nov 29, 2024
1 parent d65094b commit bb8ed47
Show file tree
Hide file tree
Showing 27 changed files with 300 additions and 307 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ import org.jacodb.taint.configuration.TypeMatches

// TODO: replace 'JcInt' with 'CommonInt', etc

context(Traits<CommonMethod, CommonInst>)
open class BasicConditionEvaluator(
val traits: Traits<CommonMethod, CommonInst>,
internal val positionResolver: PositionResolver<Maybe<CommonValue>>,
) : ConditionVisitor<Boolean> {

Expand Down Expand Up @@ -78,35 +78,35 @@ open class BasicConditionEvaluator(
error("Unexpected condition: $condition")
}

override fun visit(condition: IsConstant): Boolean = with(traits) {
override fun visit(condition: IsConstant): Boolean {
positionResolver.resolve(condition.position).onSome {
return it.isConstant()
}
return false
}

override fun visit(condition: ConstantEq): Boolean = with(traits) {
override fun visit(condition: ConstantEq): Boolean {
positionResolver.resolve(condition.position).onSome { value ->
return value.eqConstant(condition.value)
}
return false
}

override fun visit(condition: ConstantLt): Boolean = with(traits) {
override fun visit(condition: ConstantLt): Boolean {
positionResolver.resolve(condition.position).onSome { value ->
return value.ltConstant(condition.value)
}
return false
}

override fun visit(condition: ConstantGt): Boolean = with(traits) {
override fun visit(condition: ConstantGt): Boolean {
positionResolver.resolve(condition.position).onSome { value ->
return value.gtConstant(condition.value)
}
return false
}

override fun visit(condition: ConstantMatches): Boolean = with(traits){
override fun visit(condition: ConstantMatches): Boolean {
positionResolver.resolve(condition.position).onSome { value ->
return value.matches(condition.pattern)
}
Expand Down Expand Up @@ -135,13 +135,13 @@ open class BasicConditionEvaluator(
}
}

context(Traits<CommonMethod, CommonInst>)
class FactAwareConditionEvaluator(
traits: Traits<CommonMethod, CommonInst>,
positionResolver: PositionResolver<Maybe<CommonValue>>,
private val fact: Tainted,
) : BasicConditionEvaluator(traits, positionResolver) {
positionResolver: PositionResolver<Maybe<CommonValue>>,
) : BasicConditionEvaluator(positionResolver) {

override fun visit(condition: ContainsMark): Boolean = with(traits) {
override fun visit(condition: ContainsMark): Boolean {
if (fact.mark != condition.mark) return false
positionResolver.resolve(condition.position).onSome { value ->
val variable = value.toPath()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,29 @@ import org.jacodb.taint.configuration.Result
import org.jacodb.taint.configuration.ResultAnyElement
import org.jacodb.taint.configuration.This

context(Traits<CommonMethod, CommonInst>)
class CallPositionToAccessPathResolver(
val traits: Traits<CommonMethod, CommonInst>,
private val callStatement: CommonInst,
) : PositionResolver<Maybe<AccessPath>> {
private val callExpr = with(traits) {
callStatement.getCallExpr()
?: error("Call statement should have non-null callExpr")
}
private val callExpr = callStatement.getCallExpr()
?: error("Call statement should have non-null callExpr")

override fun resolve(position: Position): Maybe<AccessPath> = with(traits) {when (position) {
override fun resolve(position: Position): Maybe<AccessPath> = when (position) {
AnyArgument -> Maybe.none()
is Argument -> callExpr.args[position.index].toPathOrNull().toMaybe()
This -> (callExpr as? CommonInstanceCallExpr)?.instance?.toPathOrNull().toMaybe()
Result -> (callStatement as? CommonAssignInst)?.lhv?.toPathOrNull().toMaybe()
ResultAnyElement -> (callStatement as? CommonAssignInst)?.lhv?.toPathOrNull().toMaybe()
.fmap { it + ElementAccessor }
}
}
}

context(Traits<CommonMethod, CommonInst>)
class CallPositionToValueResolver(
val traits: Traits<CommonMethod, CommonInst>,
private val callStatement: CommonInst,
) : PositionResolver<Maybe<CommonValue>> {
private val callExpr = with(traits) {
callStatement.getCallExpr()
?: error("Call statement should have non-null callExpr")
}
private val callExpr = callStatement.getCallExpr()
?: error("Call statement should have non-null callExpr")

override fun resolve(position: Position): Maybe<CommonValue> = when (position) {
AnyArgument -> Maybe.none()
Expand All @@ -73,11 +68,11 @@ class CallPositionToValueResolver(
}
}

context(Traits<CommonMethod, CommonInst>)
class EntryPointPositionToValueResolver(
val traits: Traits<CommonMethod, CommonInst>,
private val method: CommonMethod,
) : PositionResolver<Maybe<CommonValue>> {
override fun resolve(position: Position): Maybe<CommonValue> = with(traits) {when (position) {
override fun resolve(position: Position): Maybe<CommonValue> = when (position) {
This -> Maybe.some(method.thisInstance)

is Argument -> {
Expand All @@ -87,14 +82,13 @@ class EntryPointPositionToValueResolver(

AnyArgument, Result, ResultAnyElement -> error("Unexpected $position")
}
}
}

context(Traits<CommonMethod, CommonInst>)
class EntryPointPositionToAccessPathResolver(
val traits: Traits<CommonMethod, CommonInst>,
private val method: CommonMethod,
) : PositionResolver<Maybe<AccessPath>> {
override fun resolve(position: Position): Maybe<AccessPath> = with(traits){ when (position) {
override fun resolve(position: Position): Maybe<AccessPath> = when (position) {
This -> method.thisInstance.toPathOrNull().toMaybe()

is Argument -> {
Expand All @@ -104,5 +98,4 @@ class EntryPointPositionToAccessPathResolver(

AnyArgument, Result, ResultAnyElement -> error("Unexpected $position")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ import org.jacodb.taint.configuration.TaintMethodSink

private val logger = mu.KotlinLogging.logger {}

context(Traits<Method, Statement>)
class NpeAnalyzer<Method, Statement>(
private val traits: Traits<Method, Statement>,
private val graph: ApplicationGraph<Method, Statement>,
) : Analyzer<TaintDomainFact, TaintEvent<Statement>, Method, Statement>
where Method : CommonMethod,
Statement : CommonInst {

override val flowFunctions: ForwardNpeFlowFunctions<Method, Statement> by lazy {
ForwardNpeFlowFunctions(traits, graph)
ForwardNpeFlowFunctions(graph)
}

private val taintConfigurationFeature: TaintConfigurationFeature?
Expand All @@ -66,7 +66,7 @@ class NpeAnalyzer<Method, Statement>(
}

if (edge.to.fact is Tainted && edge.to.fact.mark == TaintMark.NULLNESS) {
if (with(traits) { edge.to.fact.variable.isDereferencedAt(edge.to.statement) }) {
if (edge.to.fact.variable.isDereferencedAt(edge.to.statement)) {
val message = "NPE" // TODO
val vulnerability = TaintVulnerability(message, sink = edge.to)
logger.info {
Expand All @@ -78,8 +78,8 @@ class NpeAnalyzer<Method, Statement>(
}

run {
val callExpr = with(traits) { edge.to.statement.getCallExpr() } ?: return@run
val callee = with(traits) { callExpr.callee }
val callExpr = edge.to.statement.getCallExpr() ?: return@run
val callee = callExpr.callee

val config = taintConfigurationFeature?.let { feature ->
if (callee is JcMethod) {
Expand All @@ -98,9 +98,8 @@ class NpeAnalyzer<Method, Statement>(

// Determine whether 'edge.to' is a sink via config:
val conditionEvaluator = FactAwareConditionEvaluator(
traits,
CallPositionToValueResolver(traits, edge.to.statement),
edge.to.fact,
CallPositionToValueResolver(edge.to.statement),
)
for (item in config.filterIsInstance<TaintMethodSink>()) {
if (item.condition.accept(conditionEvaluator)) {
Expand Down
Loading

0 comments on commit bb8ed47

Please sign in to comment.