Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Publishing of libs and plugin on release

on:
release:
types: [ published ]

jobs:
publish:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Setup JDK
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'gradle'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3

- name: Publish api
env:
MAVEN_REPOSITORY_LOGIN: ${{ secrets.MAVEN_REPOSITORY_LOGIN }}
MAVEN_REPOSITORY_PASSWORD: ${{ secrets.MAVEN_REPOSITORY_PASSWORD }}
run: ./gradlew :kotlinx.fuzz.api:publish

- name: Publish engine
env:
MAVEN_REPOSITORY_LOGIN: ${{ secrets.MAVEN_REPOSITORY_LOGIN }}
MAVEN_REPOSITORY_PASSWORD: ${{ secrets.MAVEN_REPOSITORY_PASSWORD }}
run: ./gradlew :kotlinx.fuzz.engine:publish

- name: Publish jazzer
env:
MAVEN_REPOSITORY_LOGIN: ${{ secrets.MAVEN_REPOSITORY_LOGIN }}
MAVEN_REPOSITORY_PASSWORD: ${{ secrets.MAVEN_REPOSITORY_PASSWORD }}
run: ./gradlew :kotlinx.fuzz.jazzer:publish

- name: Publish gradle plugin
env:
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
run: ./gradlew :kotlinx.fuzz.gradle:publishPlugins
69 changes: 68 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,70 @@
# kotlinx.fuzz

`kotlinx.fuzz` is a general purpose fuzzing library for Kotlin
`kotlinx.fuzz` is a general purpose fuzzing library for Kotlin

## Usage

1. Add PLAN lab maven repository to your gradle config:
```kotlin
repositories {
maven(url = "https://plan-maven.apal-research.com")
}
```

2. Add `kotlinx.fuzz` as a dependency:
```kotlin
dependencies {
testRuntimeOnly("org.jetbrains:kotlinx.fuzz.jazzer:0.1.0")
}
```

3. Apply `kotlinx.fuzz` plugin to your project:
```kotlin
plugins {
id("kotlinx.fuzz") version "0.1.0"
}
```

4. Configure plugin:
```kotlin
fuzzConfig {
instrument = listOf("org.example.**")
maxSingleTargetFuzzTime = 10.seconds
}
```

5. Write your fuzz tests:
```kotlin
package org.example

import kotlinx.fuzz.KFuzzTest
import kotlinx.fuzz.KFuzzer

object ExampleTest {
@KFuzzTest
fun foo(data: KFuzzer) {
if (data.int() % 2 == 0) {
if (data.int() % 3 == 2) {
if (data.int() % 31 == 11) {
throw IllegalArgumentException()
}
}
}
}
}
```

6. Run fuzzer:
```bash
~/example » ./gradlew fuzz 1 ↵

> Task fuzz

SampleTarget > public final void org.example.ExampleTest.foo(kotlinx.fuzz.KFuzzer) FAILED
java.lang.IllegalArgumentException
at org.example.ExampleTest.foo(ExampleTest.kt:12)
```

7. Check the fuzzing report in `build/fuzz`

You can see more examples of `kotlinz.fuzz` usage in [`kotlinx.fuzz.test`](kotlinx.fuzz.test)
1 change: 1 addition & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ repositories {
}

dependencies {
implementation(gradleApi())
implementation(libs.kotlin.gradle.plugin)
implementation(libs.diktat.gradle.plugin)
implementation(kotlin("reflect"))
Expand Down
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/constants.kt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
const val GROUP_ID = "kotlinx.fuzz"
const val GROUP_ID = "org.jetbrains"
const val VERSION = "0.0.1"
36 changes: 36 additions & 0 deletions buildSrc/src/main/kotlin/kotlinx/fuzz/publishing.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package kotlinx.fuzz

import org.gradle.api.Project
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.kotlin.dsl.get

fun Project.configurePublishing() {
pluginManager.apply("maven-publish")
project.pluginManager.withPlugin("maven-publish") {
project.afterEvaluate {
project.extensions.configure<PublishingExtension>("publishing") {
publications {
this@publications.create("runner", MavenPublication::class.java) {
groupId = project.group.toString()
artifactId = project.name
version = project.version.toString()

from(components["java"])
}
}
repositories {
maven {
url = uri("https://maven.pkg.github.com/plan-research/kotlin-maven")
credentials {
username = project.findProperty("gpr.user")?.toString()
?: System.getenv("MAVEN_REPOSITORY_LOGIN")
password = project.findProperty("gpr.token")?.toString()
?: System.getenv("MAVEN_REPOSITORY_PASSWORD")
}
}
}
}
}
}
}
4 changes: 4 additions & 0 deletions kotlinx.fuzz.api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import kotlinx.fuzz.configurePublishing

plugins {
id("kotlinx.fuzz.src-module")
}
Expand All @@ -12,3 +14,5 @@ dependencies {
tasks.test {
useJUnitPlatform()
}

configurePublishing()
4 changes: 4 additions & 0 deletions kotlinx.fuzz.engine/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import kotlinx.fuzz.configurePublishing

plugins {
id("kotlinx.fuzz.src-module")
}
Expand All @@ -13,3 +15,5 @@ dependencies {
tasks.test {
useJUnitPlatform()
}

configurePublishing()
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ abstract class KFuzzPlugin : Plugin<Project> {

override fun apply(project: Project) {
project.dependencies {
add("testImplementation", "kotlinx.fuzz:kotlinx.fuzz.api")
add("testRuntimeOnly", "kotlinx.fuzz:kotlinx.fuzz.gradle")
add("testImplementation", "org.jetbrains:kotlinx.fuzz.api")
add("testRuntimeOnly", "org.jetbrains:kotlinx.fuzz.gradle")
}

project.tasks.withType<Test>().configureEach {
Expand Down
4 changes: 4 additions & 0 deletions kotlinx.fuzz.jazzer/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import kotlinx.fuzz.configurePublishing

plugins {
id("kotlinx.fuzz.src-module")
}
Expand All @@ -8,3 +10,5 @@ dependencies {
implementation(kotlin("reflect"))
implementation(libs.jazzer)
}

configurePublishing()
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ internal fun jazzerLogToCsv(file: Path, duration: Duration): String {
}
}

val maxExecNr = statsNoTimeStamps.maxOf { it.execNr }
val maxExecNr = statsNoTimeStamps.maxOfOrNull { it.execNr } ?: 0
val stats = listOf(
LibfuzzerLogEntry(0, 0, 0, 0, 0),
) + statsNoTimeStamps.map { it.addTimestamp(it.execNr * duration.inWholeSeconds / maxExecNr) }
Expand Down
2 changes: 1 addition & 1 deletion kotlinx.fuzz.test/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repositories {

dependencies {
testImplementation(kotlin("test")) // adds green arrow in IDEA (no idea why)
testRuntimeOnly("kotlinx.fuzz:kotlinx.fuzz.jazzer")
testRuntimeOnly("org.jetbrains:kotlinx.fuzz.jazzer")
}

fuzzConfig {
Expand Down
Loading