Skip to content

Commit

Permalink
Add ArkTraits
Browse files Browse the repository at this point in the history
  • Loading branch information
rudolf101 committed Jun 18, 2024
1 parent 1a00969 commit 5f6dabe
Show file tree
Hide file tree
Showing 31 changed files with 751 additions and 325 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class EntryPointPositionToValueResolver(

is Argument -> {
val p = method.parameters[position.index]
project.getArgument(p).toMaybe()
getArgument(p).toMaybe()
}

AnyArgument, Result, ResultAnyElement -> error("Unexpected $position")
Expand All @@ -96,7 +96,7 @@ class EntryPointPositionToAccessPathResolver(

is Argument -> {
val p = method.parameters[position.index]
project.getArgument(p)?.toPathOrNull().toMaybe()
getArgument(p)?.toPathOrNull().toMaybe()
}

AnyArgument, Result, ResultAnyElement -> error("Unexpected $position")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ class ForwardNpeFlowFunctions<Method, Statement>(
buildSet {
// Transmit facts on arguments (from 'actual' to 'formal'):
val actualParams = callExpr.args
val formalParams = cp.getArgumentsOf(callee)
val formalParams = getArgumentsOf(callee)
for ((formal, actual) in formalParams.zip(actualParams)) {
addAll(
transmitTaintArgumentActualToFormal(
Expand Down Expand Up @@ -619,7 +619,7 @@ class ForwardNpeFlowFunctions<Method, Statement>(
// Transmit facts on arguments (from 'formal' back to 'actual'), if they are passed by-ref:
if (fact.variable.isOnHeap) {
val actualParams = callExpr.args
val formalParams = cp.getArgumentsOf(callee)
val formalParams = getArgumentsOf(callee)
for ((formal, actual) in formalParams.zip(actualParams)) {
addAll(
transmitTaintArgumentFormalToActual(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ class ForwardTaintFlowFunctions<Method, Statement>(
buildSet {
// Transmit facts on arguments (from 'actual' to 'formal'):
val actualParams = callExpr.args
val formalParams = cp.getArgumentsOf(callee)
val formalParams = getArgumentsOf(callee)
for ((formal, actual) in formalParams.zip(actualParams)) {
addAll(transmitTaintArgumentActualToFormal(fact, from = actual, to = formal))
}
Expand Down Expand Up @@ -543,7 +543,7 @@ class ForwardTaintFlowFunctions<Method, Statement>(
// Transmit facts on arguments (from 'formal' back to 'actual'), if they are passed by-ref:
if (fact.variable.isOnHeap) {
val actualParams = callExpr.args
val formalParams = cp.getArgumentsOf(callee)
val formalParams = getArgumentsOf(callee)
for ((formal, actual) in formalParams.zip(actualParams)) {
addAll(
transmitTaintArgumentFormalToActual(
Expand Down Expand Up @@ -758,7 +758,7 @@ class BackwardTaintFlowFunctions<Method, Statement>(
buildSet {
// Transmit facts on arguments (from 'actual' to 'formal'):
val actualParams = callExpr.args
val formalParams = cp.getArgumentsOf(callee)
val formalParams = getArgumentsOf(callee)
for ((formal, actual) in formalParams.zip(actualParams)) {
addAll(transmitTaintArgumentActualToFormal(fact, from = actual, to = formal))
}
Expand Down Expand Up @@ -813,7 +813,7 @@ class BackwardTaintFlowFunctions<Method, Statement>(
// Transmit facts on arguments (from 'formal' back to 'actual'), if they are passed by-ref:
if (fact.variable.isOnHeap) {
val actualParams = callExpr.args
val formalParams = cp.getArgumentsOf(callee)
val formalParams = getArgumentsOf(callee)
for ((formal, actual) in formalParams.zip(actualParams)) {
addAll(
transmitTaintArgumentFormalToActual(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class UnusedVariableFlowFunctions<Method, Statement>(
return@FlowFunction buildSet {
add(UnusedVariableZeroFact)
val callee = graph.methodOf(calleeStart)
val formalParams = cp.getArgumentsOf(callee)
val formalParams = getArgumentsOf(callee)
for (formal in formalParams) {
add(UnusedVariable(formal.toPath(), callStatement))
}
Expand Down
154 changes: 154 additions & 0 deletions jacodb-analysis/src/main/kotlin/org/jacodb/analysis/util/ArkTraits.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* Copyright 2022 UnitTestBot contributors (utbot.org)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jacodb.analysis.util

import org.jacodb.analysis.ifds.AccessPath
import org.jacodb.analysis.ifds.ElementAccessor
import org.jacodb.analysis.ifds.FieldAccessor
import org.jacodb.analysis.util.toPathOrNull
import org.jacodb.api.common.CommonMethodParameter
import org.jacodb.api.common.cfg.CommonArgument
import org.jacodb.api.common.cfg.CommonCallExpr
import org.jacodb.api.common.cfg.CommonExpr
import org.jacodb.api.common.cfg.CommonValue
import org.jacodb.panda.dynamic.ark.base.AnyType
import org.jacodb.panda.dynamic.ark.base.ArkConstant
import org.jacodb.panda.dynamic.ark.base.ArkEntity
import org.jacodb.panda.dynamic.ark.base.ArkThis
import org.jacodb.panda.dynamic.ark.base.ArkValue
import org.jacodb.panda.dynamic.ark.base.ArrayAccess
import org.jacodb.panda.dynamic.ark.base.CallExpr
import org.jacodb.panda.dynamic.ark.base.CastExpr
import org.jacodb.panda.dynamic.ark.base.Immediate
import org.jacodb.panda.dynamic.ark.base.InstanceFieldRef
import org.jacodb.panda.dynamic.ark.base.ParameterRef
import org.jacodb.panda.dynamic.ark.base.StaticFieldRef
import org.jacodb.panda.dynamic.ark.base.Stmt
import org.jacodb.panda.dynamic.ark.model.ArkFile
import org.jacodb.panda.dynamic.ark.model.ArkMethod
import org.jacodb.panda.dynamic.ark.model.ArkMethodParameter
import org.jacodb.taint.configuration.ConstantValue
import org.jacodb.analysis.util.toPath as _toPath
import org.jacodb.analysis.util.toPathOrNull as _toPathOrNull
import org.jacodb.panda.dynamic.ark.utils.getOperands as _getOperands

interface ArkTraits : Traits<ArkMethod, Stmt> {

override val CommonCallExpr.callee: ArkMethod
get() {
check(this is CallExpr)
return cp.getMethodBySignature(method) ?: error("Method not found: $method")
}

override val ArkMethod.thisInstance: ArkThis
get() = ArkThis(AnyType)

override val ArkMethod.isConstructor: Boolean
get() = false

override fun CommonExpr.toPathOrNull(): AccessPath? {
check(this is ArkEntity)
return this._toPathOrNull()
}

override fun CommonValue.toPathOrNull(): AccessPath? {
check(this is ArkEntity)
return this._toPathOrNull()
}

override fun CommonValue.toPath(): AccessPath {
check(this is ArkEntity)
return this._toPath()
}

override fun getArgument(param: CommonMethodParameter): ParameterRef {
check(param is ArkMethodParameter)
return ParameterRef(index = param.index, type = param.type)
}

override fun getArgumentsOf(method: ArkMethod): List<CommonArgument> {
return method.parameters.map { getArgument(it) }
}

override fun CommonValue.isConstant(): Boolean {
check(this is ArkEntity)
return this is ArkConstant
}

override fun CommonValue.eqConstant(constant: ConstantValue): Boolean {
TODO("Not yet implemented")
}

override fun CommonValue.ltConstant(constant: ConstantValue): Boolean {
TODO("Not yet implemented")
}

override fun CommonValue.gtConstant(constant: ConstantValue): Boolean {
TODO("Not yet implemented")
}

override fun CommonValue.matches(pattern: String): Boolean {
TODO("Not yet implemented")
}

override fun Stmt.getCallExpr(): CallExpr? {
return _getOperands().filterIsInstance<CallExpr>().firstOrNull()
}

override fun CommonExpr.getValues(): Set<ArkValue> {
check(this is ArkEntity)
return _getOperands().filterIsInstance<ArkValue>().toSet()
}

override fun Stmt.getOperands(): List<ArkEntity> {
return _getOperands().toList()
}

companion object : ArkTraits {
lateinit var cp: ArkFile
}
}

fun ArkEntity.toPathOrNull(): AccessPath? = when (this) {
is Immediate -> AccessPath(this, emptyList())

is ArkThis -> AccessPath(this, emptyList())

is ArrayAccess -> {
array.toPathOrNull()?.let {
it + ElementAccessor
}
}

is InstanceFieldRef -> {
instance.toPathOrNull()?.let {
it + FieldAccessor(field.name)
}
}

is StaticFieldRef -> {
AccessPath(null, listOf(FieldAccessor(field.name, isStatic = true)))
}

is CastExpr -> arg.toPathOrNull()

else -> null
}

fun ArkEntity.toPath(): AccessPath {
return toPathOrNull() ?: error("Unable to build access path for value $this")
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import org.jacodb.analysis.ifds.FieldAccessor
import org.jacodb.analysis.util.getArgument
import org.jacodb.analysis.util.toPathOrNull
import org.jacodb.api.common.CommonMethodParameter
import org.jacodb.api.common.CommonProject
import org.jacodb.api.common.cfg.CommonCallExpr
import org.jacodb.api.common.cfg.CommonExpr
import org.jacodb.api.common.cfg.CommonValue
Expand All @@ -37,9 +36,9 @@ import org.jacodb.api.jvm.cfg.JcCastExpr
import org.jacodb.api.jvm.cfg.JcConstant
import org.jacodb.api.jvm.cfg.JcExpr
import org.jacodb.api.jvm.cfg.JcFieldRef
import org.jacodb.api.jvm.cfg.JcImmediate
import org.jacodb.api.jvm.cfg.JcInst
import org.jacodb.api.jvm.cfg.JcInt
import org.jacodb.api.jvm.cfg.JcImmediate
import org.jacodb.api.jvm.cfg.JcStringConstant
import org.jacodb.api.jvm.cfg.JcThis
import org.jacodb.api.jvm.cfg.JcValue
Expand Down Expand Up @@ -97,15 +96,13 @@ interface JcTraits : Traits<JcMethod, JcInst> {
return _callee
}

override fun CommonProject.getArgument(param: CommonMethodParameter): JcArgument? {
check(this is JcClasspath)
override fun getArgument(param: CommonMethodParameter): JcArgument? {
check(param is JcParameter)
return _getArgument(param)
return cp._getArgument(param)
}

override fun CommonProject.getArgumentsOf(method: JcMethod): List<JcArgument> {
check(this is JcClasspath)
return _getArgumentsOf(method)
override fun getArgumentsOf(method: JcMethod): List<JcArgument> {
return cp._getArgumentsOf(method)
}

override fun CommonValue.isConstant(): Boolean {
Expand Down Expand Up @@ -174,7 +171,9 @@ interface JcTraits : Traits<JcMethod, JcInst> {
}

// Ensure that all methods are default-implemented in the interface itself:
companion object : JcTraits
companion object : JcTraits {
lateinit var cp: JcClasspath
}
}

val JcMethod.thisInstance: JcThis
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import org.jacodb.analysis.ifds.FieldAccessor
import org.jacodb.analysis.util.getArgument
import org.jacodb.analysis.util.toPathOrNull
import org.jacodb.api.common.CommonMethodParameter
import org.jacodb.api.common.CommonProject
import org.jacodb.api.common.cfg.CommonCallExpr
import org.jacodb.api.common.cfg.CommonExpr
import org.jacodb.api.common.cfg.CommonValue
Expand Down Expand Up @@ -100,15 +99,13 @@ interface PandaStaticTraits : Traits<PandaMethod, PandaInst> {

override fun PandaInst.getCallExpr(): CommonCallExpr? = _callExpr

override fun CommonProject.getArgument(param: CommonMethodParameter): PandaArgument {
check(this is PandaProject)
override fun getArgument(param: CommonMethodParameter): PandaArgument {
check(param is PandaMethod.Parameter)
return _getArgument(param)
return cp._getArgument(param)
}

override fun CommonProject.getArgumentsOf(method: PandaMethod): List<PandaArgument> {
check(this is PandaProject)
return _getArgumentsOf(method)
override fun getArgumentsOf(method: PandaMethod): List<PandaArgument> {
return cp._getArgumentsOf(method)
}

override fun CommonValue.isConstant(): Boolean {
Expand Down Expand Up @@ -178,7 +175,9 @@ interface PandaStaticTraits : Traits<PandaMethod, PandaInst> {
}

// Ensure that all methods are default-implemented in the interface itself:
companion object : PandaStaticTraits
companion object : PandaStaticTraits {
lateinit var cp: PandaProject
}
}

val PandaMethod.thisInstance: PandaThis
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import org.jacodb.analysis.ifds.FieldAccessor
import org.jacodb.analysis.util.getArgument
import org.jacodb.analysis.util.toPathOrNull
import org.jacodb.api.common.CommonMethodParameter
import org.jacodb.api.common.CommonProject
import org.jacodb.api.common.cfg.CommonCallExpr
import org.jacodb.api.common.cfg.CommonExpr
import org.jacodb.api.common.cfg.CommonValue
Expand Down Expand Up @@ -101,14 +100,12 @@ interface PandaTraits : Traits<PandaMethod, PandaInst> {

override fun PandaInst.getCallExpr(): CommonCallExpr? = _callExpr

override fun CommonProject.getArgument(param: CommonMethodParameter): PandaArgument {
check(this is PandaProject)
override fun getArgument(param: CommonMethodParameter): PandaArgument {
check(param is PandaMethodParameter)
return _getArgument(param)
}

override fun CommonProject.getArgumentsOf(method: PandaMethod): List<PandaArgument> {
check(this is PandaProject)
override fun getArgumentsOf(method: PandaMethod): List<PandaArgument> {
return _getArgumentsOf(method)
}

Expand Down Expand Up @@ -164,17 +161,19 @@ interface PandaTraits : Traits<PandaMethod, PandaInst> {
return re.matches(s)
}

override fun CommonExpr.getValues(): Set<CommonValue> {
override fun CommonExpr.getValues(): Set<PandaValue> {
check(this is PandaExpr)
return TODO()
}

override fun PandaInst.getOperands(): List<CommonExpr> {
override fun PandaInst.getOperands(): List<PandaExpr> {
return operands
}

// Ensure that all methods are default-implemented in the interface itself:
companion object : PandaTraits
companion object : PandaTraits {
lateinit var cp: PandaProject
}
}

val PandaMethod.thisInstance: PandaThis
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package org.jacodb.analysis.util
import org.jacodb.analysis.ifds.AccessPath
import org.jacodb.api.common.CommonMethod
import org.jacodb.api.common.CommonMethodParameter
import org.jacodb.api.common.CommonProject
import org.jacodb.api.common.cfg.CommonArgument
import org.jacodb.api.common.cfg.CommonCallExpr
import org.jacodb.api.common.cfg.CommonExpr
Expand All @@ -44,8 +43,8 @@ interface Traits<out Method, out Statement>

val CommonCallExpr.callee: Method

fun CommonProject.getArgument(param: CommonMethodParameter): CommonArgument?
fun CommonProject.getArgumentsOf(method: @UnsafeVariance Method): List<CommonArgument>
fun getArgument(param: CommonMethodParameter): CommonArgument?
fun getArgumentsOf(method: @UnsafeVariance Method): List<CommonArgument>

fun CommonValue.isConstant(): Boolean
fun CommonValue.eqConstant(constant: ConstantValue): Boolean
Expand Down
Loading

0 comments on commit 5f6dabe

Please sign in to comment.