├── .java-version ├── settings.gradle.kts ├── .gitignore ├── README.md ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── renovate.json ├── .gitattributes ├── src ├── commonMain │ └── kotlin │ │ └── io │ │ └── github │ │ └── detekt │ │ └── sarif4k │ │ ├── SarifSerializer.kt │ │ ├── JsonElementExtensions.kt │ │ ├── Merging.kt │ │ └── SarifDataBindings.kt └── jvmTest │ ├── kotlin │ └── io │ │ └── github │ │ └── detekt │ │ └── sarif4k │ │ ├── util │ │ └── TestUtils.kt │ │ ├── SarifMergingTest.kt │ │ ├── PropertyBagTest.kt │ │ └── SarifSerializerTest.kt │ └── resources │ ├── test.sarif.json │ ├── input_2.sarif.json │ ├── input_1_other_uribaseid.sarif.json │ ├── input_1.sarif.json │ ├── input_2_different_tool.sarif.json │ ├── output.sarif.json │ ├── output_other_uribaseid.sarif.json │ └── output_different_tool.sarif.json ├── gradle.properties ├── .github └── workflows │ ├── dependencies.yaml │ ├── release.yml │ └── merge-check.yml ├── RELEASING.md ├── gradlew.bat ├── gradlew └── LICENSE /.java-version: -------------------------------------------------------------------------------- 1 | 21 2 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "sarif4k" 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .idea 3 | build/ 4 | /.kotlin/ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sarif4k 2 | Kotlin data bindings for the Static Analysis Results Interchange Format (SARIF) 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detekt/sarif4k/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "labels": [ 4 | "dependencies" 5 | ], 6 | "extends": [ 7 | "config:recommended", 8 | "helpers:pinGitHubActionDigests" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | 3 | *.bat text eol=crlf 4 | 5 | *.css diff=css 6 | *.htm diff=html 7 | *.html diff=html 8 | *.md diff=markdown 9 | 10 | *.jar binary 11 | *.png binary 12 | *.otf binary 13 | *.eot binary 14 | *.ttf binary 15 | *.woff binary 16 | *.woff2 binary 17 | *.ico binary 18 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/io/github/detekt/sarif4k/SarifSerializer.kt: -------------------------------------------------------------------------------- 1 | package io.github.detekt.sarif4k 2 | 3 | import kotlinx.serialization.json.Json 4 | 5 | public object SarifSerializer { 6 | private val json = Json { 7 | prettyPrint = true 8 | prettyPrintIndent = " " 9 | } 10 | 11 | public fun toMinifiedJson(sarif: SarifSchema210): String = Json.encodeToString(sarif) 12 | 13 | public fun toJson(sarif: SarifSchema210): String = json.encodeToString(sarif) + "\n" 14 | 15 | public fun fromJson(json: String): SarifSchema210 = Json.decodeFromString(json) 16 | } 17 | -------------------------------------------------------------------------------- /src/jvmTest/kotlin/io/github/detekt/sarif4k/util/TestUtils.kt: -------------------------------------------------------------------------------- 1 | package io.github.detekt.sarif4k.util 2 | 3 | import java.io.InputStream 4 | import java.io.InputStreamReader 5 | 6 | internal object Resources 7 | 8 | internal fun resourceStream(name: String): InputStream { 9 | val explicitName = if (name.startsWith("/")) name else "/$name" 10 | val resource = Resources::class.java.getResourceAsStream(explicitName) 11 | requireNotNull(resource) { "Make sure the resource '$name' exists!" } 12 | return resource 13 | } 14 | 15 | internal fun resourceAsTextContent(name: String) = InputStreamReader(resourceStream(name)).use { it.readText() } 16 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | GROUP=io.github.detekt.sarif4k 2 | VERSION=0.7.0-SNAPSHOT 3 | 4 | # OOM in Dokka: https://github.com/Kotlin/dokka/issues/1405 5 | org.gradle.jvmargs=-Xmx1G -XX:MaxMetaspaceSize=512M 6 | 7 | kotlin.code.style=official 8 | 9 | # Kotlin Multiplatform Projects are an Alpha feature. See: https://kotlinlang.org/docs/reference/evolution/components-stability.html. 10 | kotlin.mpp.stability.nowarn=true 11 | 12 | # Kotlin Native architecture warning suppression. 13 | # Affects Linux and Windows users / GitHub Actions, but they cannot do anything about it. 14 | # > Some Kotlin/Native targets cannot be built on this mingw_x64 machine and are disabled: 15 | # > * In project ':': 16 | # > * target 'macosX64' (can be built with one of the hosts: macos_x64, macos_arm64) 17 | kotlin.native.ignoreDisabledTargets=true 18 | -------------------------------------------------------------------------------- /.github/workflows/dependencies.yaml: -------------------------------------------------------------------------------- 1 | name: "Dependencies" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | jobs: 10 | dependency-submission: 11 | name: "Submit Dependency Graph" 12 | runs-on: ubuntu-latest 13 | 14 | permissions: 15 | # The Dependency Submission API requires write permission. 16 | contents: write 17 | 18 | steps: 19 | 20 | - name: "Checkout sources" 21 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 22 | 23 | - name: "Set up Java" 24 | uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5 25 | with: 26 | distribution: 'temurin' 27 | java-version-file: '.java-version' 28 | 29 | - name: "Generate and submit dependency graph" 30 | # Note: this `uses: gradle/actions/setup-gradle@v3` under the hood. 31 | uses: gradle/actions/dependency-submission@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5 32 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "Release" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | publish: 10 | name: "Publish to Sonatype" 11 | runs-on: macos-latest 12 | 13 | permissions: 14 | contents: read 15 | 16 | steps: 17 | 18 | - name: "Checkout sources" 19 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 20 | 21 | - name: "Set up Java" 22 | uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5 23 | with: 24 | distribution: 'zulu' 25 | java-version-file: '.java-version' 26 | 27 | - name: "Setup gradle" 28 | uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5 29 | 30 | - name: "Build" 31 | run: ./gradlew build 32 | 33 | - name: "Publish package" 34 | run: ./gradlew publishToSonatype 35 | env: 36 | ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} 37 | ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} 38 | -------------------------------------------------------------------------------- /RELEASING.md: -------------------------------------------------------------------------------- 1 | # Releasing 2 | 3 | - Update 4 | - the version in `gradle.properties` to a non-SNAPSHOT version. 5 | - `README.md` with the new version. 6 | - `git commit -am "Prepare for release X.Y.Z"` (where X.Y.Z is the new version) 7 | - `git tag -a X.Y.Z -m "Version X.Y.Z"` (where X.Y.Z is the new version) 8 | - Publish the version 9 | - Run`./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository` locally 10 | - Create a new release in the releases tab on GitHub 11 | - Verify the version is published 12 | - https://oss.sonatype.org/content/groups/public/io/github/detekt/sarif4k/sarif4k 13 | - https://repo.maven.apache.org/maven2/io/github/detekt/sarif4k/sarif4k/ 14 | - https://repo1.maven.org/maven2/io/github/detekt/sarif4k/sarif4k/ 15 | - Visit [Sonatype Nexus](https://oss.sonatype.org/) to debug if there is anything wrong. 16 | - Update 17 | - `gradle.properties` to the next SNAPSHOT version (X.Y.Z) 18 | - `git commit -am "Prepare next development version."` 19 | - `git push && git push --tags` 20 | - Wait for the [publish-snapshot.yml](.github/workflows/publish-snapshot.yml) action to complete. 21 | -------------------------------------------------------------------------------- /src/jvmTest/kotlin/io/github/detekt/sarif4k/SarifMergingTest.kt: -------------------------------------------------------------------------------- 1 | package io.github.detekt.sarif4k 2 | 3 | import io.github.detekt.sarif4k.util.resourceAsTextContent 4 | import org.junit.jupiter.api.Test 5 | import kotlin.test.assertEquals 6 | 7 | class SarifMergingTest { 8 | @Test 9 | fun `merge output from sarifs of the same tool`() { 10 | testMerge( 11 | "output.sarif.json", 12 | "input_1.sarif.json", 13 | "input_2.sarif.json" 14 | ) 15 | } 16 | 17 | @Test 18 | fun `merge output from sarifs with different tools`() { 19 | testMerge( 20 | "output_different_tool.sarif.json", 21 | "input_1.sarif.json", 22 | "input_2_different_tool.sarif.json" 23 | ) 24 | } 25 | 26 | @Test 27 | fun `merge output from sarifs of the same tool with different uriBaseIds`() { 28 | testMerge( 29 | "output_other_uribaseid.sarif.json", 30 | "input_1.sarif.json", 31 | "input_1_other_uribaseid.sarif.json" 32 | ) 33 | } 34 | 35 | private fun testMerge(expectedOutputFile: String, vararg inputFiles: String) { 36 | val inputs = inputFiles.map { 37 | SarifSerializer.fromJson(resourceAsTextContent(it)) 38 | } 39 | 40 | val actual = inputs.reduce(SarifSchema210::merge) 41 | val expected = SarifSerializer.fromJson(resourceAsTextContent(expectedOutputFile)) 42 | assertEquals(expected, actual) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /.github/workflows/merge-check.yml: -------------------------------------------------------------------------------- 1 | name: "Merge Checks" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - '*' 10 | 11 | jobs: 12 | build: 13 | name: "Build Project" 14 | runs-on: ${{ matrix.os }} 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | os: 19 | - macos-latest 20 | - ubuntu-latest 21 | if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} 22 | 23 | permissions: 24 | contents: read 25 | 26 | steps: 27 | 28 | - name: "Checkout sources" 29 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 30 | 31 | - name: "Set up Java" 32 | uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5 33 | with: 34 | distribution: ${{ (runner.os == 'macOS' && runner.arch == 'ARM64') && 'zulu' || 'temurin' }} 35 | java-version-file: '.java-version' 36 | 37 | - name: "Setup gradle" 38 | uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5 39 | 40 | - name: "Run Gradle tasks" 41 | run: ./gradlew build publishToMavenLocal 42 | 43 | - name: "Upload 'Test Report (${{ matrix.os }})' artifact" 44 | uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 45 | if: success() || failure() 46 | with: 47 | name: 'Test Report (${{ matrix.os }})' 48 | path: | 49 | build/reports/tests/allTests/ 50 | -------------------------------------------------------------------------------- /src/jvmTest/resources/test.sarif.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", 3 | "version": "2.1.0", 4 | "runs": [ 5 | { 6 | "originalUriBaseIds": { 7 | "%SRCROOT%": { 8 | "uri": "file:///Users/tester/detekt/" 9 | } 10 | }, 11 | "results": [ 12 | { 13 | "locations": [ 14 | { 15 | "physicalLocation": { 16 | "artifactLocation": { 17 | "uri": "TestFile.kt", 18 | "uriBaseId": "%SRCROOT%" 19 | }, 20 | "region": { 21 | "startColumn": 1, 22 | "startLine": 1 23 | } 24 | }, 25 | "properties": { 26 | "tags": [ 27 | "tag" 28 | ], 29 | "foo": { 30 | "bar": "buz" 31 | } 32 | } 33 | } 34 | ], 35 | "message": { 36 | "text": "TestMessage" 37 | }, 38 | "ruleId": "detekt.TestSmellA.TestSmellA" 39 | }, 40 | { 41 | "locations": [ 42 | { 43 | "physicalLocation": { 44 | "artifactLocation": { 45 | "uri": "TestFile.kt", 46 | "uriBaseId": "%SRCROOT%" 47 | }, 48 | "region": { 49 | "startColumn": 1, 50 | "startLine": 1 51 | } 52 | } 53 | } 54 | ], 55 | "message": { 56 | "text": "TestMessage" 57 | }, 58 | "ruleId": "detekt.TestSmellB.TestSmellB" 59 | } 60 | ], 61 | "tool": { 62 | "driver": { 63 | "downloadUri": "https://github.com/detekt/detekt/releases/download/v1.0.0/detekt", 64 | "fullName": "detekt", 65 | "guid": "022ca8c2-f6a2-4c95-b107-bb72c43263f3", 66 | "informationUri": "https://detekt.github.io/detekt", 67 | "language": "en", 68 | "name": "detekt", 69 | "organization": "detekt", 70 | "rules": [], 71 | "semanticVersion": "1.0.0", 72 | "version": "1.0.0" 73 | } 74 | } 75 | } 76 | ] 77 | } 78 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/io/github/detekt/sarif4k/JsonElementExtensions.kt: -------------------------------------------------------------------------------- 1 | package io.github.detekt.sarif4k 2 | 3 | import kotlinx.serialization.json.JsonArray 4 | import kotlinx.serialization.json.JsonElement 5 | import kotlinx.serialization.json.JsonNull 6 | import kotlinx.serialization.json.JsonObject 7 | import kotlinx.serialization.json.JsonPrimitive 8 | 9 | // Extracted from https://github.com/Kotlin/kotlinx.serialization/issues/296#issuecomment-1859572541 10 | private fun Any?.toJsonElement(): JsonElement = when (this) { 11 | null -> JsonNull 12 | is JsonElement -> this 13 | is Map<*, *> -> toJsonElement() 14 | is Iterable<*> -> toJsonElement() 15 | is Boolean -> JsonPrimitive(this) 16 | is Number -> JsonPrimitive(this) 17 | is String -> JsonPrimitive(this) 18 | is Enum<*> -> JsonPrimitive(this.name) 19 | is ByteArray -> this.toList().toJsonElement() 20 | is CharArray -> this.toList().toJsonElement() 21 | is ShortArray -> this.toList().toJsonElement() 22 | is IntArray -> this.toList().toJsonElement() 23 | is LongArray -> this.toList().toJsonElement() 24 | is FloatArray -> this.toList().toJsonElement() 25 | is DoubleArray -> this.toList().toJsonElement() 26 | is BooleanArray -> this.toList().toJsonElement() 27 | is Array<*> -> toJsonElement() 28 | else -> error("Can't serialize unknown type: $this") 29 | } 30 | 31 | internal fun Map<*, *>.toJsonElement(): JsonObject { 32 | val map = this.map { (key, value) -> 33 | key as? String ?: error("$key is not allowed as JSON key, please use a String!") 34 | key to value.toJsonElement() 35 | } 36 | return JsonObject(map.toMap()) 37 | } 38 | 39 | private fun Iterable<*>.toJsonElement(): JsonArray { 40 | return JsonArray(this.map { it.toJsonElement() }) 41 | } 42 | 43 | private fun Array<*>.toJsonElement(): JsonArray { 44 | return JsonArray(this.map { it.toJsonElement() }) 45 | } 46 | 47 | private fun JsonElement.toNativeObject(): Any? = when (this) { 48 | JsonNull -> null 49 | is JsonArray -> this.map { it.toNativeObject() } 50 | is JsonObject -> this.toNativeObject() 51 | is JsonPrimitive -> if (isString) content else { 52 | content 53 | .toBooleanStrictOrNull() 54 | ?: content.toLongOrNull() 55 | ?: content.toDoubleOrNull() 56 | ?: error("Unknown primitive: $content") 57 | } 58 | } 59 | 60 | internal fun JsonObject.toNativeObject(): Map { 61 | return this.map { (key, value) -> key to value.toNativeObject() }.toMap() 62 | } 63 | -------------------------------------------------------------------------------- /src/jvmTest/kotlin/io/github/detekt/sarif4k/PropertyBagTest.kt: -------------------------------------------------------------------------------- 1 | package io.github.detekt.sarif4k 2 | 3 | import kotlinx.serialization.json.Json 4 | import org.junit.jupiter.params.ParameterizedTest 5 | import org.junit.jupiter.params.provider.Arguments.arguments 6 | import org.junit.jupiter.params.provider.MethodSource 7 | import kotlin.test.Test 8 | import kotlin.test.assertEquals 9 | import kotlin.test.assertNotNull 10 | import kotlin.test.fail 11 | 12 | class PropertyBagTest { 13 | 14 | @ParameterizedTest 15 | @MethodSource("data") 16 | fun encode(value: Map, json: String) { 17 | assertEquals(json, Json.encodeToString(PropertyBag.serializer(), PropertyBag(value))) 18 | } 19 | 20 | @ParameterizedTest 21 | @MethodSource("data") 22 | fun decode(value: Map, json: String) { 23 | assertEquals(PropertyBag(value), Json.decodeFromString(PropertyBag.serializer(), json)) 24 | } 25 | 26 | @Test 27 | fun noTags() { 28 | assertEquals(null, PropertyBag(mapOf()).tags) 29 | } 30 | 31 | @Test 32 | fun nullTags() { 33 | assertEquals(null, PropertyBag(mapOf("tags" to null)).tags) 34 | } 35 | 36 | @Test 37 | fun emptyTags() { 38 | assertEquals(emptyList(), PropertyBag(mapOf("tags" to emptyList())).tags) 39 | } 40 | 41 | @Test 42 | fun tags() { 43 | assertEquals(listOf("foo", "bar"), PropertyBag(mapOf("tags" to listOf("foo", "bar"))).tags) 44 | } 45 | 46 | @Test 47 | fun incorrectTags_noList() { 48 | try { 49 | PropertyBag(mapOf("tags" to 1)).tags 50 | fail() 51 | } catch (e: IllegalStateException) { 52 | assertEquals("Expected a Collection for the value of tags property: 1.", e.message) 53 | assertNotNull(e.cause) 54 | } 55 | } 56 | 57 | @Test 58 | fun incorrectTags_noString() { 59 | try { 60 | PropertyBag(mapOf("tags" to listOf("foo", true, "bar"))).tags 61 | fail() 62 | } catch (e: IllegalStateException) { 63 | assertEquals("Expected a String tag at index 1: true.", e.message) 64 | assertNotNull(e.cause) 65 | } 66 | } 67 | 68 | companion object { 69 | @JvmStatic 70 | fun data() = listOf( 71 | arguments(mapOf(), """{}"""), 72 | arguments(mapOf("foo" to null), """{"foo":null}"""), 73 | arguments( 74 | mapOf("foo" to mapOf("bar" to listOf("1", 2L, false, 3.5))), 75 | """{"foo":{"bar":["1",2,false,3.5]}}""", 76 | ), 77 | arguments(mapOf("tags" to null), """{"tags":null}"""), 78 | arguments(mapOf("tags" to emptyList()), """{"tags":[]}"""), 79 | ) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | 74 | 75 | @rem Execute Gradle 76 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* 77 | 78 | :end 79 | @rem End local scope for the variables with windows NT shell 80 | if %ERRORLEVEL% equ 0 goto mainEnd 81 | 82 | :fail 83 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 84 | rem the _cmd.exe /c_ return code! 85 | set EXIT_CODE=%ERRORLEVEL% 86 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 87 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 88 | exit /b %EXIT_CODE% 89 | 90 | :mainEnd 91 | if "%OS%"=="Windows_NT" endlocal 92 | 93 | :omega 94 | -------------------------------------------------------------------------------- /src/jvmTest/resources/input_2.sarif.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", 3 | "version": "2.1.0", 4 | "runs": [ 5 | { 6 | "originalUriBaseIds": { 7 | "%SRCROOT%": { 8 | "uri": "file:///Users/tester/detekt/" 9 | } 10 | }, 11 | "results": [ 12 | { 13 | "level": "warning", 14 | "locations": [ 15 | { 16 | "physicalLocation": { 17 | "artifactLocation": { 18 | "uri": "TestFile.kt", 19 | "uriBaseId": "%SRCROOT%" 20 | }, 21 | "region": { 22 | "startColumn": 1, 23 | "startLine": 1 24 | } 25 | } 26 | } 27 | ], 28 | "message": { 29 | "text": "TestMessage" 30 | }, 31 | "ruleId": "detekt.TestSmellD.TestSmellD" 32 | }, 33 | { 34 | "level": "warning", 35 | "locations": [ 36 | { 37 | "physicalLocation": { 38 | "artifactLocation": { 39 | "uri": "TestFile.kt", 40 | "uriBaseId": "%SRCROOT%" 41 | }, 42 | "region": { 43 | "startColumn": 1, 44 | "startLine": 1 45 | } 46 | } 47 | } 48 | ], 49 | "message": { 50 | "text": "TestMessage" 51 | }, 52 | "ruleId": "detekt.TestSmellE.TestSmellE" 53 | }, 54 | { 55 | "level": "warning", 56 | "locations": [ 57 | { 58 | "physicalLocation": { 59 | "artifactLocation": { 60 | "uri": "TestFile.kt", 61 | "uriBaseId": "%SRCROOT%" 62 | }, 63 | "region": { 64 | "startColumn": 1, 65 | "startLine": 1 66 | } 67 | } 68 | } 69 | ], 70 | "message": { 71 | "text": "TestMessage" 72 | }, 73 | "ruleId": "detekt.TestSmellF.TestSmellF" 74 | } 75 | ], 76 | "tool": { 77 | "driver": { 78 | "downloadUri": "https://github.com/detekt/detekt/releases/download/v1.0.0/detekt", 79 | "fullName": "detekt", 80 | "guid": "022ca8c2-f6a2-4c95-b107-bb72c43263f3", 81 | "informationUri": "https://detekt.dev", 82 | "language": "en", 83 | "name": "detekt", 84 | "organization": "detekt", 85 | "rules": [ 86 | { 87 | "helpUri": "https://detekt.dev/potential-bugs.html#deprecation", 88 | "id": "detekt.potential-bugs.Deprecation", 89 | "name": "Deprecation", 90 | "shortDescription": { 91 | "text": "NoDeprecated" 92 | } 93 | } 94 | ], 95 | "semanticVersion": "1.0.0", 96 | "version": "1.0.0" 97 | } 98 | } 99 | } 100 | ], 101 | "properties": { 102 | "tags": [ 103 | "tag", 104 | "tag2" 105 | ], 106 | "bar": 5 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/jvmTest/resources/input_1_other_uribaseid.sarif.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", 3 | "version": "2.1.0", 4 | "runs": [ 5 | { 6 | "originalUriBaseIds": { 7 | "%SRCROOT%": { 8 | "uri": "file:///Users/tester2/detekt/" 9 | } 10 | }, 11 | "results": [ 12 | { 13 | "level": "warning", 14 | "locations": [ 15 | { 16 | "physicalLocation": { 17 | "artifactLocation": { 18 | "uri": "TestFile2.kt", 19 | "uriBaseId": "%SRCROOT%" 20 | }, 21 | "region": { 22 | "startColumn": 1, 23 | "startLine": 1 24 | } 25 | } 26 | } 27 | ], 28 | "message": { 29 | "text": "TestMessage" 30 | }, 31 | "ruleId": "detekt.TestSmellD.TestSmellD" 32 | }, 33 | { 34 | "level": "warning", 35 | "locations": [ 36 | { 37 | "physicalLocation": { 38 | "artifactLocation": { 39 | "uri": "TestFile2.kt", 40 | "uriBaseId": "%SRCROOT%" 41 | }, 42 | "region": { 43 | "startColumn": 1, 44 | "startLine": 1 45 | } 46 | } 47 | } 48 | ], 49 | "message": { 50 | "text": "TestMessage" 51 | }, 52 | "ruleId": "detekt.TestSmellE.TestSmellE" 53 | }, 54 | { 55 | "level": "warning", 56 | "locations": [ 57 | { 58 | "physicalLocation": { 59 | "artifactLocation": { 60 | "uri": "TestFile2.kt", 61 | "uriBaseId": "%SRCROOT%" 62 | }, 63 | "region": { 64 | "startColumn": 1, 65 | "startLine": 1 66 | } 67 | } 68 | } 69 | ], 70 | "message": { 71 | "text": "TestMessage" 72 | }, 73 | "ruleId": "detekt.TestSmellF.TestSmellF" 74 | } 75 | ], 76 | "tool": { 77 | "driver": { 78 | "downloadUri": "https://github.com/detekt/detekt/releases/download/v1.0.0/detekt", 79 | "fullName": "detekt", 80 | "guid": "022ca8c2-f6a2-4c95-b107-bb72c43263f3", 81 | "informationUri": "https://detekt.dev", 82 | "language": "en", 83 | "name": "detekt", 84 | "organization": "detekt", 85 | "rules": [ 86 | { 87 | "helpUri": "https://detekt.dev/potential-bugs.html#deprecation", 88 | "id": "detekt.potential-bugs.Deprecation", 89 | "name": "Deprecation", 90 | "shortDescription": { 91 | "text": "NoDeprecated" 92 | } 93 | } 94 | ], 95 | "semanticVersion": "1.0.0", 96 | "version": "1.0.0" 97 | } 98 | } 99 | } 100 | ], 101 | "properties": { 102 | "tags": [ 103 | "tag", 104 | "tag2" 105 | ], 106 | "bar": 5 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/jvmTest/resources/input_1.sarif.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", 3 | "version": "2.1.0", 4 | "runs": [ 5 | { 6 | "originalUriBaseIds": { 7 | "%SRCROOT%": { 8 | "uri": "file:///Users/tester/detekt/" 9 | } 10 | }, 11 | "results": [ 12 | { 13 | "level": "warning", 14 | "locations": [ 15 | { 16 | "physicalLocation": { 17 | "artifactLocation": { 18 | "uri": "TestFile.kt", 19 | "uriBaseId": "%SRCROOT%" 20 | }, 21 | "region": { 22 | "startColumn": 1, 23 | "startLine": 1 24 | } 25 | } 26 | } 27 | ], 28 | "message": { 29 | "text": "TestMessage" 30 | }, 31 | "ruleId": "detekt.TestSmellA.TestSmellA" 32 | }, 33 | { 34 | "level": "warning", 35 | "locations": [ 36 | { 37 | "physicalLocation": { 38 | "artifactLocation": { 39 | "uri": "TestFile.kt", 40 | "uriBaseId": "%SRCROOT%" 41 | }, 42 | "region": { 43 | "startColumn": 1, 44 | "startLine": 1 45 | } 46 | } 47 | } 48 | ], 49 | "message": { 50 | "text": "TestMessage" 51 | }, 52 | "ruleId": "detekt.TestSmellB.TestSmellB" 53 | }, 54 | { 55 | "level": "warning", 56 | "locations": [ 57 | { 58 | "physicalLocation": { 59 | "artifactLocation": { 60 | "uri": "TestFile.kt", 61 | "uriBaseId": "%SRCROOT%" 62 | }, 63 | "region": { 64 | "startColumn": 1, 65 | "startLine": 1 66 | } 67 | } 68 | } 69 | ], 70 | "message": { 71 | "text": "TestMessage" 72 | }, 73 | "ruleId": "detekt.TestSmellC.TestSmellC" 74 | } 75 | ], 76 | "tool": { 77 | "driver": { 78 | "downloadUri": "https://github.com/detekt/detekt/releases/download/v1.0.0/detekt", 79 | "fullName": "detekt", 80 | "guid": "022ca8c2-f6a2-4c95-b107-bb72c43263f3", 81 | "informationUri": "https://detekt.dev", 82 | "language": "en", 83 | "name": "detekt", 84 | "organization": "detekt", 85 | "rules": [ 86 | { 87 | "helpUri": "https://detekt.dev/potential-bugs.html#avoidreferentialequality", 88 | "id": "detekt.potential-bugs.AvoidReferentialEquality", 89 | "name": "AvoidReferentialEquality", 90 | "shortDescription": { 91 | "text": "EqualityCheck." 92 | } 93 | } 94 | ], 95 | "semanticVersion": "1.0.0", 96 | "version": "1.0.0" 97 | } 98 | } 99 | } 100 | ], 101 | "properties": { 102 | "tags": [ 103 | "tag", 104 | "tag1" 105 | ], 106 | "foo": { 107 | "bar": "buz" 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/jvmTest/resources/input_2_different_tool.sarif.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", 3 | "version": "2.1.0", 4 | "runs": [ 5 | { 6 | "originalUriBaseIds": { 7 | "%SRCROOT%": { 8 | "uri": "file:///Users/tester/detekt/" 9 | } 10 | }, 11 | "results": [ 12 | { 13 | "level": "warning", 14 | "locations": [ 15 | { 16 | "physicalLocation": { 17 | "artifactLocation": { 18 | "uri": "TestFile.kt", 19 | "uriBaseId": "%SRCROOT%" 20 | }, 21 | "region": { 22 | "startColumn": 1, 23 | "startLine": 1 24 | } 25 | } 26 | } 27 | ], 28 | "message": { 29 | "text": "TestMessage" 30 | }, 31 | "ruleId": "detekt.TestSmellD.TestSmellD" 32 | }, 33 | { 34 | "level": "warning", 35 | "locations": [ 36 | { 37 | "physicalLocation": { 38 | "artifactLocation": { 39 | "uri": "TestFile.kt", 40 | "uriBaseId": "%SRCROOT%" 41 | }, 42 | "region": { 43 | "startColumn": 1, 44 | "startLine": 1 45 | } 46 | } 47 | } 48 | ], 49 | "message": { 50 | "text": "TestMessage" 51 | }, 52 | "ruleId": "detekt.TestSmellE.TestSmellE" 53 | }, 54 | { 55 | "level": "warning", 56 | "locations": [ 57 | { 58 | "physicalLocation": { 59 | "artifactLocation": { 60 | "uri": "TestFile.kt", 61 | "uriBaseId": "%SRCROOT%" 62 | }, 63 | "region": { 64 | "startColumn": 1, 65 | "startLine": 1 66 | } 67 | } 68 | } 69 | ], 70 | "message": { 71 | "text": "TestMessage" 72 | }, 73 | "ruleId": "detekt.TestSmellF.TestSmellF" 74 | } 75 | ], 76 | "tool": { 77 | "driver": { 78 | "name": "AndroidLint", 79 | "fullName": "AndroidLint", 80 | "version": "8.1.3", 81 | "semanticVersion": "8.1.3", 82 | "organization": "Google", 83 | "informationUri": "https://developer.android.com/studio/write/lint", 84 | "fullDescription": { 85 | "text": "AndroidLintDriver" 86 | }, 87 | "language": "en-US", 88 | "rules": [] 89 | } 90 | } 91 | } 92 | ] 93 | } 94 | -------------------------------------------------------------------------------- /src/jvmTest/kotlin/io/github/detekt/sarif4k/SarifSerializerTest.kt: -------------------------------------------------------------------------------- 1 | package io.github.detekt.sarif4k 2 | 3 | import org.junit.jupiter.api.Test 4 | import java.io.Reader 5 | import kotlin.test.assertEquals 6 | 7 | class SarifSerializerTest { 8 | 9 | private val sarifSchema210 = SarifSchema210( 10 | schema = "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", 11 | version = Version.The210, 12 | runs = listOf( 13 | Run( 14 | tool = Tool( 15 | driver = ToolComponent( 16 | guid = "022ca8c2-f6a2-4c95-b107-bb72c43263f3", 17 | name = "detekt", 18 | organization = "detekt", 19 | fullName = "detekt", 20 | version = "1.0.0", 21 | semanticVersion = "1.0.0", 22 | downloadURI = "https://github.com/detekt/detekt/releases/download/v1.0.0/detekt", 23 | informationURI = "https://detekt.github.io/detekt", 24 | rules = emptyList(), 25 | language = "en" 26 | ) 27 | ), 28 | originalURIBaseIDS = mapOf( 29 | "%SRCROOT%" to ArtifactLocation(uri = "file:///Users/tester/detekt/") 30 | ), 31 | results = listOf( 32 | Result( 33 | ruleID = "detekt.TestSmellA.TestSmellA", 34 | message = Message(text = "TestMessage"), 35 | locations = listOf( 36 | Location( 37 | physicalLocation = PhysicalLocation( 38 | artifactLocation = ArtifactLocation( 39 | uri = "TestFile.kt", 40 | uriBaseID = "%SRCROOT%" 41 | ), 42 | region = Region( 43 | startLine = 1, 44 | startColumn = 1 45 | ) 46 | ), 47 | properties = PropertyBag( 48 | mapOf( 49 | "tags" to listOf("tag"), 50 | "foo" to mapOf("bar" to "buz") 51 | ) 52 | ), 53 | ) 54 | ) 55 | ), 56 | Result( 57 | ruleID = "detekt.TestSmellB.TestSmellB", 58 | message = Message(text = "TestMessage"), 59 | locations = listOf( 60 | Location( 61 | physicalLocation = PhysicalLocation( 62 | artifactLocation = ArtifactLocation( 63 | uri = "TestFile.kt", 64 | uriBaseID = "%SRCROOT%" 65 | ), 66 | region = Region( 67 | startLine = 1, 68 | startColumn = 1 69 | ) 70 | ) 71 | ) 72 | ) 73 | ) 74 | ) 75 | ) 76 | ) 77 | ) 78 | 79 | @Test 80 | fun `serialize kotlin data class to minified json`() { 81 | val actual = SarifSerializer.toMinifiedJson(sarifSchema210) 82 | val expected = getResource("/test.sarif.json").readText() 83 | assertEquals(expected.replace("\\s".toRegex(), ""), actual) 84 | } 85 | 86 | @Test 87 | fun `serialize kotlin data class to json`() { 88 | val actual = SarifSerializer.toJson(sarifSchema210) 89 | val expected = getResource("/test.sarif.json").readText() 90 | assertEquals(expected, actual) 91 | } 92 | 93 | @Test 94 | fun `deserialize json into kotlin data class`() { 95 | val actual = SarifSerializer.fromJson(getResource("/test.sarif.json").readText()) 96 | assertEquals(sarifSchema210, actual) 97 | } 98 | } 99 | 100 | private fun getResource(path: String): Reader = 101 | SarifSerializerTest::class.java.getResourceAsStream(path)!!.reader() 102 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/io/github/detekt/sarif4k/Merging.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("Merging") 2 | 3 | package io.github.detekt.sarif4k 4 | 5 | import kotlin.jvm.JvmName 6 | 7 | public fun SarifSchema210.merge(other: SarifSchema210): SarifSchema210 { 8 | require(schema == other.schema) { "Cannot merge sarifs with different schemas: '$schema' or '${other.schema}'" } 9 | require(version == other.version) { "Cannot merge sarifs with different versions: '$version' or '${other.version}'" } 10 | 11 | val mergedExternalProperties = (inlineExternalProperties.orEmpty() + other.inlineExternalProperties.orEmpty()) 12 | .takeIf { it.isNotEmpty() } 13 | 14 | val mergedProperties = when { 15 | properties != null && other.properties != null -> properties.merge(other.properties) 16 | properties != null -> properties 17 | other.properties != null -> other.properties 18 | else -> null 19 | } 20 | 21 | val mergedRuns = runs.merge(other.runs) 22 | 23 | return SarifSchema210( 24 | schema, 25 | version, 26 | mergedExternalProperties, 27 | mergedProperties, 28 | mergedRuns 29 | ) 30 | } 31 | 32 | private fun PropertyBag.merge(other: PropertyBag): PropertyBag { 33 | val aTags = this["tags"] as? Collection<*> 34 | val bTags = other["tags"] as? Collection<*> 35 | val tags = if (aTags != null && bTags != null) { 36 | mapOf("tags" to (aTags + bTags).distinct()) 37 | } else { 38 | emptyMap() 39 | } 40 | 41 | return PropertyBag(this + other + tags) 42 | } 43 | 44 | private fun List.merge(other: List): List { 45 | val runsByTool = (this + other).groupBy { it.tool.driver.fullName } 46 | 47 | return runsByTool.mapValues { (_, runs) -> 48 | val baseRun = runs.firstOrNull() ?: return@mapValues null 49 | 50 | val mergedRules = runs.flatMap { it.tool.driver.rules.orEmpty() }.distinctBy { it.id } 51 | 52 | val (mergedOriginalURIBaseIDs, runKeyMappings) = mergeOriginalURIBaseIDs(runs) 53 | 54 | val mergedResults = runs.flatMapIndexed { runIndex, run -> 55 | run.results.orEmpty().map { result -> 56 | val keyMappings = runKeyMappings.getOrNull(runIndex) ?: emptyMap() 57 | result.updateArtifactLocationBaseIds(keyMappings) 58 | } 59 | } 60 | 61 | baseRun.copy( 62 | originalURIBaseIDS = mergedOriginalURIBaseIDs.takeIf { it.isNotEmpty() }, 63 | results = mergedResults, 64 | tool = baseRun.tool.copy( 65 | driver = baseRun.tool.driver.copy( 66 | rules = mergedRules 67 | ) 68 | ) 69 | ) 70 | }.values.filterNotNull().toList() 71 | } 72 | 73 | private fun mergeOriginalURIBaseIDs(runs: List): Pair, List>> { 74 | if (runs.isEmpty()) return emptyMap() to emptyList() 75 | 76 | val mergedMap = mutableMapOf() 77 | var keyCounter = 1 78 | 79 | val runKeyMappings = runs.map { run -> 80 | run.originalURIBaseIDS?.mapValues { (key, artifactLocation) -> 81 | when (mergedMap[key]) { 82 | null -> { 83 | mergedMap[key] = artifactLocation 84 | key 85 | } 86 | artifactLocation -> key 87 | else -> { 88 | val newKey = generateSequence("${key}_${keyCounter}") { "${key}_${++keyCounter}" } 89 | .first { !mergedMap.containsKey(it) } 90 | mergedMap[newKey] = artifactLocation 91 | newKey 92 | } 93 | } 94 | }.orEmpty() 95 | } 96 | 97 | return mergedMap to runKeyMappings 98 | } 99 | 100 | private fun Result.updateArtifactLocationBaseIds(keyMappings: Map): Result { 101 | if (keyMappings.isEmpty()) return this 102 | 103 | val updatedLocations = locations?.map { location -> 104 | val updatedPhysicalLocation = location.physicalLocation?.let { physicalLocation -> 105 | val updatedArtifactLocation = physicalLocation.artifactLocation?.let { artifactLocation -> 106 | val uriBaseId = artifactLocation.uriBaseID 107 | if (uriBaseId != null && keyMappings.containsKey(uriBaseId) && keyMappings[uriBaseId] != uriBaseId) { 108 | artifactLocation.copy(uriBaseID = keyMappings[uriBaseId]) 109 | } else { 110 | artifactLocation 111 | } 112 | } 113 | physicalLocation.copy(artifactLocation = updatedArtifactLocation) 114 | } 115 | location.copy(physicalLocation = updatedPhysicalLocation) 116 | } 117 | 118 | return copy(locations = updatedLocations) 119 | } 120 | -------------------------------------------------------------------------------- /src/jvmTest/resources/output.sarif.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", 3 | "version": "2.1.0", 4 | "runs": [ 5 | { 6 | "originalUriBaseIds": { 7 | "%SRCROOT%": { 8 | "uri": "file:///Users/tester/detekt/" 9 | } 10 | }, 11 | "results": [ 12 | { 13 | "level": "warning", 14 | "locations": [ 15 | { 16 | "physicalLocation": { 17 | "artifactLocation": { 18 | "uri": "TestFile.kt", 19 | "uriBaseId": "%SRCROOT%" 20 | }, 21 | "region": { 22 | "startColumn": 1, 23 | "startLine": 1 24 | } 25 | } 26 | } 27 | ], 28 | "message": { 29 | "text": "TestMessage" 30 | }, 31 | "ruleId": "detekt.TestSmellA.TestSmellA" 32 | }, 33 | { 34 | "level": "warning", 35 | "locations": [ 36 | { 37 | "physicalLocation": { 38 | "artifactLocation": { 39 | "uri": "TestFile.kt", 40 | "uriBaseId": "%SRCROOT%" 41 | }, 42 | "region": { 43 | "startColumn": 1, 44 | "startLine": 1 45 | } 46 | } 47 | } 48 | ], 49 | "message": { 50 | "text": "TestMessage" 51 | }, 52 | "ruleId": "detekt.TestSmellB.TestSmellB" 53 | }, 54 | { 55 | "level": "warning", 56 | "locations": [ 57 | { 58 | "physicalLocation": { 59 | "artifactLocation": { 60 | "uri": "TestFile.kt", 61 | "uriBaseId": "%SRCROOT%" 62 | }, 63 | "region": { 64 | "startColumn": 1, 65 | "startLine": 1 66 | } 67 | } 68 | } 69 | ], 70 | "message": { 71 | "text": "TestMessage" 72 | }, 73 | "ruleId": "detekt.TestSmellC.TestSmellC" 74 | }, 75 | { 76 | "level": "warning", 77 | "locations": [ 78 | { 79 | "physicalLocation": { 80 | "artifactLocation": { 81 | "uri": "TestFile.kt", 82 | "uriBaseId": "%SRCROOT%" 83 | }, 84 | "region": { 85 | "startColumn": 1, 86 | "startLine": 1 87 | } 88 | } 89 | } 90 | ], 91 | "message": { 92 | "text": "TestMessage" 93 | }, 94 | "ruleId": "detekt.TestSmellD.TestSmellD" 95 | }, 96 | { 97 | "level": "warning", 98 | "locations": [ 99 | { 100 | "physicalLocation": { 101 | "artifactLocation": { 102 | "uri": "TestFile.kt", 103 | "uriBaseId": "%SRCROOT%" 104 | }, 105 | "region": { 106 | "startColumn": 1, 107 | "startLine": 1 108 | } 109 | } 110 | } 111 | ], 112 | "message": { 113 | "text": "TestMessage" 114 | }, 115 | "ruleId": "detekt.TestSmellE.TestSmellE" 116 | }, 117 | { 118 | "level": "warning", 119 | "locations": [ 120 | { 121 | "physicalLocation": { 122 | "artifactLocation": { 123 | "uri": "TestFile.kt", 124 | "uriBaseId": "%SRCROOT%" 125 | }, 126 | "region": { 127 | "startColumn": 1, 128 | "startLine": 1 129 | } 130 | } 131 | } 132 | ], 133 | "message": { 134 | "text": "TestMessage" 135 | }, 136 | "ruleId": "detekt.TestSmellF.TestSmellF" 137 | } 138 | ], 139 | "tool": { 140 | "driver": { 141 | "downloadUri": "https://github.com/detekt/detekt/releases/download/v1.0.0/detekt", 142 | "fullName": "detekt", 143 | "guid": "022ca8c2-f6a2-4c95-b107-bb72c43263f3", 144 | "informationUri": "https://detekt.dev", 145 | "language": "en", 146 | "name": "detekt", 147 | "organization": "detekt", 148 | "rules": [ 149 | { 150 | "helpUri": "https://detekt.dev/potential-bugs.html#avoidreferentialequality", 151 | "id": "detekt.potential-bugs.AvoidReferentialEquality", 152 | "name": "AvoidReferentialEquality", 153 | "shortDescription": { 154 | "text": "EqualityCheck." 155 | } 156 | }, 157 | { 158 | "helpUri": "https://detekt.dev/potential-bugs.html#deprecation", 159 | "id": "detekt.potential-bugs.Deprecation", 160 | "name": "Deprecation", 161 | "shortDescription": { 162 | "text": "NoDeprecated" 163 | } 164 | } 165 | ], 166 | "semanticVersion": "1.0.0", 167 | "version": "1.0.0" 168 | } 169 | } 170 | } 171 | ], 172 | "properties": { 173 | "tags": [ 174 | "tag", 175 | "tag1", 176 | "tag2" 177 | ], 178 | "foo": { 179 | "bar": "buz" 180 | }, 181 | "bar": 5 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/jvmTest/resources/output_other_uribaseid.sarif.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", 3 | "version": "2.1.0", 4 | "runs": [ 5 | { 6 | "originalUriBaseIds": { 7 | "%SRCROOT%": { 8 | "uri": "file:///Users/tester/detekt/" 9 | }, 10 | "%SRCROOT%_1": { 11 | "uri": "file:///Users/tester2/detekt/" 12 | } 13 | }, 14 | "results": [ 15 | { 16 | "level": "warning", 17 | "locations": [ 18 | { 19 | "physicalLocation": { 20 | "artifactLocation": { 21 | "uri": "TestFile.kt", 22 | "uriBaseId": "%SRCROOT%" 23 | }, 24 | "region": { 25 | "startColumn": 1, 26 | "startLine": 1 27 | } 28 | } 29 | } 30 | ], 31 | "message": { 32 | "text": "TestMessage" 33 | }, 34 | "ruleId": "detekt.TestSmellA.TestSmellA" 35 | }, 36 | { 37 | "level": "warning", 38 | "locations": [ 39 | { 40 | "physicalLocation": { 41 | "artifactLocation": { 42 | "uri": "TestFile.kt", 43 | "uriBaseId": "%SRCROOT%" 44 | }, 45 | "region": { 46 | "startColumn": 1, 47 | "startLine": 1 48 | } 49 | } 50 | } 51 | ], 52 | "message": { 53 | "text": "TestMessage" 54 | }, 55 | "ruleId": "detekt.TestSmellB.TestSmellB" 56 | }, 57 | { 58 | "level": "warning", 59 | "locations": [ 60 | { 61 | "physicalLocation": { 62 | "artifactLocation": { 63 | "uri": "TestFile.kt", 64 | "uriBaseId": "%SRCROOT%" 65 | }, 66 | "region": { 67 | "startColumn": 1, 68 | "startLine": 1 69 | } 70 | } 71 | } 72 | ], 73 | "message": { 74 | "text": "TestMessage" 75 | }, 76 | "ruleId": "detekt.TestSmellC.TestSmellC" 77 | }, 78 | { 79 | "level": "warning", 80 | "locations": [ 81 | { 82 | "physicalLocation": { 83 | "artifactLocation": { 84 | "uri": "TestFile2.kt", 85 | "uriBaseId": "%SRCROOT%_1" 86 | }, 87 | "region": { 88 | "startColumn": 1, 89 | "startLine": 1 90 | } 91 | } 92 | } 93 | ], 94 | "message": { 95 | "text": "TestMessage" 96 | }, 97 | "ruleId": "detekt.TestSmellD.TestSmellD" 98 | }, 99 | { 100 | "level": "warning", 101 | "locations": [ 102 | { 103 | "physicalLocation": { 104 | "artifactLocation": { 105 | "uri": "TestFile2.kt", 106 | "uriBaseId": "%SRCROOT%_1" 107 | }, 108 | "region": { 109 | "startColumn": 1, 110 | "startLine": 1 111 | } 112 | } 113 | } 114 | ], 115 | "message": { 116 | "text": "TestMessage" 117 | }, 118 | "ruleId": "detekt.TestSmellE.TestSmellE" 119 | }, 120 | { 121 | "level": "warning", 122 | "locations": [ 123 | { 124 | "physicalLocation": { 125 | "artifactLocation": { 126 | "uri": "TestFile2.kt", 127 | "uriBaseId": "%SRCROOT%_1" 128 | }, 129 | "region": { 130 | "startColumn": 1, 131 | "startLine": 1 132 | } 133 | } 134 | } 135 | ], 136 | "message": { 137 | "text": "TestMessage" 138 | }, 139 | "ruleId": "detekt.TestSmellF.TestSmellF" 140 | } 141 | ], 142 | "tool": { 143 | "driver": { 144 | "downloadUri": "https://github.com/detekt/detekt/releases/download/v1.0.0/detekt", 145 | "fullName": "detekt", 146 | "guid": "022ca8c2-f6a2-4c95-b107-bb72c43263f3", 147 | "informationUri": "https://detekt.dev", 148 | "language": "en", 149 | "name": "detekt", 150 | "organization": "detekt", 151 | "rules": [ 152 | { 153 | "helpUri": "https://detekt.dev/potential-bugs.html#avoidreferentialequality", 154 | "id": "detekt.potential-bugs.AvoidReferentialEquality", 155 | "name": "AvoidReferentialEquality", 156 | "shortDescription": { 157 | "text": "EqualityCheck." 158 | } 159 | }, 160 | { 161 | "helpUri": "https://detekt.dev/potential-bugs.html#deprecation", 162 | "id": "detekt.potential-bugs.Deprecation", 163 | "name": "Deprecation", 164 | "shortDescription": { 165 | "text": "NoDeprecated" 166 | } 167 | } 168 | ], 169 | "semanticVersion": "1.0.0", 170 | "version": "1.0.0" 171 | } 172 | } 173 | } 174 | ], 175 | "properties": { 176 | "tags": [ 177 | "tag", 178 | "tag1", 179 | "tag2" 180 | ], 181 | "foo": { 182 | "bar": "buz" 183 | }, 184 | "bar": 5 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/jvmTest/resources/output_different_tool.sarif.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json", 3 | "version": "2.1.0", 4 | "runs": [ 5 | { 6 | "originalUriBaseIds": { 7 | "%SRCROOT%": { 8 | "uri": "file:///Users/tester/detekt/" 9 | } 10 | }, 11 | "results": [ 12 | { 13 | "level": "warning", 14 | "locations": [ 15 | { 16 | "physicalLocation": { 17 | "artifactLocation": { 18 | "uri": "TestFile.kt", 19 | "uriBaseId": "%SRCROOT%" 20 | }, 21 | "region": { 22 | "startColumn": 1, 23 | "startLine": 1 24 | } 25 | } 26 | } 27 | ], 28 | "message": { 29 | "text": "TestMessage" 30 | }, 31 | "ruleId": "detekt.TestSmellA.TestSmellA" 32 | }, 33 | { 34 | "level": "warning", 35 | "locations": [ 36 | { 37 | "physicalLocation": { 38 | "artifactLocation": { 39 | "uri": "TestFile.kt", 40 | "uriBaseId": "%SRCROOT%" 41 | }, 42 | "region": { 43 | "startColumn": 1, 44 | "startLine": 1 45 | } 46 | } 47 | } 48 | ], 49 | "message": { 50 | "text": "TestMessage" 51 | }, 52 | "ruleId": "detekt.TestSmellB.TestSmellB" 53 | }, 54 | { 55 | "level": "warning", 56 | "locations": [ 57 | { 58 | "physicalLocation": { 59 | "artifactLocation": { 60 | "uri": "TestFile.kt", 61 | "uriBaseId": "%SRCROOT%" 62 | }, 63 | "region": { 64 | "startColumn": 1, 65 | "startLine": 1 66 | } 67 | } 68 | } 69 | ], 70 | "message": { 71 | "text": "TestMessage" 72 | }, 73 | "ruleId": "detekt.TestSmellC.TestSmellC" 74 | } 75 | ], 76 | "tool": { 77 | "driver": { 78 | "downloadUri": "https://github.com/detekt/detekt/releases/download/v1.0.0/detekt", 79 | "fullName": "detekt", 80 | "guid": "022ca8c2-f6a2-4c95-b107-bb72c43263f3", 81 | "informationUri": "https://detekt.dev", 82 | "language": "en", 83 | "name": "detekt", 84 | "organization": "detekt", 85 | "rules": [ 86 | { 87 | "helpUri": "https://detekt.dev/potential-bugs.html#avoidreferentialequality", 88 | "id": "detekt.potential-bugs.AvoidReferentialEquality", 89 | "name": "AvoidReferentialEquality", 90 | "shortDescription": { 91 | "text": "EqualityCheck." 92 | } 93 | } 94 | ], 95 | "semanticVersion": "1.0.0", 96 | "version": "1.0.0" 97 | } 98 | } 99 | }, 100 | { 101 | "originalUriBaseIds": { 102 | "%SRCROOT%": { 103 | "uri": "file:///Users/tester/detekt/" 104 | } 105 | }, 106 | "results": [ 107 | { 108 | "level": "warning", 109 | "locations": [ 110 | { 111 | "physicalLocation": { 112 | "artifactLocation": { 113 | "uri": "TestFile.kt", 114 | "uriBaseId": "%SRCROOT%" 115 | }, 116 | "region": { 117 | "startColumn": 1, 118 | "startLine": 1 119 | } 120 | } 121 | } 122 | ], 123 | "message": { 124 | "text": "TestMessage" 125 | }, 126 | "ruleId": "detekt.TestSmellD.TestSmellD" 127 | }, 128 | { 129 | "level": "warning", 130 | "locations": [ 131 | { 132 | "physicalLocation": { 133 | "artifactLocation": { 134 | "uri": "TestFile.kt", 135 | "uriBaseId": "%SRCROOT%" 136 | }, 137 | "region": { 138 | "startColumn": 1, 139 | "startLine": 1 140 | } 141 | } 142 | } 143 | ], 144 | "message": { 145 | "text": "TestMessage" 146 | }, 147 | "ruleId": "detekt.TestSmellE.TestSmellE" 148 | }, 149 | { 150 | "level": "warning", 151 | "locations": [ 152 | { 153 | "physicalLocation": { 154 | "artifactLocation": { 155 | "uri": "TestFile.kt", 156 | "uriBaseId": "%SRCROOT%" 157 | }, 158 | "region": { 159 | "startColumn": 1, 160 | "startLine": 1 161 | } 162 | } 163 | } 164 | ], 165 | "message": { 166 | "text": "TestMessage" 167 | }, 168 | "ruleId": "detekt.TestSmellF.TestSmellF" 169 | } 170 | ], 171 | "tool": { 172 | "driver": { 173 | "fullDescription": { 174 | "text": "AndroidLintDriver" 175 | }, 176 | "fullName": "AndroidLint", 177 | "informationUri": "https://developer.android.com/studio/write/lint", 178 | "language": "en-US", 179 | "name": "AndroidLint", 180 | "organization": "Google", 181 | "rules": [], 182 | "semanticVersion": "8.1.3", 183 | "version": "8.1.3" 184 | } 185 | } 186 | } 187 | ], 188 | "properties": { 189 | "tags": [ 190 | "tag", 191 | "tag1" 192 | ], 193 | "foo": { 194 | "bar": "buz" 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # SPDX-License-Identifier: Apache-2.0 19 | # 20 | 21 | ############################################################################## 22 | # 23 | # Gradle start up script for POSIX generated by Gradle. 24 | # 25 | # Important for running: 26 | # 27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 28 | # noncompliant, but you have some other compliant shell such as ksh or 29 | # bash, then to run this script, type that shell name before the whole 30 | # command line, like: 31 | # 32 | # ksh Gradle 33 | # 34 | # Busybox and similar reduced shells will NOT work, because this script 35 | # requires all of these POSIX shell features: 36 | # * functions; 37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 39 | # * compound commands having a testable exit status, especially «case»; 40 | # * various built-in commands including «command», «set», and «ulimit». 41 | # 42 | # Important for patching: 43 | # 44 | # (2) This script targets any POSIX shell, so it avoids extensions provided 45 | # by Bash, Ksh, etc; in particular arrays are avoided. 46 | # 47 | # The "traditional" practice of packing multiple parameters into a 48 | # space-separated string is a well documented source of bugs and security 49 | # problems, so this is (mostly) avoided, by progressively accumulating 50 | # options in "$@", and eventually passing that to Java. 51 | # 52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 54 | # see the in-line comments for details. 55 | # 56 | # There are tweaks for specific operating systems such as AIX, CygWin, 57 | # Darwin, MinGW, and NonStop. 58 | # 59 | # (3) This script is generated from the Groovy template 60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 61 | # within the Gradle project. 62 | # 63 | # You can find Gradle at https://github.com/gradle/gradle/. 64 | # 65 | ############################################################################## 66 | 67 | # Attempt to set APP_HOME 68 | 69 | # Resolve links: $0 may be a link 70 | app_path=$0 71 | 72 | # Need this for daisy-chained symlinks. 73 | while 74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 75 | [ -h "$app_path" ] 76 | do 77 | ls=$( ls -ld "$app_path" ) 78 | link=${ls#*' -> '} 79 | case $link in #( 80 | /*) app_path=$link ;; #( 81 | *) app_path=$APP_HOME$link ;; 82 | esac 83 | done 84 | 85 | # This is normally unused 86 | # shellcheck disable=SC2034 87 | APP_BASE_NAME=${0##*/} 88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | 118 | 119 | # Determine the Java command to use to start the JVM. 120 | if [ -n "$JAVA_HOME" ] ; then 121 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 122 | # IBM's JDK on AIX uses strange locations for the executables 123 | JAVACMD=$JAVA_HOME/jre/sh/java 124 | else 125 | JAVACMD=$JAVA_HOME/bin/java 126 | fi 127 | if [ ! -x "$JAVACMD" ] ; then 128 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 129 | 130 | Please set the JAVA_HOME variable in your environment to match the 131 | location of your Java installation." 132 | fi 133 | else 134 | JAVACMD=java 135 | if ! command -v java >/dev/null 2>&1 136 | then 137 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 138 | 139 | Please set the JAVA_HOME variable in your environment to match the 140 | location of your Java installation." 141 | fi 142 | fi 143 | 144 | # Increase the maximum file descriptors if we can. 145 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 146 | case $MAX_FD in #( 147 | max*) 148 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 149 | # shellcheck disable=SC2039,SC3045 150 | MAX_FD=$( ulimit -H -n ) || 151 | warn "Could not query maximum file descriptor limit" 152 | esac 153 | case $MAX_FD in #( 154 | '' | soft) :;; #( 155 | *) 156 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 157 | # shellcheck disable=SC2039,SC3045 158 | ulimit -n "$MAX_FD" || 159 | warn "Could not set maximum file descriptor limit to $MAX_FD" 160 | esac 161 | fi 162 | 163 | # Collect all arguments for the java command, stacking in reverse order: 164 | # * args from the command line 165 | # * the main class name 166 | # * -classpath 167 | # * -D...appname settings 168 | # * --module-path (only if needed) 169 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 170 | 171 | # For Cygwin or MSYS, switch paths to Windows format before running java 172 | if "$cygwin" || "$msys" ; then 173 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 174 | 175 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 176 | 177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 178 | for arg do 179 | if 180 | case $arg in #( 181 | -*) false ;; # don't mess with options #( 182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 183 | [ -e "$t" ] ;; #( 184 | *) false ;; 185 | esac 186 | then 187 | arg=$( cygpath --path --ignore --mixed "$arg" ) 188 | fi 189 | # Roll the args list around exactly as many times as the number of 190 | # args, so each arg winds up back in the position where it started, but 191 | # possibly modified. 192 | # 193 | # NB: a `for` loop captures its iteration list before it begins, so 194 | # changing the positional parameters here affects neither the number of 195 | # iterations, nor the values presented in `arg`. 196 | shift # remove old arg 197 | set -- "$@" "$arg" # push replacement arg 198 | done 199 | fi 200 | 201 | 202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 204 | 205 | # Collect all arguments for the java command: 206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 207 | # and any embedded shellness will be escaped. 208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 209 | # treated as '${Hostname}' itself on the command line. 210 | 211 | set -- \ 212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 213 | -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ 214 | "$@" 215 | 216 | # Stop when "xargs" is not available. 217 | if ! command -v xargs >/dev/null 2>&1 218 | then 219 | die "xargs is not available" 220 | fi 221 | 222 | # Use "xargs" to parse quoted args. 223 | # 224 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 225 | # 226 | # In Bash we could simply go: 227 | # 228 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 229 | # set -- "${ARGS[@]}" "$@" 230 | # 231 | # but POSIX shell has neither arrays nor command substitution, so instead we 232 | # post-process each arg (as a line of input to sed) to backslash-escape any 233 | # character that might be a shell metacharacter, then use eval to reverse 234 | # that process (while maintaining the separation between arguments), and wrap 235 | # the whole thing up as a single "set" statement. 236 | # 237 | # This will of course break if any of these variables contains a newline or 238 | # an unmatched quote. 239 | # 240 | 241 | eval "set -- $( 242 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 243 | xargs -n1 | 244 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 245 | tr '\n' ' ' 246 | )" '"$@"' 247 | 248 | exec "$JAVACMD" "$@" 249 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/commonMain/kotlin/io/github/detekt/sarif4k/SarifDataBindings.kt: -------------------------------------------------------------------------------- 1 | package io.github.detekt.sarif4k 2 | 3 | import kotlinx.serialization.KSerializer 4 | import kotlinx.serialization.SerialName 5 | import kotlinx.serialization.Serializable 6 | import kotlinx.serialization.descriptors.PrimitiveKind 7 | import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor 8 | import kotlinx.serialization.descriptors.SerialDescriptor 9 | import kotlinx.serialization.encoding.Decoder 10 | import kotlinx.serialization.encoding.Encoder 11 | import kotlinx.serialization.json.JsonObject 12 | import kotlin.jvm.JvmInline 13 | 14 | /* 15 | * Using https://app.quicktype.io/ to generate from schema 16 | * https://github.com/oasis-tcs/sarif-spec/blob/5280a944e8faa17a60ab15917a5449e27ed5b32c/Schemata/sarif-external-property-file-schema-2.1.0.json 17 | * 18 | * Manually added `@Serializable(with = )` for enums. This can be automated 19 | * once https://github.com/quicktype/quicktype/pull/1680 is merged. 20 | * 21 | * Manually modified the version to be immediately after schema based on the recommendation for 22 | * consumers to sniff the version before parsing the entire file. 23 | * https://github.com/detekt/detekt/issues/3045#issuecomment-711071231 24 | * 25 | * Manually modified `PropertyBag` to accept arbitrary values. 26 | */ 27 | /** 28 | * Static Analysis Results Format (SARIF) Version 2.1.0 JSON Schema: a standard format for 29 | * the output of static analysis tools. 30 | */ 31 | @Serializable 32 | public data class SarifSchema210 ( 33 | /** 34 | * The URI of the JSON schema corresponding to the version. 35 | */ 36 | @SerialName("\$schema") 37 | val schema: String? = null, 38 | 39 | /** 40 | * The SARIF format version of this log file. 41 | */ 42 | val version: Version, 43 | 44 | /** 45 | * References to external property files that share data between runs. 46 | */ 47 | val inlineExternalProperties: List? = null, 48 | 49 | /** 50 | * Key/value pairs that provide additional information about the log file. 51 | */ 52 | val properties: PropertyBag? = null, 53 | 54 | /** 55 | * The set of runs contained in this log file. 56 | */ 57 | val runs: List, 58 | ) 59 | 60 | /** 61 | * The top-level element of an external property file. 62 | */ 63 | @Serializable 64 | public data class ExternalProperties ( 65 | /** 66 | * Addresses that will be merged with a separate run. 67 | */ 68 | val addresses: List
? = null, 69 | 70 | /** 71 | * An array of artifact objects that will be merged with a separate run. 72 | */ 73 | val artifacts: List? = null, 74 | 75 | /** 76 | * A conversion object that will be merged with a separate run. 77 | */ 78 | val conversion: Conversion? = null, 79 | 80 | /** 81 | * The analysis tool object that will be merged with a separate run. 82 | */ 83 | val driver: ToolComponent? = null, 84 | 85 | /** 86 | * Tool extensions that will be merged with a separate run. 87 | */ 88 | val extensions: List? = null, 89 | 90 | /** 91 | * Key/value pairs that provide additional information that will be merged with a separate 92 | * run. 93 | */ 94 | val externalizedProperties: PropertyBag? = null, 95 | 96 | /** 97 | * An array of graph objects that will be merged with a separate run. 98 | */ 99 | val graphs: List? = null, 100 | 101 | /** 102 | * A stable, unique identifier for this external properties object, in the form of a GUID. 103 | */ 104 | val guid: String? = null, 105 | 106 | /** 107 | * Describes the invocation of the analysis tool that will be merged with a separate run. 108 | */ 109 | val invocations: List? = null, 110 | 111 | /** 112 | * An array of logical locations such as namespaces, types or functions that will be merged 113 | * with a separate run. 114 | */ 115 | val logicalLocations: List? = null, 116 | 117 | /** 118 | * Tool policies that will be merged with a separate run. 119 | */ 120 | val policies: List? = null, 121 | 122 | /** 123 | * Key/value pairs that provide additional information about the external properties. 124 | */ 125 | val properties: PropertyBag? = null, 126 | 127 | /** 128 | * An array of result objects that will be merged with a separate run. 129 | */ 130 | val results: List? = null, 131 | 132 | /** 133 | * A stable, unique identifier for the run associated with this external properties object, 134 | * in the form of a GUID. 135 | */ 136 | @SerialName("runGuid") 137 | val runGUID: String? = null, 138 | 139 | /** 140 | * The URI of the JSON schema corresponding to the version of the external property file 141 | * format. 142 | */ 143 | val schema: String? = null, 144 | 145 | /** 146 | * Tool taxonomies that will be merged with a separate run. 147 | */ 148 | val taxonomies: List? = null, 149 | 150 | /** 151 | * An array of threadFlowLocation objects that will be merged with a separate run. 152 | */ 153 | val threadFlowLocations: List? = null, 154 | 155 | /** 156 | * Tool translations that will be merged with a separate run. 157 | */ 158 | val translations: List? = null, 159 | 160 | /** 161 | * The SARIF format version of this external properties object. 162 | */ 163 | val version: Version? = null, 164 | 165 | /** 166 | * Requests that will be merged with a separate run. 167 | */ 168 | val webRequests: List? = null, 169 | 170 | /** 171 | * Responses that will be merged with a separate run. 172 | */ 173 | val webResponses: List? = null 174 | ) 175 | 176 | /** 177 | * A physical or virtual address, or a range of addresses, in an 'addressable region' 178 | * (memory or a binary file). 179 | * 180 | * The address of the location. 181 | */ 182 | @Serializable 183 | public data class Address ( 184 | /** 185 | * The address expressed as a byte offset from the start of the addressable region. 186 | */ 187 | val absoluteAddress: Long? = null, 188 | 189 | /** 190 | * A human-readable fully qualified name that is associated with the address. 191 | */ 192 | val fullyQualifiedName: String? = null, 193 | 194 | /** 195 | * The index within run.addresses of the cached object for this address. 196 | */ 197 | val index: Long? = null, 198 | 199 | /** 200 | * An open-ended string that identifies the address kind. 'data', 'function', 201 | * 'header','instruction', 'module', 'page', 'section', 'segment', 'stack', 'stackFrame', 202 | * 'table' are well-known values. 203 | */ 204 | val kind: String? = null, 205 | 206 | /** 207 | * The number of bytes in this range of addresses. 208 | */ 209 | val length: Long? = null, 210 | 211 | /** 212 | * A name that is associated with the address, e.g., '.text'. 213 | */ 214 | val name: String? = null, 215 | 216 | /** 217 | * The byte offset of this address from the absolute or relative address of the parent 218 | * object. 219 | */ 220 | val offsetFromParent: Long? = null, 221 | 222 | /** 223 | * The index within run.addresses of the parent object. 224 | */ 225 | val parentIndex: Long? = null, 226 | 227 | /** 228 | * Key/value pairs that provide additional information about the address. 229 | */ 230 | val properties: PropertyBag? = null, 231 | 232 | /** 233 | * The address expressed as a byte offset from the absolute address of the top-most parent 234 | * object. 235 | */ 236 | val relativeAddress: Long? = null 237 | ) 238 | 239 | /** 240 | * Key/value pairs that provide additional information about the address. 241 | * 242 | * Key/value pairs that provide additional information about the object. 243 | * 244 | * Key/value pairs that provide additional information about the artifact content. 245 | * 246 | * Key/value pairs that provide additional information about the message. 247 | * 248 | * Key/value pairs that provide additional information about the artifact location. 249 | * 250 | * Key/value pairs that provide additional information about the artifact. 251 | * 252 | * Contains configuration information specific to a report. 253 | * 254 | * Key/value pairs that provide additional information about the reporting configuration. 255 | * 256 | * Key/value pairs that provide additional information about the reporting descriptor 257 | * reference. 258 | * 259 | * Key/value pairs that provide additional information about the toolComponentReference. 260 | * 261 | * Key/value pairs that provide additional information about the configuration override. 262 | * 263 | * Key/value pairs that provide additional information about the invocation. 264 | * 265 | * Key/value pairs that provide additional information about the exception. 266 | * 267 | * Key/value pairs that provide additional information about the region. 268 | * 269 | * Key/value pairs that provide additional information about the logical location. 270 | * 271 | * Key/value pairs that provide additional information about the physical location. 272 | * 273 | * Key/value pairs that provide additional information about the location. 274 | * 275 | * Key/value pairs that provide additional information about the location relationship. 276 | * 277 | * Key/value pairs that provide additional information about the stack frame. 278 | * 279 | * Key/value pairs that provide additional information about the stack. 280 | * 281 | * Key/value pairs that provide additional information about the notification. 282 | * 283 | * Key/value pairs that provide additional information about the conversion. 284 | * 285 | * Key/value pairs that provide additional information about the report. 286 | * 287 | * Key/value pairs that provide additional information about the tool component. 288 | * 289 | * Key/value pairs that provide additional information about the translation metadata. 290 | * 291 | * Key/value pairs that provide additional information about the tool. 292 | * 293 | * Key/value pairs that provide additional information that will be merged with a separate 294 | * run. 295 | * 296 | * Key/value pairs that provide additional information about the edge. 297 | * 298 | * Key/value pairs that provide additional information about the node. 299 | * 300 | * Key/value pairs that provide additional information about the graph. 301 | * 302 | * Key/value pairs that provide additional information about the external properties. 303 | * 304 | * Key/value pairs that provide additional information about the attachment. 305 | * 306 | * Key/value pairs that provide additional information about the rectangle. 307 | * 308 | * Key/value pairs that provide additional information about the code flow. 309 | * 310 | * Key/value pairs that provide additional information about the threadflow location. 311 | * 312 | * Key/value pairs that provide additional information about the request. 313 | * 314 | * Key/value pairs that provide additional information about the response. 315 | * 316 | * Key/value pairs that provide additional information about the thread flow. 317 | * 318 | * Key/value pairs that provide additional information about the change. 319 | * 320 | * Key/value pairs that provide additional information about the replacement. 321 | * 322 | * Key/value pairs that provide additional information about the fix. 323 | * 324 | * Key/value pairs that provide additional information about the edge traversal. 325 | * 326 | * Key/value pairs that provide additional information about the graph traversal. 327 | * 328 | * Key/value pairs that provide additional information about the result. 329 | * 330 | * Key/value pairs that provide additional information about the suppression. 331 | * 332 | * Key/value pairs that provide additional information about the log file. 333 | * 334 | * Key/value pairs that provide additional information about the run automation details. 335 | * 336 | * Key/value pairs that provide additional information about the external property file. 337 | * 338 | * Key/value pairs that provide additional information about the external property files. 339 | * 340 | * Key/value pairs that provide additional information about the run. 341 | * 342 | * Key/value pairs that provide additional information about the special locations. 343 | * 344 | * Key/value pairs that provide additional information about the version control details. 345 | */ 346 | @Serializable(with = PropertyBag.Companion::class) 347 | @JvmInline 348 | public value class PropertyBag( 349 | private val value: Map, 350 | ) : Map by value { 351 | public constructor(tags: Set, map: Map) : this(map + mapOf("tags" to tags)) 352 | 353 | /** 354 | * A set of distinct strings that provide additional information. 355 | */ 356 | public val tags: List? 357 | get() = try { 358 | val tagList = value["tags"] as Collection<*>? 359 | tagList?.mapIndexed { index, it -> 360 | try { 361 | it as String 362 | } catch (e: ClassCastException) { 363 | throw IllegalStateException("Expected a String tag at index $index: ${it}.", e) 364 | } 365 | } 366 | } catch (e: ClassCastException) { 367 | throw IllegalStateException("Expected a Collection for the value of tags property: ${value["tags"]}.", e) 368 | } 369 | 370 | public companion object : KSerializer { 371 | override val descriptor: SerialDescriptor = JsonObject.serializer().descriptor 372 | 373 | override fun deserialize(decoder: Decoder): PropertyBag { 374 | val jsonObject = decoder.decodeSerializableValue(JsonObject.serializer()) 375 | return PropertyBag(jsonObject.toNativeObject()) 376 | } 377 | 378 | override fun serialize(encoder: Encoder, value: PropertyBag) { 379 | encoder.encodeSerializableValue(JsonObject.serializer(), value.toJsonElement()) 380 | } 381 | } 382 | } 383 | 384 | /** 385 | * A single artifact. In some cases, this artifact might be nested within another artifact. 386 | */ 387 | @Serializable 388 | public data class Artifact ( 389 | /** 390 | * The contents of the artifact. 391 | */ 392 | val contents: ArtifactContent? = null, 393 | 394 | /** 395 | * A short description of the artifact. 396 | */ 397 | val description: Message? = null, 398 | 399 | /** 400 | * Specifies the encoding for an artifact object that refers to a text file. 401 | */ 402 | val encoding: String? = null, 403 | 404 | /** 405 | * A dictionary, each of whose keys is the name of a hash function and each of whose values 406 | * is the hashed value of the artifact produced by the specified hash function. 407 | */ 408 | val hashes: Map? = null, 409 | 410 | /** 411 | * The Coordinated Universal Time (UTC) date and time at which the artifact was most 412 | * recently modified. See "Date/time properties" in the SARIF spec for the required format. 413 | */ 414 | @SerialName("lastModifiedTimeUtc") 415 | val lastModifiedTimeUTC: String? = null, 416 | 417 | /** 418 | * The length of the artifact in bytes. 419 | */ 420 | val length: Long? = null, 421 | 422 | /** 423 | * The location of the artifact. 424 | */ 425 | val location: ArtifactLocation? = null, 426 | 427 | /** 428 | * The MIME type (RFC 2045) of the artifact. 429 | */ 430 | val mimeType: String? = null, 431 | 432 | /** 433 | * The offset in bytes of the artifact within its containing artifact. 434 | */ 435 | val offset: Long? = null, 436 | 437 | /** 438 | * Identifies the index of the immediate parent of the artifact, if this artifact is nested. 439 | */ 440 | val parentIndex: Long? = null, 441 | 442 | /** 443 | * Key/value pairs that provide additional information about the artifact. 444 | */ 445 | val properties: PropertyBag? = null, 446 | 447 | /** 448 | * The role or roles played by the artifact in the analysis. 449 | */ 450 | val roles: List? = null, 451 | 452 | /** 453 | * Specifies the source language for any artifact object that refers to a text file that 454 | * contains source code. 455 | */ 456 | val sourceLanguage: String? = null 457 | ) 458 | 459 | /** 460 | * The contents of the artifact. 461 | * 462 | * Represents the contents of an artifact. 463 | * 464 | * The portion of the artifact contents within the specified region. 465 | * 466 | * The body of the request. 467 | * 468 | * The body of the response. 469 | * 470 | * The content to insert at the location specified by the 'deletedRegion' property. 471 | */ 472 | @Serializable 473 | public data class ArtifactContent ( 474 | /** 475 | * MIME Base64-encoded content from a binary artifact, or from a text artifact in its 476 | * original encoding. 477 | */ 478 | val binary: String? = null, 479 | 480 | /** 481 | * Key/value pairs that provide additional information about the artifact content. 482 | */ 483 | val properties: PropertyBag? = null, 484 | 485 | /** 486 | * An alternate rendered representation of the artifact (e.g., a decompiled representation 487 | * of a binary region). 488 | */ 489 | val rendered: MultiformatMessageString? = null, 490 | 491 | /** 492 | * UTF-8-encoded content from a text artifact. 493 | */ 494 | val text: String? = null 495 | ) 496 | 497 | /** 498 | * An alternate rendered representation of the artifact (e.g., a decompiled representation 499 | * of a binary region). 500 | * 501 | * A message string or message format string rendered in multiple formats. 502 | * 503 | * A comprehensive description of the tool component. 504 | * 505 | * A description of the report. Should, as far as possible, provide details sufficient to 506 | * enable resolution of any problem indicated by the result. 507 | * 508 | * Provides the primary documentation for the report, useful when there is no online 509 | * documentation. 510 | * 511 | * A concise description of the report. Should be a single sentence that is understandable 512 | * when visible space is limited to a single line of text. 513 | * 514 | * A brief description of the tool component. 515 | * 516 | * A comprehensive description of the translation metadata. 517 | * 518 | * A brief description of the translation metadata. 519 | */ 520 | @Serializable 521 | public data class MultiformatMessageString ( 522 | /** 523 | * A Markdown message string or format string. 524 | */ 525 | val markdown: String? = null, 526 | 527 | /** 528 | * Key/value pairs that provide additional information about the message. 529 | */ 530 | val properties: PropertyBag? = null, 531 | 532 | /** 533 | * A plain text message string or format string. 534 | */ 535 | val text: String 536 | ) 537 | 538 | /** 539 | * A short description of the artifact. 540 | * 541 | * A short description of the artifact location. 542 | * 543 | * A message relevant to the region. 544 | * 545 | * A message relevant to the location. 546 | * 547 | * A description of the location relationship. 548 | * 549 | * A message relevant to this call stack. 550 | * 551 | * A message that describes the condition that was encountered. 552 | * 553 | * A description of the reporting descriptor relationship. 554 | * 555 | * A description of the graph. 556 | * 557 | * A short description of the edge. 558 | * 559 | * A short description of the node. 560 | * 561 | * A message describing the role played by the attachment. 562 | * 563 | * A message relevant to the rectangle. 564 | * 565 | * A message relevant to the code flow. 566 | * 567 | * A message relevant to the thread flow. 568 | * 569 | * A message that describes the proposed fix, enabling viewers to present the proposed 570 | * change to an end user. 571 | * 572 | * A description of this graph traversal. 573 | * 574 | * A message to display to the user as the edge is traversed. 575 | * 576 | * A message that describes the result. The first sentence of the message only will be 577 | * displayed when visible space is limited. 578 | * 579 | * A description of the identity and role played within the engineering system by this 580 | * object's containing run object. 581 | * 582 | * Encapsulates a message intended to be read by the end user. 583 | */ 584 | @Serializable 585 | public data class Message ( 586 | /** 587 | * An array of strings to substitute into the message string. 588 | */ 589 | val arguments: List? = null, 590 | 591 | /** 592 | * The identifier for this message. 593 | */ 594 | val id: String? = null, 595 | 596 | /** 597 | * A Markdown message string. 598 | */ 599 | val markdown: String? = null, 600 | 601 | /** 602 | * Key/value pairs that provide additional information about the message. 603 | */ 604 | val properties: PropertyBag? = null, 605 | 606 | /** 607 | * A plain text message string. 608 | */ 609 | val text: String? = null 610 | ) 611 | 612 | /** 613 | * The location of the artifact. 614 | * 615 | * Specifies the location of an artifact. 616 | * 617 | * An absolute URI specifying the location of the executable that was invoked. 618 | * 619 | * A file containing the standard error stream from the process that was invoked. 620 | * 621 | * A file containing the standard input stream to the process that was invoked. 622 | * 623 | * A file containing the standard output stream from the process that was invoked. 624 | * 625 | * A file containing the interleaved standard output and standard error stream from the 626 | * process that was invoked. 627 | * 628 | * The working directory for the invocation. 629 | * 630 | * Identifies the artifact that the analysis tool was instructed to scan. This need not be 631 | * the same as the artifact where the result actually occurred. 632 | * 633 | * The location of the attachment. 634 | * 635 | * The location of the artifact to change. 636 | * 637 | * The location of the external property file. 638 | * 639 | * Provides a suggestion to SARIF consumers to display file paths relative to the specified 640 | * location. 641 | * 642 | * The location in the local file system to which the root of the repository was mapped at 643 | * the time of the analysis. 644 | */ 645 | @Serializable 646 | public data class ArtifactLocation ( 647 | /** 648 | * A short description of the artifact location. 649 | */ 650 | val description: Message? = null, 651 | 652 | /** 653 | * The index within the run artifacts array of the artifact object associated with the 654 | * artifact location. 655 | */ 656 | val index: Long? = null, 657 | 658 | /** 659 | * Key/value pairs that provide additional information about the artifact location. 660 | */ 661 | val properties: PropertyBag? = null, 662 | 663 | /** 664 | * A string containing a valid relative or absolute URI. 665 | */ 666 | val uri: String? = null, 667 | 668 | /** 669 | * A string which indirectly specifies the absolute URI with respect to which a relative URI 670 | * in the "uri" property is interpreted. 671 | */ 672 | @SerialName("uriBaseId") 673 | val uriBaseID: String? = null 674 | ) 675 | 676 | @Serializable(with = Role.Companion::class) 677 | public enum class Role( 678 | public val value: String, 679 | ) { 680 | Added("added"), 681 | AnalysisTarget("analysisTarget"), 682 | Attachment("attachment"), 683 | DebugOutputFile("debugOutputFile"), 684 | Deleted("deleted"), 685 | Directory("directory"), 686 | Driver("driver"), 687 | Extension("extension"), 688 | MemoryContents("memoryContents"), 689 | Modified("modified"), 690 | Policy("policy"), 691 | ReferencedOnCommandLine("referencedOnCommandLine"), 692 | Renamed("renamed"), 693 | ResponseFile("responseFile"), 694 | ResultFile("resultFile"), 695 | StandardStream("standardStream"), 696 | Taxonomy("taxonomy"), 697 | ToolSpecifiedConfiguration("toolSpecifiedConfiguration"), 698 | TracedFile("tracedFile"), 699 | Translation("translation"), 700 | Uncontrolled("uncontrolled"), 701 | Unmodified("unmodified"), 702 | UserSpecifiedConfiguration("userSpecifiedConfiguration"); 703 | 704 | public companion object : KSerializer { 705 | override val descriptor: SerialDescriptor get() { 706 | return PrimitiveSerialDescriptor("quicktype.Role", PrimitiveKind.STRING) 707 | } 708 | override fun deserialize(decoder: Decoder): Role = when (val value = decoder.decodeString()) { 709 | "added" -> Added 710 | "analysisTarget" -> AnalysisTarget 711 | "attachment" -> Attachment 712 | "debugOutputFile" -> DebugOutputFile 713 | "deleted" -> Deleted 714 | "directory" -> Directory 715 | "driver" -> Driver 716 | "extension" -> Extension 717 | "memoryContents" -> MemoryContents 718 | "modified" -> Modified 719 | "policy" -> Policy 720 | "referencedOnCommandLine" -> ReferencedOnCommandLine 721 | "renamed" -> Renamed 722 | "responseFile" -> ResponseFile 723 | "resultFile" -> ResultFile 724 | "standardStream" -> StandardStream 725 | "taxonomy" -> Taxonomy 726 | "toolSpecifiedConfiguration" -> ToolSpecifiedConfiguration 727 | "tracedFile" -> TracedFile 728 | "translation" -> Translation 729 | "uncontrolled" -> Uncontrolled 730 | "unmodified" -> Unmodified 731 | "userSpecifiedConfiguration" -> UserSpecifiedConfiguration 732 | else -> throw IllegalArgumentException("Role could not parse: $value") 733 | } 734 | override fun serialize(encoder: Encoder, value: Role) { 735 | return encoder.encodeString(value.value) 736 | } 737 | } 738 | } 739 | 740 | /** 741 | * A conversion object that will be merged with a separate run. 742 | * 743 | * Describes how a converter transformed the output of a static analysis tool from the 744 | * analysis tool's native output format into the SARIF format. 745 | * 746 | * A conversion object that describes how a converter transformed an analysis tool's native 747 | * reporting format into the SARIF format. 748 | */ 749 | @Serializable 750 | public data class Conversion ( 751 | /** 752 | * The locations of the analysis tool's per-run log files. 753 | */ 754 | val analysisToolLogFiles: List? = null, 755 | 756 | /** 757 | * An invocation object that describes the invocation of the converter. 758 | */ 759 | val invocation: Invocation? = null, 760 | 761 | /** 762 | * Key/value pairs that provide additional information about the conversion. 763 | */ 764 | val properties: PropertyBag? = null, 765 | 766 | /** 767 | * A tool object that describes the converter. 768 | */ 769 | val tool: Tool 770 | ) 771 | 772 | /** 773 | * An invocation object that describes the invocation of the converter. 774 | * 775 | * The runtime environment of the analysis tool run. 776 | */ 777 | @Serializable 778 | public data class Invocation ( 779 | /** 780 | * The account under which the invocation occurred. 781 | */ 782 | val account: String? = null, 783 | 784 | /** 785 | * An array of strings, containing in order the command line arguments passed to the tool 786 | * from the operating system. 787 | */ 788 | val arguments: List? = null, 789 | 790 | /** 791 | * The command line used to invoke the tool. 792 | */ 793 | val commandLine: String? = null, 794 | 795 | /** 796 | * The Coordinated Universal Time (UTC) date and time at which the invocation ended. See 797 | * "Date/time properties" in the SARIF spec for the required format. 798 | */ 799 | @SerialName("endTimeUtc") 800 | val endTimeUTC: String? = null, 801 | 802 | /** 803 | * The environment variables associated with the analysis tool process, expressed as 804 | * key/value pairs. 805 | */ 806 | val environmentVariables: Map? = null, 807 | 808 | /** 809 | * An absolute URI specifying the location of the executable that was invoked. 810 | */ 811 | val executableLocation: ArtifactLocation? = null, 812 | 813 | /** 814 | * Specifies whether the tool's execution completed successfully. 815 | */ 816 | val executionSuccessful: Boolean, 817 | 818 | /** 819 | * The process exit code. 820 | */ 821 | val exitCode: Long? = null, 822 | 823 | /** 824 | * The reason for the process exit. 825 | */ 826 | val exitCodeDescription: String? = null, 827 | 828 | /** 829 | * The name of the signal that caused the process to exit. 830 | */ 831 | val exitSignalName: String? = null, 832 | 833 | /** 834 | * The numeric value of the signal that caused the process to exit. 835 | */ 836 | val exitSignalNumber: Long? = null, 837 | 838 | /** 839 | * The machine on which the invocation occurred. 840 | */ 841 | val machine: String? = null, 842 | 843 | /** 844 | * An array of configurationOverride objects that describe notifications related runtime 845 | * overrides. 846 | */ 847 | val notificationConfigurationOverrides: List? = null, 848 | 849 | /** 850 | * The id of the process in which the invocation occurred. 851 | */ 852 | @SerialName("processId") 853 | val processID: Long? = null, 854 | 855 | /** 856 | * The reason given by the operating system that the process failed to start. 857 | */ 858 | val processStartFailureMessage: String? = null, 859 | 860 | /** 861 | * Key/value pairs that provide additional information about the invocation. 862 | */ 863 | val properties: PropertyBag? = null, 864 | 865 | /** 866 | * The locations of any response files specified on the tool's command line. 867 | */ 868 | val responseFiles: List? = null, 869 | 870 | /** 871 | * An array of configurationOverride objects that describe rules related runtime overrides. 872 | */ 873 | val ruleConfigurationOverrides: List? = null, 874 | 875 | /** 876 | * The Coordinated Universal Time (UTC) date and time at which the invocation started. See 877 | * "Date/time properties" in the SARIF spec for the required format. 878 | */ 879 | @SerialName("startTimeUtc") 880 | val startTimeUTC: String? = null, 881 | 882 | /** 883 | * A file containing the standard error stream from the process that was invoked. 884 | */ 885 | val stderr: ArtifactLocation? = null, 886 | 887 | /** 888 | * A file containing the standard input stream to the process that was invoked. 889 | */ 890 | val stdin: ArtifactLocation? = null, 891 | 892 | /** 893 | * A file containing the standard output stream from the process that was invoked. 894 | */ 895 | val stdout: ArtifactLocation? = null, 896 | 897 | /** 898 | * A file containing the interleaved standard output and standard error stream from the 899 | * process that was invoked. 900 | */ 901 | val stdoutStderr: ArtifactLocation? = null, 902 | 903 | /** 904 | * A list of conditions detected by the tool that are relevant to the tool's configuration. 905 | */ 906 | val toolConfigurationNotifications: List? = null, 907 | 908 | /** 909 | * A list of runtime conditions detected by the tool during the analysis. 910 | */ 911 | val toolExecutionNotifications: List? = null, 912 | 913 | /** 914 | * The working directory for the invocation. 915 | */ 916 | val workingDirectory: ArtifactLocation? = null 917 | ) 918 | 919 | /** 920 | * Information about how a specific rule or notification was reconfigured at runtime. 921 | */ 922 | @Serializable 923 | public data class ConfigurationOverride ( 924 | /** 925 | * Specifies how the rule or notification was configured during the scan. 926 | */ 927 | val configuration: ReportingConfiguration, 928 | 929 | /** 930 | * A reference used to locate the descriptor whose configuration was overridden. 931 | */ 932 | val descriptor: ReportingDescriptorReference, 933 | 934 | /** 935 | * Key/value pairs that provide additional information about the configuration override. 936 | */ 937 | val properties: PropertyBag? = null 938 | ) 939 | 940 | /** 941 | * Specifies how the rule or notification was configured during the scan. 942 | * 943 | * Information about a rule or notification that can be configured at runtime. 944 | * 945 | * Default reporting configuration information. 946 | */ 947 | @Serializable 948 | public data class ReportingConfiguration ( 949 | /** 950 | * Specifies whether the report may be produced during the scan. 951 | */ 952 | val enabled: Boolean? = null, 953 | 954 | /** 955 | * Specifies the failure level for the report. 956 | */ 957 | val level: Level? = null, 958 | 959 | /** 960 | * Contains configuration information specific to a report. 961 | */ 962 | val parameters: PropertyBag? = null, 963 | 964 | /** 965 | * Key/value pairs that provide additional information about the reporting configuration. 966 | */ 967 | val properties: PropertyBag? = null, 968 | 969 | /** 970 | * Specifies the relative priority of the report. Used for analysis output only. 971 | */ 972 | val rank: Double? = null 973 | ) 974 | 975 | /** 976 | * Specifies the failure level for the report. 977 | * 978 | * A value specifying the severity level of the notification. 979 | * 980 | * A value specifying the severity level of the result. 981 | */ 982 | @Serializable(with = Level.Companion::class) 983 | public enum class Level( 984 | public val value: String, 985 | ) { 986 | Error("error"), 987 | None("none"), 988 | Note("note"), 989 | Warning("warning"); 990 | 991 | public companion object : KSerializer { 992 | override val descriptor: SerialDescriptor get() { 993 | return PrimitiveSerialDescriptor("quicktype.Level", PrimitiveKind.STRING) 994 | } 995 | override fun deserialize(decoder: Decoder): Level = when (val value = decoder.decodeString()) { 996 | "error" -> Error 997 | "none" -> None 998 | "note" -> Note 999 | "warning" -> Warning 1000 | else -> throw IllegalArgumentException("Level could not parse: $value") 1001 | } 1002 | override fun serialize(encoder: Encoder, value: Level) { 1003 | return encoder.encodeString(value.value) 1004 | } 1005 | } 1006 | } 1007 | 1008 | /** 1009 | * A reference used to locate the descriptor whose configuration was overridden. 1010 | * 1011 | * A reference used to locate the rule descriptor associated with this notification. 1012 | * 1013 | * A reference used to locate the descriptor relevant to this notification. 1014 | * 1015 | * A reference to the related reporting descriptor. 1016 | * 1017 | * A reference used to locate the rule descriptor relevant to this result. 1018 | * 1019 | * Information about how to locate a relevant reporting descriptor. 1020 | */ 1021 | @Serializable 1022 | public data class ReportingDescriptorReference ( 1023 | /** 1024 | * A guid that uniquely identifies the descriptor. 1025 | */ 1026 | val guid: String? = null, 1027 | 1028 | /** 1029 | * The id of the descriptor. 1030 | */ 1031 | val id: String? = null, 1032 | 1033 | /** 1034 | * The index into an array of descriptors in toolComponent.ruleDescriptors, 1035 | * toolComponent.notificationDescriptors, or toolComponent.taxonomyDescriptors, depending on 1036 | * context. 1037 | */ 1038 | val index: Long? = null, 1039 | 1040 | /** 1041 | * Key/value pairs that provide additional information about the reporting descriptor 1042 | * reference. 1043 | */ 1044 | val properties: PropertyBag? = null, 1045 | 1046 | /** 1047 | * A reference used to locate the toolComponent associated with the descriptor. 1048 | */ 1049 | val toolComponent: ToolComponentReference? = null 1050 | ) 1051 | 1052 | /** 1053 | * A reference used to locate the toolComponent associated with the descriptor. 1054 | * 1055 | * Identifies a particular toolComponent object, either the driver or an extension. 1056 | * 1057 | * The component which is strongly associated with this component. For a translation, this 1058 | * refers to the component which has been translated. For an extension, this is the driver 1059 | * that provides the extension's plugin model. 1060 | */ 1061 | @Serializable 1062 | public data class ToolComponentReference ( 1063 | /** 1064 | * The 'guid' property of the referenced toolComponent. 1065 | */ 1066 | val guid: String? = null, 1067 | 1068 | /** 1069 | * An index into the referenced toolComponent in tool.extensions. 1070 | */ 1071 | val index: Long? = null, 1072 | 1073 | /** 1074 | * The 'name' property of the referenced toolComponent. 1075 | */ 1076 | val name: String? = null, 1077 | 1078 | /** 1079 | * Key/value pairs that provide additional information about the toolComponentReference. 1080 | */ 1081 | val properties: PropertyBag? = null 1082 | ) 1083 | 1084 | /** 1085 | * Describes a condition relevant to the tool itself, as opposed to being relevant to a 1086 | * target being analyzed by the tool. 1087 | */ 1088 | @Serializable 1089 | public data class Notification ( 1090 | /** 1091 | * A reference used to locate the rule descriptor associated with this notification. 1092 | */ 1093 | val associatedRule: ReportingDescriptorReference? = null, 1094 | 1095 | /** 1096 | * A reference used to locate the descriptor relevant to this notification. 1097 | */ 1098 | val descriptor: ReportingDescriptorReference? = null, 1099 | 1100 | /** 1101 | * The runtime exception, if any, relevant to this notification. 1102 | */ 1103 | val exception: Exception? = null, 1104 | 1105 | /** 1106 | * A value specifying the severity level of the notification. 1107 | */ 1108 | val level: Level? = null, 1109 | 1110 | /** 1111 | * The locations relevant to this notification. 1112 | */ 1113 | val locations: List? = null, 1114 | 1115 | /** 1116 | * A message that describes the condition that was encountered. 1117 | */ 1118 | val message: Message, 1119 | 1120 | /** 1121 | * Key/value pairs that provide additional information about the notification. 1122 | */ 1123 | val properties: PropertyBag? = null, 1124 | 1125 | /** 1126 | * The thread identifier of the code that generated the notification. 1127 | */ 1128 | @SerialName("threadId") 1129 | val threadID: Long? = null, 1130 | 1131 | /** 1132 | * The Coordinated Universal Time (UTC) date and time at which the analysis tool generated 1133 | * the notification. 1134 | */ 1135 | @SerialName("timeUtc") 1136 | val timeUTC: String? = null 1137 | ) 1138 | 1139 | /** 1140 | * The runtime exception, if any, relevant to this notification. 1141 | * 1142 | * Describes a runtime exception encountered during the execution of an analysis tool. 1143 | */ 1144 | @Serializable 1145 | public data class Exception ( 1146 | /** 1147 | * An array of exception objects each of which is considered a cause of this exception. 1148 | */ 1149 | val innerExceptions: List? = null, 1150 | 1151 | /** 1152 | * A string that identifies the kind of exception, for example, the fully qualified type 1153 | * name of an object that was thrown, or the symbolic name of a signal. 1154 | */ 1155 | val kind: String? = null, 1156 | 1157 | /** 1158 | * A message that describes the exception. 1159 | */ 1160 | val message: String? = null, 1161 | 1162 | /** 1163 | * Key/value pairs that provide additional information about the exception. 1164 | */ 1165 | val properties: PropertyBag? = null, 1166 | 1167 | /** 1168 | * The sequence of function calls leading to the exception. 1169 | */ 1170 | val stack: Stack? = null 1171 | ) 1172 | 1173 | /** 1174 | * The sequence of function calls leading to the exception. 1175 | * 1176 | * A call stack that is relevant to a result. 1177 | * 1178 | * The call stack leading to this location. 1179 | */ 1180 | @Serializable 1181 | public data class Stack ( 1182 | /** 1183 | * An array of stack frames that represents a sequence of calls, rendered in reverse 1184 | * chronological order, that comprise the call stack. 1185 | */ 1186 | val frames: List, 1187 | 1188 | /** 1189 | * A message relevant to this call stack. 1190 | */ 1191 | val message: Message? = null, 1192 | 1193 | /** 1194 | * Key/value pairs that provide additional information about the stack. 1195 | */ 1196 | val properties: PropertyBag? = null 1197 | ) 1198 | 1199 | /** 1200 | * A function call within a stack trace. 1201 | */ 1202 | @Serializable 1203 | public data class StackFrame ( 1204 | /** 1205 | * The location to which this stack frame refers. 1206 | */ 1207 | val location: Location? = null, 1208 | 1209 | /** 1210 | * The name of the module that contains the code of this stack frame. 1211 | */ 1212 | val module: String? = null, 1213 | 1214 | /** 1215 | * The parameters of the call that is executing. 1216 | */ 1217 | val parameters: List? = null, 1218 | 1219 | /** 1220 | * Key/value pairs that provide additional information about the stack frame. 1221 | */ 1222 | val properties: PropertyBag? = null, 1223 | 1224 | /** 1225 | * The thread identifier of the stack frame. 1226 | */ 1227 | @SerialName("threadId") 1228 | val threadID: Long? = null 1229 | ) 1230 | 1231 | /** 1232 | * The location to which this stack frame refers. 1233 | * 1234 | * A location within a programming artifact. 1235 | * 1236 | * A code location associated with the node. 1237 | * 1238 | * The code location. 1239 | * 1240 | * Identifies the location associated with the suppression. 1241 | */ 1242 | @Serializable 1243 | public data class Location ( 1244 | /** 1245 | * A set of regions relevant to the location. 1246 | */ 1247 | val annotations: List? = null, 1248 | 1249 | /** 1250 | * Value that distinguishes this location from all other locations within a single result 1251 | * object. 1252 | */ 1253 | val id: Long? = null, 1254 | 1255 | /** 1256 | * The logical locations associated with the result. 1257 | */ 1258 | val logicalLocations: List? = null, 1259 | 1260 | /** 1261 | * A message relevant to the location. 1262 | */ 1263 | val message: Message? = null, 1264 | 1265 | /** 1266 | * Identifies the artifact and region. 1267 | */ 1268 | val physicalLocation: PhysicalLocation? = null, 1269 | 1270 | /** 1271 | * Key/value pairs that provide additional information about the location. 1272 | */ 1273 | val properties: PropertyBag? = null, 1274 | 1275 | /** 1276 | * An array of objects that describe relationships between this location and others. 1277 | */ 1278 | val relationships: List? = null 1279 | ) 1280 | 1281 | /** 1282 | * Specifies a portion of the artifact that encloses the region. Allows a viewer to display 1283 | * additional context around the region. 1284 | * 1285 | * Specifies a portion of the artifact. 1286 | * 1287 | * The region of the artifact to delete. 1288 | * 1289 | * A region within an artifact where a result was detected. 1290 | */ 1291 | @Serializable 1292 | public data class Region ( 1293 | /** 1294 | * The length of the region in bytes. 1295 | */ 1296 | val byteLength: Long? = null, 1297 | 1298 | /** 1299 | * The zero-based offset from the beginning of the artifact of the first byte in the region. 1300 | */ 1301 | val byteOffset: Long? = null, 1302 | 1303 | /** 1304 | * The length of the region in characters. 1305 | */ 1306 | val charLength: Long? = null, 1307 | 1308 | /** 1309 | * The zero-based offset from the beginning of the artifact of the first character in the 1310 | * region. 1311 | */ 1312 | val charOffset: Long? = null, 1313 | 1314 | /** 1315 | * The column number of the character following the end of the region. 1316 | */ 1317 | val endColumn: Long? = null, 1318 | 1319 | /** 1320 | * The line number of the last character in the region. 1321 | */ 1322 | val endLine: Long? = null, 1323 | 1324 | /** 1325 | * A message relevant to the region. 1326 | */ 1327 | val message: Message? = null, 1328 | 1329 | /** 1330 | * Key/value pairs that provide additional information about the region. 1331 | */ 1332 | val properties: PropertyBag? = null, 1333 | 1334 | /** 1335 | * The portion of the artifact contents within the specified region. 1336 | */ 1337 | val snippet: ArtifactContent? = null, 1338 | 1339 | /** 1340 | * Specifies the source language, if any, of the portion of the artifact specified by the 1341 | * region object. 1342 | */ 1343 | val sourceLanguage: String? = null, 1344 | 1345 | /** 1346 | * The column number of the first character in the region. 1347 | */ 1348 | val startColumn: Long? = null, 1349 | 1350 | /** 1351 | * The line number of the first character in the region. 1352 | */ 1353 | val startLine: Long? = null 1354 | ) 1355 | 1356 | /** 1357 | * A logical location of a construct that produced a result. 1358 | */ 1359 | @Serializable 1360 | public data class LogicalLocation ( 1361 | /** 1362 | * The machine-readable name for the logical location, such as a mangled function name 1363 | * provided by a C++ compiler that encodes calling convention, return type and other details 1364 | * along with the function name. 1365 | */ 1366 | val decoratedName: String? = null, 1367 | 1368 | /** 1369 | * The human-readable fully qualified name of the logical location. 1370 | */ 1371 | val fullyQualifiedName: String? = null, 1372 | 1373 | /** 1374 | * The index within the logical locations array. 1375 | */ 1376 | val index: Long? = null, 1377 | 1378 | /** 1379 | * The type of construct this logical location component refers to. Should be one of 1380 | * 'function', 'member', 'module', 'namespace', 'parameter', 'resource', 'returnType', 1381 | * 'type', 'variable', 'object', 'array', 'property', 'value', 'element', 'text', 1382 | * 'attribute', 'comment', 'declaration', 'dtd' or 'processingInstruction', if any of those 1383 | * accurately describe the construct. 1384 | */ 1385 | val kind: String? = null, 1386 | 1387 | /** 1388 | * Identifies the construct in which the result occurred. For example, this property might 1389 | * contain the name of a class or a method. 1390 | */ 1391 | val name: String? = null, 1392 | 1393 | /** 1394 | * Identifies the index of the immediate parent of the construct in which the result was 1395 | * detected. For example, this property might point to a logical location that represents 1396 | * the namespace that holds a type. 1397 | */ 1398 | val parentIndex: Long? = null, 1399 | 1400 | /** 1401 | * Key/value pairs that provide additional information about the logical location. 1402 | */ 1403 | val properties: PropertyBag? = null 1404 | ) 1405 | 1406 | /** 1407 | * Identifies the artifact and region. 1408 | * 1409 | * A physical location relevant to a result. Specifies a reference to a programming artifact 1410 | * together with a range of bytes or characters within that artifact. 1411 | */ 1412 | @Serializable 1413 | public data class PhysicalLocation ( 1414 | /** 1415 | * The address of the location. 1416 | */ 1417 | val address: Address? = null, 1418 | 1419 | /** 1420 | * The location of the artifact. 1421 | */ 1422 | val artifactLocation: ArtifactLocation? = null, 1423 | 1424 | /** 1425 | * Specifies a portion of the artifact that encloses the region. Allows a viewer to display 1426 | * additional context around the region. 1427 | */ 1428 | val contextRegion: Region? = null, 1429 | 1430 | /** 1431 | * Key/value pairs that provide additional information about the physical location. 1432 | */ 1433 | val properties: PropertyBag? = null, 1434 | 1435 | /** 1436 | * Specifies a portion of the artifact. 1437 | */ 1438 | val region: Region? = null 1439 | ) 1440 | 1441 | /** 1442 | * Information about the relation of one location to another. 1443 | */ 1444 | @Serializable 1445 | public data class LocationRelationship ( 1446 | /** 1447 | * A description of the location relationship. 1448 | */ 1449 | val description: Message? = null, 1450 | 1451 | /** 1452 | * A set of distinct strings that categorize the relationship. Well-known kinds include 1453 | * 'includes', 'isIncludedBy' and 'relevant'. 1454 | */ 1455 | val kinds: List? = null, 1456 | 1457 | /** 1458 | * Key/value pairs that provide additional information about the location relationship. 1459 | */ 1460 | val properties: PropertyBag? = null, 1461 | 1462 | /** 1463 | * A reference to the related location. 1464 | */ 1465 | val target: Long 1466 | ) 1467 | 1468 | /** 1469 | * A tool object that describes the converter. 1470 | * 1471 | * The analysis tool that was run. 1472 | * 1473 | * Information about the tool or tool pipeline that generated the results in this run. A run 1474 | * can only contain results produced by a single tool or tool pipeline. A run can aggregate 1475 | * results from multiple log files, as long as context around the tool run (tool 1476 | * command-line arguments and the like) is identical for all aggregated files. 1477 | */ 1478 | @Serializable 1479 | public data class Tool ( 1480 | /** 1481 | * The analysis tool that was run. 1482 | */ 1483 | val driver: ToolComponent, 1484 | 1485 | /** 1486 | * Tool extensions that contributed to or reconfigured the analysis tool that was run. 1487 | */ 1488 | val extensions: List? = null, 1489 | 1490 | /** 1491 | * Key/value pairs that provide additional information about the tool. 1492 | */ 1493 | val properties: PropertyBag? = null 1494 | ) 1495 | 1496 | /** 1497 | * The analysis tool that was run. 1498 | * 1499 | * A component, such as a plug-in or the driver, of the analysis tool that was run. 1500 | * 1501 | * The analysis tool object that will be merged with a separate run. 1502 | */ 1503 | @Serializable 1504 | public data class ToolComponent ( 1505 | /** 1506 | * The component which is strongly associated with this component. For a translation, this 1507 | * refers to the component which has been translated. For an extension, this is the driver 1508 | * that provides the extension's plugin model. 1509 | */ 1510 | val associatedComponent: ToolComponentReference? = null, 1511 | 1512 | /** 1513 | * The kinds of data contained in this object. 1514 | */ 1515 | val contents: List? = null, 1516 | 1517 | /** 1518 | * The binary version of the tool component's primary executable file expressed as four 1519 | * non-negative integers separated by a period (for operating systems that express file 1520 | * versions in this way). 1521 | */ 1522 | val dottedQuadFileVersion: String? = null, 1523 | 1524 | /** 1525 | * The absolute URI from which the tool component can be downloaded. 1526 | */ 1527 | @SerialName("downloadUri") 1528 | val downloadURI: String? = null, 1529 | 1530 | /** 1531 | * A comprehensive description of the tool component. 1532 | */ 1533 | val fullDescription: MultiformatMessageString? = null, 1534 | 1535 | /** 1536 | * The name of the tool component along with its version and any other useful identifying 1537 | * information, such as its locale. 1538 | */ 1539 | val fullName: String? = null, 1540 | 1541 | /** 1542 | * A dictionary, each of whose keys is a resource identifier and each of whose values is a 1543 | * multiformatMessageString object, which holds message strings in plain text and 1544 | * (optionally) Markdown format. The strings can include placeholders, which can be used to 1545 | * construct a message in combination with an arbitrary number of additional string 1546 | * arguments. 1547 | */ 1548 | val globalMessageStrings: Map? = null, 1549 | 1550 | /** 1551 | * A unique identifier for the tool component in the form of a GUID. 1552 | */ 1553 | val guid: String? = null, 1554 | 1555 | /** 1556 | * The absolute URI at which information about this version of the tool component can be 1557 | * found. 1558 | */ 1559 | @SerialName("informationUri") 1560 | val informationURI: String? = null, 1561 | 1562 | /** 1563 | * Specifies whether this object contains a complete definition of the localizable and/or 1564 | * non-localizable data for this component, as opposed to including only data that is 1565 | * relevant to the results persisted to this log file. 1566 | */ 1567 | val isComprehensive: Boolean? = null, 1568 | 1569 | /** 1570 | * The language of the messages emitted into the log file during this run (expressed as an 1571 | * ISO 639-1 two-letter lowercase language code) and an optional region (expressed as an ISO 1572 | * 3166-1 two-letter uppercase subculture code associated with a country or region). The 1573 | * casing is recommended but not required (in order for this data to conform to RFC5646). 1574 | */ 1575 | val language: String? = null, 1576 | 1577 | /** 1578 | * The semantic version of the localized strings defined in this component; maintained by 1579 | * components that provide translations. 1580 | */ 1581 | val localizedDataSemanticVersion: String? = null, 1582 | 1583 | /** 1584 | * An array of the artifactLocation objects associated with the tool component. 1585 | */ 1586 | val locations: List? = null, 1587 | 1588 | /** 1589 | * The minimum value of localizedDataSemanticVersion required in translations consumed by 1590 | * this component; used by components that consume translations. 1591 | */ 1592 | val minimumRequiredLocalizedDataSemanticVersion: String? = null, 1593 | 1594 | /** 1595 | * The name of the tool component. 1596 | */ 1597 | val name: String, 1598 | 1599 | /** 1600 | * An array of reportingDescriptor objects relevant to the notifications related to the 1601 | * configuration and runtime execution of the tool component. 1602 | */ 1603 | val notifications: List? = null, 1604 | 1605 | /** 1606 | * The organization or company that produced the tool component. 1607 | */ 1608 | val organization: String? = null, 1609 | 1610 | /** 1611 | * A product suite to which the tool component belongs. 1612 | */ 1613 | val product: String? = null, 1614 | 1615 | /** 1616 | * A localizable string containing the name of the suite of products to which the tool 1617 | * component belongs. 1618 | */ 1619 | val productSuite: String? = null, 1620 | 1621 | /** 1622 | * Key/value pairs that provide additional information about the tool component. 1623 | */ 1624 | val properties: PropertyBag? = null, 1625 | 1626 | /** 1627 | * A string specifying the UTC date (and optionally, the time) of the component's release. 1628 | */ 1629 | @SerialName("releaseDateUtc") 1630 | val releaseDateUTC: String? = null, 1631 | 1632 | /** 1633 | * An array of reportingDescriptor objects relevant to the analysis performed by the tool 1634 | * component. 1635 | */ 1636 | val rules: List? = null, 1637 | 1638 | /** 1639 | * The tool component version in the format specified by Semantic Versioning 2.0. 1640 | */ 1641 | val semanticVersion: String? = null, 1642 | 1643 | /** 1644 | * A brief description of the tool component. 1645 | */ 1646 | val shortDescription: MultiformatMessageString? = null, 1647 | 1648 | /** 1649 | * An array of toolComponentReference objects to declare the taxonomies supported by the 1650 | * tool component. 1651 | */ 1652 | val supportedTaxonomies: List? = null, 1653 | 1654 | /** 1655 | * An array of reportingDescriptor objects relevant to the definitions of both standalone 1656 | * and tool-defined taxonomies. 1657 | */ 1658 | val taxa: List? = null, 1659 | 1660 | /** 1661 | * Translation metadata, required for a translation, not populated by other component types. 1662 | */ 1663 | val translationMetadata: TranslationMetadata? = null, 1664 | 1665 | /** 1666 | * The tool component version, in whatever format the component natively provides. 1667 | */ 1668 | val version: String? = null 1669 | ) 1670 | 1671 | @Serializable(with = Content.Companion::class) 1672 | public enum class Content( 1673 | public val value: String, 1674 | ) { 1675 | LocalizedData("localizedData"), 1676 | NonLocalizedData("nonLocalizedData"); 1677 | 1678 | public companion object : KSerializer { 1679 | override val descriptor: SerialDescriptor get() { 1680 | return PrimitiveSerialDescriptor("quicktype.Content", PrimitiveKind.STRING) 1681 | } 1682 | override fun deserialize(decoder: Decoder): Content = when (val value = decoder.decodeString()) { 1683 | "localizedData" -> LocalizedData 1684 | "nonLocalizedData" -> NonLocalizedData 1685 | else -> throw IllegalArgumentException("Content could not parse: $value") 1686 | } 1687 | override fun serialize(encoder: Encoder, value: Content) { 1688 | return encoder.encodeString(value.value) 1689 | } 1690 | } 1691 | } 1692 | 1693 | /** 1694 | * Metadata that describes a specific report produced by the tool, as part of the analysis 1695 | * it provides or its runtime reporting. 1696 | */ 1697 | @Serializable 1698 | public data class ReportingDescriptor ( 1699 | /** 1700 | * Default reporting configuration information. 1701 | */ 1702 | val defaultConfiguration: ReportingConfiguration? = null, 1703 | 1704 | /** 1705 | * An array of unique identifies in the form of a GUID by which this report was known in 1706 | * some previous version of the analysis tool. 1707 | */ 1708 | val deprecatedGuids: List? = null, 1709 | 1710 | /** 1711 | * An array of stable, opaque identifiers by which this report was known in some previous 1712 | * version of the analysis tool. 1713 | */ 1714 | @SerialName("deprecatedIds") 1715 | val deprecatedIDS: List? = null, 1716 | 1717 | /** 1718 | * An array of readable identifiers by which this report was known in some previous version 1719 | * of the analysis tool. 1720 | */ 1721 | val deprecatedNames: List? = null, 1722 | 1723 | /** 1724 | * A description of the report. Should, as far as possible, provide details sufficient to 1725 | * enable resolution of any problem indicated by the result. 1726 | */ 1727 | val fullDescription: MultiformatMessageString? = null, 1728 | 1729 | /** 1730 | * A unique identifier for the reporting descriptor in the form of a GUID. 1731 | */ 1732 | val guid: String? = null, 1733 | 1734 | /** 1735 | * Provides the primary documentation for the report, useful when there is no online 1736 | * documentation. 1737 | */ 1738 | val help: MultiformatMessageString? = null, 1739 | 1740 | /** 1741 | * A URI where the primary documentation for the report can be found. 1742 | */ 1743 | @SerialName("helpUri") 1744 | val helpURI: String? = null, 1745 | 1746 | /** 1747 | * A stable, opaque identifier for the report. 1748 | */ 1749 | val id: String, 1750 | 1751 | /** 1752 | * A set of name/value pairs with arbitrary names. Each value is a multiformatMessageString 1753 | * object, which holds message strings in plain text and (optionally) Markdown format. The 1754 | * strings can include placeholders, which can be used to construct a message in combination 1755 | * with an arbitrary number of additional string arguments. 1756 | */ 1757 | val messageStrings: Map? = null, 1758 | 1759 | /** 1760 | * A report identifier that is understandable to an end user. 1761 | */ 1762 | val name: String? = null, 1763 | 1764 | /** 1765 | * Key/value pairs that provide additional information about the report. 1766 | */ 1767 | val properties: PropertyBag? = null, 1768 | 1769 | /** 1770 | * An array of objects that describe relationships between this reporting descriptor and 1771 | * others. 1772 | */ 1773 | val relationships: List? = null, 1774 | 1775 | /** 1776 | * A concise description of the report. Should be a single sentence that is understandable 1777 | * when visible space is limited to a single line of text. 1778 | */ 1779 | val shortDescription: MultiformatMessageString? = null 1780 | ) 1781 | 1782 | /** 1783 | * Information about the relation of one reporting descriptor to another. 1784 | */ 1785 | @Serializable 1786 | public data class ReportingDescriptorRelationship ( 1787 | /** 1788 | * A description of the reporting descriptor relationship. 1789 | */ 1790 | val description: Message? = null, 1791 | 1792 | /** 1793 | * A set of distinct strings that categorize the relationship. Well-known kinds include 1794 | * 'canPrecede', 'canFollow', 'willPrecede', 'willFollow', 'superset', 'subset', 'equal', 1795 | * 'disjoint', 'relevant', and 'incomparable'. 1796 | */ 1797 | val kinds: List? = null, 1798 | 1799 | /** 1800 | * Key/value pairs that provide additional information about the reporting descriptor 1801 | * reference. 1802 | */ 1803 | val properties: PropertyBag? = null, 1804 | 1805 | /** 1806 | * A reference to the related reporting descriptor. 1807 | */ 1808 | val target: ReportingDescriptorReference 1809 | ) 1810 | 1811 | /** 1812 | * Translation metadata, required for a translation, not populated by other component 1813 | * types. 1814 | * 1815 | * Provides additional metadata related to translation. 1816 | */ 1817 | @Serializable 1818 | public data class TranslationMetadata ( 1819 | /** 1820 | * The absolute URI from which the translation metadata can be downloaded. 1821 | */ 1822 | @SerialName("downloadUri") 1823 | val downloadURI: String? = null, 1824 | 1825 | /** 1826 | * A comprehensive description of the translation metadata. 1827 | */ 1828 | val fullDescription: MultiformatMessageString? = null, 1829 | 1830 | /** 1831 | * The full name associated with the translation metadata. 1832 | */ 1833 | val fullName: String? = null, 1834 | 1835 | /** 1836 | * The absolute URI from which information related to the translation metadata can be 1837 | * downloaded. 1838 | */ 1839 | @SerialName("informationUri") 1840 | val informationURI: String? = null, 1841 | 1842 | /** 1843 | * The name associated with the translation metadata. 1844 | */ 1845 | val name: String, 1846 | 1847 | /** 1848 | * Key/value pairs that provide additional information about the translation metadata. 1849 | */ 1850 | val properties: PropertyBag? = null, 1851 | 1852 | /** 1853 | * A brief description of the translation metadata. 1854 | */ 1855 | val shortDescription: MultiformatMessageString? = null 1856 | ) 1857 | 1858 | /** 1859 | * A network of nodes and directed edges that describes some aspect of the structure of the 1860 | * code (for example, a call graph). 1861 | */ 1862 | @Serializable 1863 | public data class Graph ( 1864 | /** 1865 | * A description of the graph. 1866 | */ 1867 | val description: Message? = null, 1868 | 1869 | /** 1870 | * An array of edge objects representing the edges of the graph. 1871 | */ 1872 | val edges: List? = null, 1873 | 1874 | /** 1875 | * An array of node objects representing the nodes of the graph. 1876 | */ 1877 | val nodes: List? = null, 1878 | 1879 | /** 1880 | * Key/value pairs that provide additional information about the graph. 1881 | */ 1882 | val properties: PropertyBag? = null 1883 | ) 1884 | 1885 | /** 1886 | * Represents a directed edge in a graph. 1887 | */ 1888 | @Serializable 1889 | public data class Edge ( 1890 | /** 1891 | * A string that uniquely identifies the edge within its graph. 1892 | */ 1893 | val id: String, 1894 | 1895 | /** 1896 | * A short description of the edge. 1897 | */ 1898 | val label: Message? = null, 1899 | 1900 | /** 1901 | * Key/value pairs that provide additional information about the edge. 1902 | */ 1903 | val properties: PropertyBag? = null, 1904 | 1905 | /** 1906 | * Identifies the source node (the node at which the edge starts). 1907 | */ 1908 | @SerialName("sourceNodeId") 1909 | val sourceNodeID: String, 1910 | 1911 | /** 1912 | * Identifies the target node (the node at which the edge ends). 1913 | */ 1914 | @SerialName("targetNodeId") 1915 | val targetNodeID: String 1916 | ) 1917 | 1918 | /** 1919 | * Represents a node in a graph. 1920 | */ 1921 | @Serializable 1922 | public data class Node ( 1923 | /** 1924 | * Array of child nodes. 1925 | */ 1926 | val children: List? = null, 1927 | 1928 | /** 1929 | * A string that uniquely identifies the node within its graph. 1930 | */ 1931 | val id: String, 1932 | 1933 | /** 1934 | * A short description of the node. 1935 | */ 1936 | val label: Message? = null, 1937 | 1938 | /** 1939 | * A code location associated with the node. 1940 | */ 1941 | val location: Location? = null, 1942 | 1943 | /** 1944 | * Key/value pairs that provide additional information about the node. 1945 | */ 1946 | val properties: PropertyBag? = null 1947 | ) 1948 | 1949 | /** 1950 | * A result produced by an analysis tool. 1951 | */ 1952 | @Serializable 1953 | public data class Result ( 1954 | /** 1955 | * Identifies the artifact that the analysis tool was instructed to scan. This need not be 1956 | * the same as the artifact where the result actually occurred. 1957 | */ 1958 | val analysisTarget: ArtifactLocation? = null, 1959 | 1960 | /** 1961 | * A set of artifacts relevant to the result. 1962 | */ 1963 | val attachments: List? = null, 1964 | 1965 | /** 1966 | * The state of a result relative to a baseline of a previous run. 1967 | */ 1968 | val baselineState: BaselineState? = null, 1969 | 1970 | /** 1971 | * An array of 'codeFlow' objects relevant to the result. 1972 | */ 1973 | val codeFlows: List? = null, 1974 | 1975 | /** 1976 | * A stable, unique identifier for the equivalence class of logically identical results to 1977 | * which this result belongs, in the form of a GUID. 1978 | */ 1979 | @SerialName("correlationGuid") 1980 | val correlationGUID: String? = null, 1981 | 1982 | /** 1983 | * A set of strings each of which individually defines a stable, unique identity for the 1984 | * result. 1985 | */ 1986 | val fingerprints: Map? = null, 1987 | 1988 | /** 1989 | * An array of 'fix' objects, each of which represents a proposed fix to the problem 1990 | * indicated by the result. 1991 | */ 1992 | val fixes: List? = null, 1993 | 1994 | /** 1995 | * An array of zero or more unique graph objects associated with the result. 1996 | */ 1997 | val graphs: List? = null, 1998 | 1999 | /** 2000 | * An array of one or more unique 'graphTraversal' objects. 2001 | */ 2002 | val graphTraversals: List? = null, 2003 | 2004 | /** 2005 | * A stable, unique identifier for the result in the form of a GUID. 2006 | */ 2007 | val guid: String? = null, 2008 | 2009 | /** 2010 | * An absolute URI at which the result can be viewed. 2011 | */ 2012 | @SerialName("hostedViewerUri") 2013 | val hostedViewerURI: String? = null, 2014 | 2015 | /** 2016 | * A value that categorizes results by evaluation state. 2017 | */ 2018 | val kind: ResultKind? = null, 2019 | 2020 | /** 2021 | * A value specifying the severity level of the result. 2022 | */ 2023 | val level: Level? = null, 2024 | 2025 | /** 2026 | * The set of locations where the result was detected. Specify only one location unless the 2027 | * problem indicated by the result can only be corrected by making a change at every 2028 | * specified location. 2029 | */ 2030 | val locations: List? = null, 2031 | 2032 | /** 2033 | * A message that describes the result. The first sentence of the message only will be 2034 | * displayed when visible space is limited. 2035 | */ 2036 | val message: Message, 2037 | 2038 | /** 2039 | * A positive integer specifying the number of times this logically unique result was 2040 | * observed in this run. 2041 | */ 2042 | val occurrenceCount: Long? = null, 2043 | 2044 | /** 2045 | * A set of strings that contribute to the stable, unique identity of the result. 2046 | */ 2047 | val partialFingerprints: Map? = null, 2048 | 2049 | /** 2050 | * Key/value pairs that provide additional information about the result. 2051 | */ 2052 | val properties: PropertyBag? = null, 2053 | 2054 | /** 2055 | * Information about how and when the result was detected. 2056 | */ 2057 | val provenance: ResultProvenance? = null, 2058 | 2059 | /** 2060 | * A number representing the priority or importance of the result. 2061 | */ 2062 | val rank: Double? = null, 2063 | 2064 | /** 2065 | * A set of locations relevant to this result. 2066 | */ 2067 | val relatedLocations: List? = null, 2068 | 2069 | /** 2070 | * A reference used to locate the rule descriptor relevant to this result. 2071 | */ 2072 | val rule: ReportingDescriptorReference? = null, 2073 | 2074 | /** 2075 | * The stable, unique identifier of the rule, if any, to which this result is relevant. 2076 | */ 2077 | @SerialName("ruleId") 2078 | val ruleID: String? = null, 2079 | 2080 | /** 2081 | * The index within the tool component rules array of the rule object associated with this 2082 | * result. 2083 | */ 2084 | val ruleIndex: Long? = null, 2085 | 2086 | /** 2087 | * An array of 'stack' objects relevant to the result. 2088 | */ 2089 | val stacks: List? = null, 2090 | 2091 | /** 2092 | * A set of suppressions relevant to this result. 2093 | */ 2094 | val suppressions: List? = null, 2095 | 2096 | /** 2097 | * An array of references to taxonomy reporting descriptors that are applicable to the 2098 | * result. 2099 | */ 2100 | val taxa: List? = null, 2101 | 2102 | /** 2103 | * A web request associated with this result. 2104 | */ 2105 | val webRequest: WebRequest? = null, 2106 | 2107 | /** 2108 | * A web response associated with this result. 2109 | */ 2110 | val webResponse: WebResponse? = null, 2111 | 2112 | /** 2113 | * The URIs of the work items associated with this result. 2114 | */ 2115 | val workItemUris: List? = null 2116 | ) 2117 | 2118 | /** 2119 | * An artifact relevant to a result. 2120 | */ 2121 | @Serializable 2122 | public data class Attachment ( 2123 | /** 2124 | * The location of the attachment. 2125 | */ 2126 | val artifactLocation: ArtifactLocation, 2127 | 2128 | /** 2129 | * A message describing the role played by the attachment. 2130 | */ 2131 | val description: Message? = null, 2132 | 2133 | /** 2134 | * Key/value pairs that provide additional information about the attachment. 2135 | */ 2136 | val properties: PropertyBag? = null, 2137 | 2138 | /** 2139 | * An array of rectangles specifying areas of interest within the image. 2140 | */ 2141 | val rectangles: List? = null, 2142 | 2143 | /** 2144 | * An array of regions of interest within the attachment. 2145 | */ 2146 | val regions: List? = null 2147 | ) 2148 | 2149 | /** 2150 | * An area within an image. 2151 | */ 2152 | @Serializable 2153 | public data class Rectangle ( 2154 | /** 2155 | * The Y coordinate of the bottom edge of the rectangle, measured in the image's natural 2156 | * units. 2157 | */ 2158 | val bottom: Double? = null, 2159 | 2160 | /** 2161 | * The X coordinate of the left edge of the rectangle, measured in the image's natural units. 2162 | */ 2163 | val left: Double? = null, 2164 | 2165 | /** 2166 | * A message relevant to the rectangle. 2167 | */ 2168 | val message: Message? = null, 2169 | 2170 | /** 2171 | * Key/value pairs that provide additional information about the rectangle. 2172 | */ 2173 | val properties: PropertyBag? = null, 2174 | 2175 | /** 2176 | * The X coordinate of the right edge of the rectangle, measured in the image's natural 2177 | * units. 2178 | */ 2179 | val right: Double? = null, 2180 | 2181 | /** 2182 | * The Y coordinate of the top edge of the rectangle, measured in the image's natural units. 2183 | */ 2184 | val top: Double? = null 2185 | ) 2186 | 2187 | /** 2188 | * The state of a result relative to a baseline of a previous run. 2189 | */ 2190 | @Serializable(with = BaselineState.Companion::class) 2191 | public enum class BaselineState( 2192 | public val value: String, 2193 | ) { 2194 | Absent("absent"), 2195 | New("new"), 2196 | Unchanged("unchanged"), 2197 | Updated("updated"); 2198 | 2199 | public companion object : KSerializer { 2200 | override val descriptor: SerialDescriptor get() { 2201 | return PrimitiveSerialDescriptor("quicktype.BaselineState", PrimitiveKind.STRING) 2202 | } 2203 | override fun deserialize(decoder: Decoder): BaselineState = when (val value = decoder.decodeString()) { 2204 | "absent" -> Absent 2205 | "new" -> New 2206 | "unchanged" -> Unchanged 2207 | "updated" -> Updated 2208 | else -> throw IllegalArgumentException("BaselineState could not parse: $value") 2209 | } 2210 | override fun serialize(encoder: Encoder, value: BaselineState) { 2211 | return encoder.encodeString(value.value) 2212 | } 2213 | } 2214 | } 2215 | 2216 | /** 2217 | * A set of threadFlows which together describe a pattern of code execution relevant to 2218 | * detecting a result. 2219 | */ 2220 | @Serializable 2221 | public data class CodeFlow ( 2222 | /** 2223 | * A message relevant to the code flow. 2224 | */ 2225 | val message: Message? = null, 2226 | 2227 | /** 2228 | * Key/value pairs that provide additional information about the code flow. 2229 | */ 2230 | val properties: PropertyBag? = null, 2231 | 2232 | /** 2233 | * An array of one or more unique threadFlow objects, each of which describes the progress 2234 | * of a program through a thread of execution. 2235 | */ 2236 | val threadFlows: List 2237 | ) 2238 | 2239 | /** 2240 | * Describes a sequence of code locations that specify a path through a single thread of 2241 | * execution such as an operating system or fiber. 2242 | */ 2243 | @Serializable 2244 | public data class ThreadFlow ( 2245 | /** 2246 | * An string that uniquely identifies the threadFlow within the codeFlow in which it occurs. 2247 | */ 2248 | val id: String? = null, 2249 | 2250 | /** 2251 | * Values of relevant expressions at the start of the thread flow that remain constant. 2252 | */ 2253 | val immutableState: Map? = null, 2254 | 2255 | /** 2256 | * Values of relevant expressions at the start of the thread flow that may change during 2257 | * thread flow execution. 2258 | */ 2259 | val initialState: Map? = null, 2260 | 2261 | /** 2262 | * A temporally ordered array of 'threadFlowLocation' objects, each of which describes a 2263 | * location visited by the tool while producing the result. 2264 | */ 2265 | val locations: List, 2266 | 2267 | /** 2268 | * A message relevant to the thread flow. 2269 | */ 2270 | val message: Message? = null, 2271 | 2272 | /** 2273 | * Key/value pairs that provide additional information about the thread flow. 2274 | */ 2275 | val properties: PropertyBag? = null 2276 | ) 2277 | 2278 | /** 2279 | * A location visited by an analysis tool while simulating or monitoring the execution of a 2280 | * program. 2281 | */ 2282 | @Serializable 2283 | public data class ThreadFlowLocation ( 2284 | /** 2285 | * An integer representing the temporal order in which execution reached this location. 2286 | */ 2287 | val executionOrder: Long? = null, 2288 | 2289 | /** 2290 | * The Coordinated Universal Time (UTC) date and time at which this location was executed. 2291 | */ 2292 | @SerialName("executionTimeUtc") 2293 | val executionTimeUTC: String? = null, 2294 | 2295 | /** 2296 | * Specifies the importance of this location in understanding the code flow in which it 2297 | * occurs. The order from most to least important is "essential", "important", 2298 | * "unimportant". Default: "important". 2299 | */ 2300 | val importance: Importance? = null, 2301 | 2302 | /** 2303 | * The index within the run threadFlowLocations array. 2304 | */ 2305 | val index: Long? = null, 2306 | 2307 | /** 2308 | * A set of distinct strings that categorize the thread flow location. Well-known kinds 2309 | * include 'acquire', 'release', 'enter', 'exit', 'call', 'return', 'branch', 'implicit', 2310 | * 'false', 'true', 'caution', 'danger', 'unknown', 'unreachable', 'taint', 'function', 2311 | * 'handler', 'lock', 'memory', 'resource', 'scope' and 'value'. 2312 | */ 2313 | val kinds: List? = null, 2314 | 2315 | /** 2316 | * The code location. 2317 | */ 2318 | val location: Location? = null, 2319 | 2320 | /** 2321 | * The name of the module that contains the code that is executing. 2322 | */ 2323 | val module: String? = null, 2324 | 2325 | /** 2326 | * An integer representing a containment hierarchy within the thread flow. 2327 | */ 2328 | val nestingLevel: Long? = null, 2329 | 2330 | /** 2331 | * Key/value pairs that provide additional information about the threadflow location. 2332 | */ 2333 | val properties: PropertyBag? = null, 2334 | 2335 | /** 2336 | * The call stack leading to this location. 2337 | */ 2338 | val stack: Stack? = null, 2339 | 2340 | /** 2341 | * A dictionary, each of whose keys specifies a variable or expression, the associated value 2342 | * of which represents the variable or expression value. For an annotation of kind 2343 | * 'continuation', for example, this dictionary might hold the current assumed values of a 2344 | * set of global variables. 2345 | */ 2346 | val state: Map? = null, 2347 | 2348 | /** 2349 | * An array of references to rule or taxonomy reporting descriptors that are applicable to 2350 | * the thread flow location. 2351 | */ 2352 | val taxa: List? = null, 2353 | 2354 | /** 2355 | * A web request associated with this thread flow location. 2356 | */ 2357 | val webRequest: WebRequest? = null, 2358 | 2359 | /** 2360 | * A web response associated with this thread flow location. 2361 | */ 2362 | val webResponse: WebResponse? = null 2363 | ) 2364 | 2365 | /** 2366 | * Specifies the importance of this location in understanding the code flow in which it 2367 | * occurs. The order from most to least important is "essential", "important", 2368 | * "unimportant". Default: "important". 2369 | */ 2370 | @Serializable(with = Importance.Companion::class) 2371 | public enum class Importance( 2372 | public val value: String, 2373 | ) { 2374 | Essential("essential"), 2375 | Important("important"), 2376 | Unimportant("unimportant"); 2377 | 2378 | public companion object : KSerializer { 2379 | override val descriptor: SerialDescriptor get() { 2380 | return PrimitiveSerialDescriptor("quicktype.Importance", PrimitiveKind.STRING) 2381 | } 2382 | override fun deserialize(decoder: Decoder): Importance = when (val value = decoder.decodeString()) { 2383 | "essential" -> Essential 2384 | "important" -> Important 2385 | "unimportant" -> Unimportant 2386 | else -> throw IllegalArgumentException("Importance could not parse: $value") 2387 | } 2388 | override fun serialize(encoder: Encoder, value: Importance) { 2389 | return encoder.encodeString(value.value) 2390 | } 2391 | } 2392 | } 2393 | 2394 | /** 2395 | * A web request associated with this thread flow location. 2396 | * 2397 | * Describes an HTTP request. 2398 | * 2399 | * A web request associated with this result. 2400 | */ 2401 | @Serializable 2402 | public data class WebRequest ( 2403 | /** 2404 | * The body of the request. 2405 | */ 2406 | val body: ArtifactContent? = null, 2407 | 2408 | /** 2409 | * The request headers. 2410 | */ 2411 | val headers: Map? = null, 2412 | 2413 | /** 2414 | * The index within the run.webRequests array of the request object associated with this 2415 | * result. 2416 | */ 2417 | val index: Long? = null, 2418 | 2419 | /** 2420 | * The HTTP method. Well-known values are 'GET', 'PUT', 'POST', 'DELETE', 'PATCH', 'HEAD', 2421 | * 'OPTIONS', 'TRACE', 'CONNECT'. 2422 | */ 2423 | val method: String? = null, 2424 | 2425 | /** 2426 | * The request parameters. 2427 | */ 2428 | val parameters: Map? = null, 2429 | 2430 | /** 2431 | * Key/value pairs that provide additional information about the request. 2432 | */ 2433 | val properties: PropertyBag? = null, 2434 | 2435 | /** 2436 | * The request protocol. Example: 'http'. 2437 | */ 2438 | val protocol: String? = null, 2439 | 2440 | /** 2441 | * The target of the request. 2442 | */ 2443 | val target: String? = null, 2444 | 2445 | /** 2446 | * The request version. Example: '1.1'. 2447 | */ 2448 | val version: String? = null 2449 | ) 2450 | 2451 | /** 2452 | * A web response associated with this thread flow location. 2453 | * 2454 | * Describes the response to an HTTP request. 2455 | * 2456 | * A web response associated with this result. 2457 | */ 2458 | @Serializable 2459 | public data class WebResponse ( 2460 | /** 2461 | * The body of the response. 2462 | */ 2463 | val body: ArtifactContent? = null, 2464 | 2465 | /** 2466 | * The response headers. 2467 | */ 2468 | val headers: Map? = null, 2469 | 2470 | /** 2471 | * The index within the run.webResponses array of the response object associated with this 2472 | * result. 2473 | */ 2474 | val index: Long? = null, 2475 | 2476 | /** 2477 | * Specifies whether a response was received from the server. 2478 | */ 2479 | val noResponseReceived: Boolean? = null, 2480 | 2481 | /** 2482 | * Key/value pairs that provide additional information about the response. 2483 | */ 2484 | val properties: PropertyBag? = null, 2485 | 2486 | /** 2487 | * The response protocol. Example: 'http'. 2488 | */ 2489 | val protocol: String? = null, 2490 | 2491 | /** 2492 | * The response reason. Example: 'Not found'. 2493 | */ 2494 | val reasonPhrase: String? = null, 2495 | 2496 | /** 2497 | * The response status code. Example: 451. 2498 | */ 2499 | val statusCode: Long? = null, 2500 | 2501 | /** 2502 | * The response version. Example: '1.1'. 2503 | */ 2504 | val version: String? = null 2505 | ) 2506 | 2507 | /** 2508 | * A proposed fix for the problem represented by a result object. A fix specifies a set of 2509 | * artifacts to modify. For each artifact, it specifies a set of bytes to remove, and 2510 | * provides a set of new bytes to replace them. 2511 | */ 2512 | @Serializable 2513 | public data class Fix ( 2514 | /** 2515 | * One or more artifact changes that comprise a fix for a result. 2516 | */ 2517 | val artifactChanges: List, 2518 | 2519 | /** 2520 | * A message that describes the proposed fix, enabling viewers to present the proposed 2521 | * change to an end user. 2522 | */ 2523 | val description: Message? = null, 2524 | 2525 | /** 2526 | * Key/value pairs that provide additional information about the fix. 2527 | */ 2528 | val properties: PropertyBag? = null 2529 | ) 2530 | 2531 | /** 2532 | * A change to a single artifact. 2533 | */ 2534 | @Serializable 2535 | public data class ArtifactChange ( 2536 | /** 2537 | * The location of the artifact to change. 2538 | */ 2539 | val artifactLocation: ArtifactLocation, 2540 | 2541 | /** 2542 | * Key/value pairs that provide additional information about the change. 2543 | */ 2544 | val properties: PropertyBag? = null, 2545 | 2546 | /** 2547 | * An array of replacement objects, each of which represents the replacement of a single 2548 | * region in a single artifact specified by 'artifactLocation'. 2549 | */ 2550 | val replacements: List 2551 | ) 2552 | 2553 | /** 2554 | * The replacement of a single region of an artifact. 2555 | */ 2556 | @Serializable 2557 | public data class Replacement ( 2558 | /** 2559 | * The region of the artifact to delete. 2560 | */ 2561 | val deletedRegion: Region, 2562 | 2563 | /** 2564 | * The content to insert at the location specified by the 'deletedRegion' property. 2565 | */ 2566 | val insertedContent: ArtifactContent? = null, 2567 | 2568 | /** 2569 | * Key/value pairs that provide additional information about the replacement. 2570 | */ 2571 | val properties: PropertyBag? = null 2572 | ) 2573 | 2574 | /** 2575 | * Represents a path through a graph. 2576 | */ 2577 | @Serializable 2578 | public data class GraphTraversal ( 2579 | /** 2580 | * A description of this graph traversal. 2581 | */ 2582 | val description: Message? = null, 2583 | 2584 | /** 2585 | * The sequences of edges traversed by this graph traversal. 2586 | */ 2587 | val edgeTraversals: List? = null, 2588 | 2589 | /** 2590 | * Values of relevant expressions at the start of the graph traversal that remain constant 2591 | * for the graph traversal. 2592 | */ 2593 | val immutableState: Map? = null, 2594 | 2595 | /** 2596 | * Values of relevant expressions at the start of the graph traversal that may change during 2597 | * graph traversal. 2598 | */ 2599 | val initialState: Map? = null, 2600 | 2601 | /** 2602 | * Key/value pairs that provide additional information about the graph traversal. 2603 | */ 2604 | val properties: PropertyBag? = null, 2605 | 2606 | /** 2607 | * The index within the result.graphs to be associated with the result. 2608 | */ 2609 | val resultGraphIndex: Long? = null, 2610 | 2611 | /** 2612 | * The index within the run.graphs to be associated with the result. 2613 | */ 2614 | val runGraphIndex: Long? = null 2615 | ) 2616 | 2617 | /** 2618 | * Represents the traversal of a single edge during a graph traversal. 2619 | */ 2620 | @Serializable 2621 | public data class EdgeTraversal ( 2622 | /** 2623 | * Identifies the edge being traversed. 2624 | */ 2625 | @SerialName("edgeId") 2626 | val edgeID: String, 2627 | 2628 | /** 2629 | * The values of relevant expressions after the edge has been traversed. 2630 | */ 2631 | val finalState: Map? = null, 2632 | 2633 | /** 2634 | * A message to display to the user as the edge is traversed. 2635 | */ 2636 | val message: Message? = null, 2637 | 2638 | /** 2639 | * Key/value pairs that provide additional information about the edge traversal. 2640 | */ 2641 | val properties: PropertyBag? = null, 2642 | 2643 | /** 2644 | * The number of edge traversals necessary to return from a nested graph. 2645 | */ 2646 | val stepOverEdgeCount: Long? = null 2647 | ) 2648 | 2649 | /** 2650 | * A value that categorizes results by evaluation state. 2651 | */ 2652 | @Serializable(with = ResultKind.Companion::class) 2653 | public enum class ResultKind( 2654 | public val value: String, 2655 | ) { 2656 | Fail("fail"), 2657 | Informational("informational"), 2658 | NotApplicable("notApplicable"), 2659 | Open("open"), 2660 | Pass("pass"), 2661 | Review("review"); 2662 | 2663 | public companion object : KSerializer { 2664 | override val descriptor: SerialDescriptor get() { 2665 | return PrimitiveSerialDescriptor("quicktype.ResultKind", PrimitiveKind.STRING) 2666 | } 2667 | override fun deserialize(decoder: Decoder): ResultKind = when (val value = decoder.decodeString()) { 2668 | "fail" -> Fail 2669 | "informational" -> Informational 2670 | "notApplicable" -> NotApplicable 2671 | "open" -> Open 2672 | "pass" -> Pass 2673 | "review" -> Review 2674 | else -> throw IllegalArgumentException("ResultKind could not parse: $value") 2675 | } 2676 | override fun serialize(encoder: Encoder, value: ResultKind) { 2677 | return encoder.encodeString(value.value) 2678 | } 2679 | } 2680 | } 2681 | 2682 | /** 2683 | * Information about how and when the result was detected. 2684 | * 2685 | * Contains information about how and when a result was detected. 2686 | */ 2687 | @Serializable 2688 | public data class ResultProvenance ( 2689 | /** 2690 | * An array of physicalLocation objects which specify the portions of an analysis tool's 2691 | * output that a converter transformed into the result. 2692 | */ 2693 | val conversionSources: List? = null, 2694 | 2695 | /** 2696 | * A GUID-valued string equal to the automationDetails.guid property of the run in which the 2697 | * result was first detected. 2698 | */ 2699 | @SerialName("firstDetectionRunGuid") 2700 | val firstDetectionRunGUID: String? = null, 2701 | 2702 | /** 2703 | * The Coordinated Universal Time (UTC) date and time at which the result was first 2704 | * detected. See "Date/time properties" in the SARIF spec for the required format. 2705 | */ 2706 | @SerialName("firstDetectionTimeUtc") 2707 | val firstDetectionTimeUTC: String? = null, 2708 | 2709 | /** 2710 | * The index within the run.invocations array of the invocation object which describes the 2711 | * tool invocation that detected the result. 2712 | */ 2713 | val invocationIndex: Long? = null, 2714 | 2715 | /** 2716 | * A GUID-valued string equal to the automationDetails.guid property of the run in which the 2717 | * result was most recently detected. 2718 | */ 2719 | @SerialName("lastDetectionRunGuid") 2720 | val lastDetectionRunGUID: String? = null, 2721 | 2722 | /** 2723 | * The Coordinated Universal Time (UTC) date and time at which the result was most recently 2724 | * detected. See "Date/time properties" in the SARIF spec for the required format. 2725 | */ 2726 | @SerialName("lastDetectionTimeUtc") 2727 | val lastDetectionTimeUTC: String? = null, 2728 | 2729 | /** 2730 | * Key/value pairs that provide additional information about the result. 2731 | */ 2732 | val properties: PropertyBag? = null 2733 | ) 2734 | 2735 | /** 2736 | * A suppression that is relevant to a result. 2737 | */ 2738 | @Serializable 2739 | public data class Suppression ( 2740 | /** 2741 | * A stable, unique identifier for the suprression in the form of a GUID. 2742 | */ 2743 | val guid: String? = null, 2744 | 2745 | /** 2746 | * A string representing the justification for the suppression. 2747 | */ 2748 | val justification: String? = null, 2749 | 2750 | /** 2751 | * A string that indicates where the suppression is persisted. 2752 | */ 2753 | val kind: SuppressionKind, 2754 | 2755 | /** 2756 | * Identifies the location associated with the suppression. 2757 | */ 2758 | val location: Location? = null, 2759 | 2760 | /** 2761 | * Key/value pairs that provide additional information about the suppression. 2762 | */ 2763 | val properties: PropertyBag? = null, 2764 | 2765 | /** 2766 | * A string that indicates the review status of the suppression. 2767 | */ 2768 | val status: Status? = null 2769 | ) 2770 | 2771 | /** 2772 | * A string that indicates where the suppression is persisted. 2773 | */ 2774 | @Serializable(with = SuppressionKind.Companion::class) 2775 | public enum class SuppressionKind( 2776 | public val value: String, 2777 | ) { 2778 | External("external"), 2779 | InSource("inSource"); 2780 | 2781 | public companion object : KSerializer { 2782 | override val descriptor: SerialDescriptor get() { 2783 | return PrimitiveSerialDescriptor("quicktype.SuppressionKind", PrimitiveKind.STRING) 2784 | } 2785 | override fun deserialize(decoder: Decoder): SuppressionKind = when (val value = decoder.decodeString()) { 2786 | "external" -> External 2787 | "inSource" -> InSource 2788 | else -> throw IllegalArgumentException("SuppressionKind could not parse: $value") 2789 | } 2790 | override fun serialize(encoder: Encoder, value: SuppressionKind) { 2791 | return encoder.encodeString(value.value) 2792 | } 2793 | } 2794 | } 2795 | 2796 | /** 2797 | * A string that indicates the review status of the suppression. 2798 | */ 2799 | @Serializable(with = Status.Companion::class) 2800 | public enum class Status( 2801 | public val value: String, 2802 | ) { 2803 | Accepted("accepted"), 2804 | Rejected("rejected"), 2805 | UnderReview("underReview"); 2806 | 2807 | public companion object : KSerializer { 2808 | override val descriptor: SerialDescriptor get() { 2809 | return PrimitiveSerialDescriptor("quicktype.Status", PrimitiveKind.STRING) 2810 | } 2811 | override fun deserialize(decoder: Decoder): Status = when (val value = decoder.decodeString()) { 2812 | "accepted" -> Accepted 2813 | "rejected" -> Rejected 2814 | "underReview" -> UnderReview 2815 | else -> throw IllegalArgumentException("Status could not parse: $value") 2816 | } 2817 | override fun serialize(encoder: Encoder, value: Status) { 2818 | return encoder.encodeString(value.value) 2819 | } 2820 | } 2821 | } 2822 | 2823 | /** 2824 | * The SARIF format version of this external properties object. 2825 | * 2826 | * The SARIF format version of this log file. 2827 | */ 2828 | @Serializable(with = Version.Companion::class) 2829 | public enum class Version( 2830 | public val value: String, 2831 | ) { 2832 | The210("2.1.0"); 2833 | 2834 | public companion object : KSerializer { 2835 | override val descriptor: SerialDescriptor get() { 2836 | return PrimitiveSerialDescriptor("quicktype.Version", PrimitiveKind.STRING) 2837 | } 2838 | override fun deserialize(decoder: Decoder): Version = when (val value = decoder.decodeString()) { 2839 | "2.1.0" -> The210 2840 | else -> throw IllegalArgumentException("Version could not parse: $value") 2841 | } 2842 | override fun serialize(encoder: Encoder, value: Version) { 2843 | return encoder.encodeString(value.value) 2844 | } 2845 | } 2846 | } 2847 | 2848 | /** 2849 | * Describes a single run of an analysis tool, and contains the reported output of that run. 2850 | */ 2851 | @Serializable 2852 | public data class Run ( 2853 | /** 2854 | * Addresses associated with this run instance, if any. 2855 | */ 2856 | val addresses: List
? = null, 2857 | 2858 | /** 2859 | * An array of artifact objects relevant to the run. 2860 | */ 2861 | val artifacts: List? = null, 2862 | 2863 | /** 2864 | * Automation details that describe this run. 2865 | */ 2866 | val automationDetails: RunAutomationDetails? = null, 2867 | 2868 | /** 2869 | * The 'guid' property of a previous SARIF 'run' that comprises the baseline that was used 2870 | * to compute result 'baselineState' properties for the run. 2871 | */ 2872 | @SerialName("baselineGuid") 2873 | val baselineGUID: String? = null, 2874 | 2875 | /** 2876 | * Specifies the unit in which the tool measures columns. 2877 | */ 2878 | val columnKind: ColumnKind? = null, 2879 | 2880 | /** 2881 | * A conversion object that describes how a converter transformed an analysis tool's native 2882 | * reporting format into the SARIF format. 2883 | */ 2884 | val conversion: Conversion? = null, 2885 | 2886 | /** 2887 | * Specifies the default encoding for any artifact object that refers to a text file. 2888 | */ 2889 | val defaultEncoding: String? = null, 2890 | 2891 | /** 2892 | * Specifies the default source language for any artifact object that refers to a text file 2893 | * that contains source code. 2894 | */ 2895 | val defaultSourceLanguage: String? = null, 2896 | 2897 | /** 2898 | * References to external property files that should be inlined with the content of a root 2899 | * log file. 2900 | */ 2901 | val externalPropertyFileReferences: ExternalPropertyFileReferences? = null, 2902 | 2903 | /** 2904 | * An array of zero or more unique graph objects associated with the run. 2905 | */ 2906 | val graphs: List? = null, 2907 | 2908 | /** 2909 | * Describes the invocation of the analysis tool. 2910 | */ 2911 | val invocations: List? = null, 2912 | 2913 | /** 2914 | * The language of the messages emitted into the log file during this run (expressed as an 2915 | * ISO 639-1 two-letter lowercase culture code) and an optional region (expressed as an ISO 2916 | * 3166-1 two-letter uppercase subculture code associated with a country or region). The 2917 | * casing is recommended but not required (in order for this data to conform to RFC5646). 2918 | */ 2919 | val language: String? = null, 2920 | 2921 | /** 2922 | * An array of logical locations such as namespaces, types or functions. 2923 | */ 2924 | val logicalLocations: List? = null, 2925 | 2926 | /** 2927 | * An ordered list of character sequences that were treated as line breaks when computing 2928 | * region information for the run. 2929 | */ 2930 | val newlineSequences: List? = null, 2931 | 2932 | /** 2933 | * The artifact location specified by each uriBaseId symbol on the machine where the tool 2934 | * originally ran. 2935 | */ 2936 | @SerialName("originalUriBaseIds") 2937 | val originalURIBaseIDS: Map? = null, 2938 | 2939 | /** 2940 | * Contains configurations that may potentially override both 2941 | * reportingDescriptor.defaultConfiguration (the tool's default severities) and 2942 | * invocation.configurationOverrides (severities established at run-time from the command 2943 | * line). 2944 | */ 2945 | val policies: List? = null, 2946 | 2947 | /** 2948 | * Key/value pairs that provide additional information about the run. 2949 | */ 2950 | val properties: PropertyBag? = null, 2951 | 2952 | /** 2953 | * An array of strings used to replace sensitive information in a redaction-aware property. 2954 | */ 2955 | val redactionTokens: List? = null, 2956 | 2957 | /** 2958 | * The set of results contained in an SARIF log. The results array can be omitted when a run 2959 | * is solely exporting rules metadata. It must be present (but may be empty) if a log file 2960 | * represents an actual scan. 2961 | */ 2962 | val results: List? = null, 2963 | 2964 | /** 2965 | * Automation details that describe the aggregate of runs to which this run belongs. 2966 | */ 2967 | val runAggregates: List? = null, 2968 | 2969 | /** 2970 | * A specialLocations object that defines locations of special significance to SARIF 2971 | * consumers. 2972 | */ 2973 | val specialLocations: SpecialLocations? = null, 2974 | 2975 | /** 2976 | * An array of toolComponent objects relevant to a taxonomy in which results are categorized. 2977 | */ 2978 | val taxonomies: List? = null, 2979 | 2980 | /** 2981 | * An array of threadFlowLocation objects cached at run level. 2982 | */ 2983 | val threadFlowLocations: List? = null, 2984 | 2985 | /** 2986 | * Information about the tool or tool pipeline that generated the results in this run. A run 2987 | * can only contain results produced by a single tool or tool pipeline. A run can aggregate 2988 | * results from multiple log files, as long as context around the tool run (tool 2989 | * command-line arguments and the like) is identical for all aggregated files. 2990 | */ 2991 | val tool: Tool, 2992 | 2993 | /** 2994 | * The set of available translations of the localized data provided by the tool. 2995 | */ 2996 | val translations: List? = null, 2997 | 2998 | /** 2999 | * Specifies the revision in version control of the artifacts that were scanned. 3000 | */ 3001 | val versionControlProvenance: List? = null, 3002 | 3003 | /** 3004 | * An array of request objects cached at run level. 3005 | */ 3006 | val webRequests: List? = null, 3007 | 3008 | /** 3009 | * An array of response objects cached at run level. 3010 | */ 3011 | val webResponses: List? = null 3012 | ) 3013 | 3014 | /** 3015 | * Automation details that describe this run. 3016 | * 3017 | * Information that describes a run's identity and role within an engineering system process. 3018 | */ 3019 | @Serializable 3020 | public data class RunAutomationDetails ( 3021 | /** 3022 | * A stable, unique identifier for the equivalence class of runs to which this object's 3023 | * containing run object belongs in the form of a GUID. 3024 | */ 3025 | @SerialName("correlationGuid") 3026 | val correlationGUID: String? = null, 3027 | 3028 | /** 3029 | * A description of the identity and role played within the engineering system by this 3030 | * object's containing run object. 3031 | */ 3032 | val description: Message? = null, 3033 | 3034 | /** 3035 | * A stable, unique identifier for this object's containing run object in the form of a GUID. 3036 | */ 3037 | val guid: String? = null, 3038 | 3039 | /** 3040 | * A hierarchical string that uniquely identifies this object's containing run object. 3041 | */ 3042 | val id: String? = null, 3043 | 3044 | /** 3045 | * Key/value pairs that provide additional information about the run automation details. 3046 | */ 3047 | val properties: PropertyBag? = null 3048 | ) 3049 | 3050 | /** 3051 | * Specifies the unit in which the tool measures columns. 3052 | */ 3053 | @Serializable(with = ColumnKind.Companion::class) 3054 | public enum class ColumnKind( 3055 | public val value: String, 3056 | ) { 3057 | UnicodeCodePoints("unicodeCodePoints"), 3058 | Utf16CodeUnits("utf16CodeUnits"); 3059 | 3060 | public companion object : KSerializer { 3061 | override val descriptor: SerialDescriptor get() { 3062 | return PrimitiveSerialDescriptor("quicktype.ColumnKind", PrimitiveKind.STRING) 3063 | } 3064 | override fun deserialize(decoder: Decoder): ColumnKind = when (val value = decoder.decodeString()) { 3065 | "unicodeCodePoints" -> UnicodeCodePoints 3066 | "utf16CodeUnits" -> Utf16CodeUnits 3067 | else -> throw IllegalArgumentException("ColumnKind could not parse: $value") 3068 | } 3069 | override fun serialize(encoder: Encoder, value: ColumnKind) { 3070 | return encoder.encodeString(value.value) 3071 | } 3072 | } 3073 | } 3074 | 3075 | /** 3076 | * References to external property files that should be inlined with the content of a root 3077 | * log file. 3078 | */ 3079 | @Serializable 3080 | public data class ExternalPropertyFileReferences ( 3081 | /** 3082 | * An array of external property files containing run.addresses arrays to be merged with the 3083 | * root log file. 3084 | */ 3085 | val addresses: List? = null, 3086 | 3087 | /** 3088 | * An array of external property files containing run.artifacts arrays to be merged with the 3089 | * root log file. 3090 | */ 3091 | val artifacts: List? = null, 3092 | 3093 | /** 3094 | * An external property file containing a run.conversion object to be merged with the root 3095 | * log file. 3096 | */ 3097 | val conversion: ExternalPropertyFileReference? = null, 3098 | 3099 | /** 3100 | * An external property file containing a run.driver object to be merged with the root log 3101 | * file. 3102 | */ 3103 | val driver: ExternalPropertyFileReference? = null, 3104 | 3105 | /** 3106 | * An array of external property files containing run.extensions arrays to be merged with 3107 | * the root log file. 3108 | */ 3109 | val extensions: List? = null, 3110 | 3111 | /** 3112 | * An external property file containing a run.properties object to be merged with the root 3113 | * log file. 3114 | */ 3115 | val externalizedProperties: ExternalPropertyFileReference? = null, 3116 | 3117 | /** 3118 | * An array of external property files containing a run.graphs object to be merged with the 3119 | * root log file. 3120 | */ 3121 | val graphs: List? = null, 3122 | 3123 | /** 3124 | * An array of external property files containing run.invocations arrays to be merged with 3125 | * the root log file. 3126 | */ 3127 | val invocations: List? = null, 3128 | 3129 | /** 3130 | * An array of external property files containing run.logicalLocations arrays to be merged 3131 | * with the root log file. 3132 | */ 3133 | val logicalLocations: List? = null, 3134 | 3135 | /** 3136 | * An array of external property files containing run.policies arrays to be merged with the 3137 | * root log file. 3138 | */ 3139 | val policies: List? = null, 3140 | 3141 | /** 3142 | * Key/value pairs that provide additional information about the external property files. 3143 | */ 3144 | val properties: PropertyBag? = null, 3145 | 3146 | /** 3147 | * An array of external property files containing run.results arrays to be merged with the 3148 | * root log file. 3149 | */ 3150 | val results: List? = null, 3151 | 3152 | /** 3153 | * An array of external property files containing run.taxonomies arrays to be merged with 3154 | * the root log file. 3155 | */ 3156 | val taxonomies: List? = null, 3157 | 3158 | /** 3159 | * An array of external property files containing run.threadFlowLocations arrays to be 3160 | * merged with the root log file. 3161 | */ 3162 | val threadFlowLocations: List? = null, 3163 | 3164 | /** 3165 | * An array of external property files containing run.translations arrays to be merged with 3166 | * the root log file. 3167 | */ 3168 | val translations: List? = null, 3169 | 3170 | /** 3171 | * An array of external property files containing run.requests arrays to be merged with the 3172 | * root log file. 3173 | */ 3174 | val webRequests: List? = null, 3175 | 3176 | /** 3177 | * An array of external property files containing run.responses arrays to be merged with the 3178 | * root log file. 3179 | */ 3180 | val webResponses: List? = null 3181 | ) 3182 | 3183 | /** 3184 | * An external property file containing a run.conversion object to be merged with the root 3185 | * log file. 3186 | * 3187 | * An external property file containing a run.driver object to be merged with the root log 3188 | * file. 3189 | * 3190 | * An external property file containing a run.properties object to be merged with the root 3191 | * log file. 3192 | * 3193 | * Contains information that enables a SARIF consumer to locate the external property file 3194 | * that contains the value of an externalized property associated with the run. 3195 | */ 3196 | @Serializable 3197 | public data class ExternalPropertyFileReference ( 3198 | /** 3199 | * A stable, unique identifier for the external property file in the form of a GUID. 3200 | */ 3201 | val guid: String? = null, 3202 | 3203 | /** 3204 | * A non-negative integer specifying the number of items contained in the external property 3205 | * file. 3206 | */ 3207 | val itemCount: Long? = null, 3208 | 3209 | /** 3210 | * The location of the external property file. 3211 | */ 3212 | val location: ArtifactLocation? = null, 3213 | 3214 | /** 3215 | * Key/value pairs that provide additional information about the external property file. 3216 | */ 3217 | val properties: PropertyBag? = null 3218 | ) 3219 | 3220 | /** 3221 | * A specialLocations object that defines locations of special significance to SARIF 3222 | * consumers. 3223 | * 3224 | * Defines locations of special significance to SARIF consumers. 3225 | */ 3226 | @Serializable 3227 | public data class SpecialLocations ( 3228 | /** 3229 | * Provides a suggestion to SARIF consumers to display file paths relative to the specified 3230 | * location. 3231 | */ 3232 | val displayBase: ArtifactLocation? = null, 3233 | 3234 | /** 3235 | * Key/value pairs that provide additional information about the special locations. 3236 | */ 3237 | val properties: PropertyBag? = null 3238 | ) 3239 | 3240 | /** 3241 | * Specifies the information necessary to retrieve a desired revision from a version control 3242 | * system. 3243 | */ 3244 | @Serializable 3245 | public data class VersionControlDetails ( 3246 | /** 3247 | * A Coordinated Universal Time (UTC) date and time that can be used to synchronize an 3248 | * enlistment to the state of the repository at that time. 3249 | */ 3250 | @SerialName("asOfTimeUtc") 3251 | val asOfTimeUTC: String? = null, 3252 | 3253 | /** 3254 | * The name of a branch containing the revision. 3255 | */ 3256 | val branch: String? = null, 3257 | 3258 | /** 3259 | * The location in the local file system to which the root of the repository was mapped at 3260 | * the time of the analysis. 3261 | */ 3262 | val mappedTo: ArtifactLocation? = null, 3263 | 3264 | /** 3265 | * Key/value pairs that provide additional information about the version control details. 3266 | */ 3267 | val properties: PropertyBag? = null, 3268 | 3269 | /** 3270 | * The absolute URI of the repository. 3271 | */ 3272 | @SerialName("repositoryUri") 3273 | val repositoryURI: String, 3274 | 3275 | /** 3276 | * A string that uniquely and permanently identifies the revision within the repository. 3277 | */ 3278 | @SerialName("revisionId") 3279 | val revisionID: String? = null, 3280 | 3281 | /** 3282 | * A tag that has been applied to the revision. 3283 | */ 3284 | val revisionTag: String? = null 3285 | ) 3286 | --------------------------------------------------------------------------------