Skip to content

Commit

Permalink
Merge branch 'refs/heads/neo' into lipen/taint-panda
Browse files Browse the repository at this point in the history
# Conflicts:
#	buildSrc/src/main/kotlin/Dependencies.kt
  • Loading branch information
CaelmBleidd committed Jul 5, 2024
2 parents 5df0be7 + 5046602 commit dd07c11
Show file tree
Hide file tree
Showing 198 changed files with 13,023 additions and 1,913 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ name: Build and run tests

on:
push:
branches:
- develop
- neo
pull_request:
branches:
- develop
Expand Down
38 changes: 37 additions & 1 deletion buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ object Versions {
const val dokka = "1.7.20"
const val gradle_download = "5.3.0"
const val gradle_versions = "0.47.0"
const val hikaricp = "5.0.1"

// hikaricp version compatible with Java 8
const val hikaricp = "4.0.3"

const val guava = "31.1-jre"
const val javax_activation = "1.1"
const val javax_mail = "1.4.7"
Expand Down Expand Up @@ -35,6 +38,9 @@ object Versions {
const val soot_utbot_fork = "4.4.0-FORK-2"
const val sootup = "1.0.0"
const val sqlite = "3.41.2.2"
const val xodus = "2.0.1"
const val rocks_db = "9.1.1"
const val lmdb_java = "0.9.0"
}

fun dep(group: String, name: String, version: String): String = "$group:$name:$version"
Expand Down Expand Up @@ -274,6 +280,30 @@ object Libs {
version = Versions.juliet
)

val xodusUtils = dep(
group = "org.jetbrains.xodus",
name = "xodus-utils",
version = Versions.xodus
)

val xodusApi = dep(
group = "org.jetbrains.xodus",
name = "xodus-openAPI",
version = Versions.xodus
)

val xodusEnvironment = dep(
group = "org.jetbrains.xodus",
name = "xodus-environment",
version = Versions.xodus
)

val lmdb_java = dep(
group = "org.lmdbjava",
name = "lmdbjava",
version = Versions.lmdb_java
)

@Suppress("FunctionName")
fun juliet_cwe(cweNum: Int) = dep(
group = "com.github.UnitTestBot.juliet-java-test-suite",
Expand All @@ -287,6 +317,12 @@ object Libs {
name = "sarif4k",
version = Versions.sarif4k
)

val rocks_db = dep(
group = "org.rocksdb",
name = "rocksdbjni",
version = Versions.rocks_db
)
}

object Plugins {
Expand Down
13 changes: 12 additions & 1 deletion buildSrc/src/main/kotlin/Tests.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.testing.Test
import java.util.*

object Tests {
val lifecycleTag = "lifecycle"
Expand All @@ -11,5 +12,15 @@ fun Test.setup(jacocoTestReport: TaskProvider<*>) {
events("passed", "skipped", "failed")
}
finalizedBy(jacocoTestReport) // report is always generated after tests run
jvmArgs = listOf("-Xmx2g", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=heapdump.hprof")
val majorJavaVersion =
Integer.parseInt(StringTokenizer(System.getProperty("java.specification.version"), ".").nextToken())

maxHeapSize = "8G"

if (majorJavaVersion >= 16) {
jvmArgs = listOf(
"--add-opens", "java.base/java.nio=ALL-UNNAMED", // this is necessary for LMDB
"--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED" // this is necessary for LMDB
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import org.jacodb.impl.features.InMemoryHierarchy
import org.jacodb.impl.features.Usages
import org.jacodb.impl.features.usagesExt
import org.jacodb.testing.WithDB
import org.jacodb.testing.WithRAMDB
import org.jacodb.testing.analysis.NpeExamples
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Disabled
Expand All @@ -42,9 +43,9 @@ import kotlin.time.Duration.Companion.seconds

private val logger = mu.KotlinLogging.logger {}

class IfdsNpeTest : BaseAnalysisTest() {
abstract class IfdsNpeTest : BaseAnalysisTest() {

companion object : WithDB(Usages, InMemoryHierarchy) {
companion object {
@JvmStatic
fun provideClassesForJuliet476(): Stream<Arguments> =
provideClassesForJuliet(476, listOf("null_check_after_deref"))
Expand Down Expand Up @@ -238,3 +239,11 @@ class IfdsNpeTest : BaseAnalysisTest() {
}
}
}

class IfdsNpeSqlTest : IfdsNpeTest() {
companion object : WithDB(Usages, InMemoryHierarchy)
}

class IfdsNpeRAMTest : IfdsNpeTest() {
companion object : WithRAMDB(Usages, InMemoryHierarchy)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import org.jacodb.api.jvm.ext.methods
import org.jacodb.impl.features.InMemoryHierarchy
import org.jacodb.impl.features.Usages
import org.jacodb.testing.WithDB
import org.jacodb.testing.WithRAMDB
import org.jacodb.testing.analysis.SqlInjectionExamples
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
Expand All @@ -39,9 +40,9 @@ import kotlin.time.Duration.Companion.seconds

private val logger = mu.KotlinLogging.logger {}

class IfdsSqlTest : BaseAnalysisTest() {
abstract class IfdsSqlTest : BaseAnalysisTest() {

companion object : WithDB(Usages, InMemoryHierarchy) {
companion object {
@JvmStatic
fun provideClassesForJuliet89(): Stream<Arguments> = provideClassesForJuliet(89, specificBansCwe89)

Expand Down Expand Up @@ -108,3 +109,11 @@ class IfdsSqlTest : BaseAnalysisTest() {
logger.info { "SARIF:\n$sarifJson" }
}
}

class IfdsSqlSqlTest : IfdsSqlTest() {
companion object : WithDB(Usages, InMemoryHierarchy)
}

class IfdsSqlRAMTest : IfdsSqlTest() {
companion object : WithRAMDB(Usages, InMemoryHierarchy)
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import org.jacodb.api.jvm.ext.methods
import org.jacodb.impl.features.InMemoryHierarchy
import org.jacodb.impl.features.Usages
import org.jacodb.testing.WithDB
import org.jacodb.testing.WithRAMDB
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
Expand All @@ -31,9 +32,9 @@ import org.junit.jupiter.params.provider.MethodSource
import java.util.stream.Stream
import kotlin.time.Duration.Companion.seconds

class IfdsUnusedTest : BaseAnalysisTest() {
abstract class IfdsUnusedTest : BaseAnalysisTest() {

companion object : WithDB(Usages, InMemoryHierarchy) {
companion object {
@JvmStatic
fun provideClassesForJuliet563(): Stream<Arguments> = provideClassesForJuliet(
563, listOf(
Expand Down Expand Up @@ -77,3 +78,14 @@ class IfdsUnusedTest : BaseAnalysisTest() {
Assertions.assertTrue(sinks.isNotEmpty())
}
}


class IfdsUnusedSqlTest : IfdsUnusedTest() {

companion object : WithDB(Usages, InMemoryHierarchy)
}

class IfdsUnusedRAMTest : IfdsUnusedTest() {

companion object : WithRAMDB(Usages, InMemoryHierarchy)
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ import org.jacodb.taint.configuration.TaintConfigurationFeature
import org.jacodb.taint.configuration.TaintMark
import org.jacodb.testing.BaseTest
import org.jacodb.testing.WithDB
import org.jacodb.testing.WithRAMDB
import org.jacodb.testing.allClasspath
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test

class TaintFlowFunctionsTest : BaseTest() {
open class TaintFlowFunctionsTest : BaseTest() {

companion object : WithDB(Usages, InMemoryHierarchy), JcTraits

Expand Down Expand Up @@ -216,3 +217,8 @@ class TaintFlowFunctionsTest : BaseTest() {
Assertions.assertEquals(listOf(xTaint), facts)
}
}

class TaintFlowFunctionsRAMTest : TaintFlowFunctionsTest() {

companion object : WithRAMDB(Usages, InMemoryHierarchy)
}
53 changes: 48 additions & 5 deletions jacodb-api-jvm/src/main/kotlin/org/jacodb/api/jvm/Api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ package org.jacodb.api.jvm

import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.future.future
import org.jacodb.api.jvm.storage.ers.EntityRelationshipStorage
import org.jacodb.api.jvm.storage.ers.Transaction
import org.jooq.DSLContext
import java.io.Closeable
import java.io.File
import java.sql.Connection
import java.util.concurrent.ConcurrentHashMap

enum class LocationType {
RUNTIME,
Expand Down Expand Up @@ -142,13 +145,15 @@ interface JcDatabasePersistence : Closeable {

val locations: List<JcByteCodeLocation>

val ers: EntityRelationshipStorage

fun setup()

fun <T> write(action: (DSLContext) -> T): T
fun <T> read(action: (DSLContext) -> T): T
fun <T> write(action: (JCDBContext) -> T): T
fun <T> read(action: (JCDBContext) -> T): T

fun persist(location: RegisteredLocation, classes: List<ClassSource>)
fun findSymbolId(symbol: String): Long?
fun findSymbolId(symbol: String): Long
fun findSymbolName(symbolId: Long): String
fun findLocation(locationId: Long): RegisteredLocation

Expand All @@ -162,6 +167,44 @@ interface JcDatabasePersistence : Closeable {
fun createIndexes() {}
}

/**
* Abstract database access context contains several named context objects.
* Normally, there should be implemented specific context classes for each persistence
* implementation with its specific context objects.
*
* For SQLite persistence, JCDBContext should contain [DSLContext] object and may contain [Connection] object.
*
* For [EntityRelationshipStorage] persistence, JCDBContext should contain [Transaction] object.
*/
@Suppress("UNCHECKED_CAST")
class JCDBContext private constructor() {

private val contextObjects = ConcurrentHashMap<ContextProperty<*>, Any>()

fun <T : Any> setContextObject(contextKey: ContextProperty<T>, contextObject: T) = apply {
contextObjects[contextKey] = contextObject
}

fun <T : Any> getContextObject(property: ContextProperty<T>): T =
contextObjects[property] as? T?
?: throw NullPointerException("JCDBContext doesn't contain context object $property")

fun <T : Any> hasContextObject(property: ContextProperty<T>): Boolean = contextObjects.containsKey(property)

companion object {
fun <T : Any> of(contextKey: ContextProperty<T>, contextObject: T): JCDBContext {
return JCDBContext().apply { this(contextKey, contextObject) }
}

fun empty() = JCDBContext()
}
}

interface ContextProperty<T : Any>

operator fun <T : Any> JCDBContext.invoke(contextKey: ContextProperty<T>, contextObject: T) =
setContextObject(contextKey, contextObject)

interface RegisteredLocation {
val jcLocation: JcByteCodeLocation?
val id: Long
Expand All @@ -170,7 +213,7 @@ interface RegisteredLocation {
}

interface JCDBSymbolsInterner {
val jooq: DSLContext
fun findOrNew(symbol: String): Long
fun flush(conn: Connection)
fun findSymbolName(symbolId: Long): String?
fun flush(context: JCDBContext)
}
4 changes: 1 addition & 3 deletions jacodb-api-jvm/src/main/kotlin/org/jacodb/api/jvm/Index.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@

package org.jacodb.api.jvm

import org.jooq.DSLContext
import org.objectweb.asm.tree.ClassNode

/** index builder */
interface ByteCodeIndexer {

fun index(classNode: ClassNode)

fun flush(jooq: DSLContext)
fun flush(context: JCDBContext)
}

interface JcFeature<REQ, RES> {
Expand All @@ -34,7 +33,6 @@ interface JcFeature<REQ, RES> {
fun newIndexer(jcdb: JcDatabase, location: RegisteredLocation): ByteCodeIndexer

fun onSignal(signal: JcSignal)

}


Expand Down
10 changes: 5 additions & 5 deletions jacodb-api-jvm/src/main/kotlin/org/jacodb/api/jvm/JcClasspath.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@ interface JcClasspath : Closeable, CommonProject {
*/
fun findTypeOrNull(name: String): JcType?

fun classTypeOf(
fun typeOf(
jcClass: JcClassOrInterface,
nullability: Boolean? = null,
annotations: List<JcAnnotation> = listOf(),
): JcClassType
annotations: List<JcAnnotation> = listOf()
): JcRefType

fun arrayTypeOf(
elementType: JcType,
nullability: Boolean? = null,
annotations: List<JcAnnotation> = listOf(),
annotations: List<JcAnnotation> = listOf()
): JcArrayType

fun toJcClass(source: ClassSource): JcClassOrInterface
Expand Down Expand Up @@ -161,7 +161,7 @@ interface JcClasspathExtFeature : JcClasspathFeature {
/**
* semantic is the same as for `tryFindClass` method
*/
fun tryFindType(classpath: JcClasspath, name: String): JcResolvedTypeResult? = null
fun tryFindType(classpath: JcClasspath, name: String, nullable: Boolean? = null): JcResolvedTypeResult? = null

fun findClasses(classpath: JcClasspath, name: String): List<JcClassOrInterface>? = null

Expand Down
8 changes: 6 additions & 2 deletions jacodb-api-jvm/src/main/kotlin/org/jacodb/api/jvm/JcLookup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface JcLookup<Field : JcAccessible, Method : JcAccessible> {
* lookup for field with specific name
* @param name of field
*/
fun field(name: String): Field? = field(name, null)
fun field(name: String): Field? = field(name, typeName = null, fieldKind = FieldKind.ANY)

/**
* lookup for field with specific name and expected type. Used during instructions parsing. In this case field type is preserved
Expand All @@ -38,7 +38,7 @@ interface JcLookup<Field : JcAccessible, Method : JcAccessible> {
* @param name of field
* @param typeName expected type of field
*/
fun field(name: String, typeName: TypeName?): Field?
fun field(name: String, typeName: TypeName?, fieldKind: FieldKind): Field?

/**
* Lookup for method based on name and description:
Expand All @@ -65,4 +65,8 @@ interface JcLookup<Field : JcAccessible, Method : JcAccessible> {
* @param description jvm description of method
*/
fun specialMethod(name: String, description: String): Method?

enum class FieldKind {
INSTANCE, STATIC, ANY
}
}
Loading

0 comments on commit dd07c11

Please sign in to comment.