Skip to content

Commit

Permalink
Use sane fallbacks when reading empty files
Browse files Browse the repository at this point in the history
Fixes #3861.

Signed-off-by: Sebastian Schuberth <[email protected]>
  • Loading branch information
sschuberth committed Apr 9, 2021
1 parent f13d589 commit 54b6bb6
Show file tree
Hide file tree
Showing 49 changed files with 237 additions and 150 deletions.
12 changes: 10 additions & 2 deletions advisor/src/main/kotlin/Advisor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,16 @@ class Advisor(
"Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms."
}

requireNotNull(ortResult.analyzer) {
"The provided ORT result file '${ortFile.canonicalPath}' does not contain an analyzer result."
requireNotNull(ortResult) {
"The provided ORT result file '${ortFile.canonicalPath}' has no content."
}

if (ortResult.analyzer == null) {
log.warn {
"The provided ORT result file '${ortFile.canonicalPath}' does not contain an analyzer result."
}

return ortResult
}

val providers = providerFactories.map { it.create(config) }
Expand Down
9 changes: 6 additions & 3 deletions advisor/src/test/kotlin/advisors/VulnerableCodeTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ class VulnerableCodeTest : WordSpec({
stubVulnerability("v3", "CVE-2019-CoV19", 77.0f)

val vulnerableCode = createVulnerableCode(wiremock)
val packagesToAdvise = resultFile().readValue<OrtResult>().getPackages(false).map { it.pkg }
val ortResult = resultFile().readValue<OrtResult>()
val packagesToAdvise = ortResult?.getPackages(false)?.map { it.pkg }.orEmpty()

val result = vulnerableCode.retrievePackageVulnerabilities(packagesToAdvise).mapKeys { it.key.id }

Expand Down Expand Up @@ -145,7 +146,8 @@ class VulnerableCodeTest : WordSpec({
)

val vulnerableCode = createVulnerableCode(wiremock)
val packagesToAdvise = resultFile().readValue<OrtResult>().getPackages(false).map { it.pkg }
val ortResult = resultFile().readValue<OrtResult>()
val packagesToAdvise = ortResult?.getPackages(false)?.map { it.pkg }.orEmpty()

vulnerableCode.retrievePackageVulnerabilities(packagesToAdvise).mapKeys { it.key.id } shouldNotBeNull {
val strutsResults = getValue(idStruts)
Expand Down Expand Up @@ -235,7 +237,8 @@ private val vulnerabilityDetailsTemplate = File(TEST_FILES_ROOT).resolve(VULNERA
*/
private fun expectErrorResult(wiremock: WireMockServer) {
val vulnerableCode = createVulnerableCode(wiremock)
val packagesToAdvise = resultFile().readValue<OrtResult>().getPackages(false).map { it.pkg }
val ortResult = resultFile().readValue<OrtResult>()
val packagesToAdvise = ortResult?.getPackages(false)?.map { it.pkg }.orEmpty()

val result = runBlocking {
vulnerableCode.retrievePackageVulnerabilities(packagesToAdvise).mapKeys { it.key.id }
Expand Down
2 changes: 1 addition & 1 deletion analyzer/src/main/kotlin/Analyzer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class Analyzer(private val config: AnalyzerConfiguration) {
val repositoryConfiguration = if (actualRepositoryConfigurationFile.isFile) {
log.info { "Using configuration file '${actualRepositoryConfigurationFile.absolutePath}'." }

actualRepositoryConfigurationFile.readValue()
actualRepositoryConfigurationFile.readValue() ?: RepositoryConfiguration()
} else {
RepositoryConfiguration()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import org.ossreviewtoolkit.model.readValue
*/
class FilePackageCurationProvider(curationFile: File) : PackageCurationProvider {
internal val packageCurations: List<PackageCuration> by lazy {
curationFile.readValue<List<PackageCuration>>()
curationFile.readValue<List<PackageCuration>>().orEmpty()
}

override fun getCurationsFor(pkgId: Identifier) = packageCurations.filter { it.isApplicable(pkgId) }
Expand Down
2 changes: 1 addition & 1 deletion analyzer/src/main/kotlin/managers/Npm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ open class Npm(

log.debug { "Found a 'package.json' file in '$packageDir'." }

val json = it.readValue<ObjectNode>()
val json = it.readValue<ObjectNode>() ?: return@forEach
val rawName = json["name"].textValue()
val (namespace, name) = splitNamespaceAndName(rawName)
val version = json["version"].textValue()
Expand Down
7 changes: 3 additions & 4 deletions analyzer/src/main/kotlin/managers/utils/NodeSupport.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@ package org.ossreviewtoolkit.analyzer.managers.utils

import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.node.ArrayNode
import com.fasterxml.jackson.databind.node.ObjectNode

import java.io.File
import java.nio.file.FileSystems
import java.nio.file.PathMatcher

import org.ossreviewtoolkit.model.readValue
import org.ossreviewtoolkit.model.readJsonFile
import org.ossreviewtoolkit.utils.AuthenticatedProxy
import org.ossreviewtoolkit.utils.ProtocolProxyMap
import org.ossreviewtoolkit.utils.collectMessagesAsString
Expand Down Expand Up @@ -176,7 +175,7 @@ private fun getPackageJsonInfo(definitionFiles: Set<File>): Collection<PackageJs

private fun isYarnWorkspaceRoot(definitionFile: File) =
try {
definitionFile.readValue<ObjectNode>()["workspaces"] != null
readJsonFile(definitionFile).has("workspaces")
} catch (e: JsonProcessingException) {
e.showStackTrace()

Expand Down Expand Up @@ -211,7 +210,7 @@ private fun getYarnWorkspaceSubmodules(definitionFiles: Set<File>): Set<File> {

private fun getWorkspaceMatchers(definitionFile: File): List<PathMatcher> {
var workspaces = try {
definitionFile.readValue<ObjectNode>()["workspaces"]
readJsonFile(definitionFile).get("workspaces")
} catch (e: JsonProcessingException) {
e.showStackTrace()

Expand Down
29 changes: 15 additions & 14 deletions cli/src/funTest/kotlin/ExamplesFunTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ class ExamplesFunTest : StringSpec() {

"license-classifications.yml can be deserialized" {
shouldNotThrow<IOException> {
val classifications =
takeExampleFile("license-classifications.yml").readValue<LicenseClassifications>()
val classifications = takeExampleFile("license-classifications.yml").readValue()
?: LicenseClassifications()

classifications.categories.filter { it.description.isNotEmpty() } shouldNot beEmpty()
classifications.categoryNames shouldContain "public-domain"
Expand Down Expand Up @@ -130,19 +130,20 @@ class ExamplesFunTest : StringSpec() {
val resultFile = File("src/funTest/assets/semver4j-analyzer-result.yml")
val licenseFile = File("../examples/license-classifications.yml")
val ortResult = resultFile.readValue<OrtResult>()
val evaluator = Evaluator(
ortResult = ortResult,
licenseInfoResolver = ortResult.createLicenseInfoResolver(),
licenseClassifications = licenseFile.readValue()
)

val script = takeExampleFile("rules.kts").readText()

val result = evaluator.run(script)

result.violations shouldHaveSize 2
val failedRules = result.violations.map { it.rule }
failedRules shouldContainExactlyInAnyOrder listOf("UNHANDLED_LICENSE", "COPYLEFT_LIMITED_IN_SOURCE")
ortResult shouldNotBeNull {
val evaluator = Evaluator(
ortResult = this,
licenseInfoResolver = createLicenseInfoResolver(),
licenseClassifications = licenseFile.readValue() ?: LicenseClassifications()
)
val script = takeExampleFile("rules.kts").readText()
val result = evaluator.run(script)

result.violations shouldHaveSize 2
val failedRules = result.violations.map { it.rule }
failedRules shouldContainExactlyInAnyOrder listOf("UNHANDLED_LICENSE", "COPYLEFT_LIMITED_IN_SOURCE")
}
}

"asciidoctor-pdf-theme.yml is a valid asciidoctor-pdf theme" {
Expand Down
16 changes: 13 additions & 3 deletions cli/src/main/kotlin/commands/DownloaderCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,25 @@ class DownloaderCommand : CliktCommand(name = "download", help = "Fetch source c
when (input) {
is FileType -> {
val ortFile = (input as FileType).file
val (analyzerResult, duration) = measureTimedValue { ortFile.readValue<OrtResult>().analyzer?.result }
val (ortResult, duration) = measureTimedValue { ortFile.readValue<OrtResult>() }

log.perf {
"Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in " +
"${duration.inMilliseconds}ms."
}

requireNotNull(analyzerResult) {
"The provided ORT result file '${ortFile.canonicalPath}' does not contain an analyzer result."
requireNotNull(ortResult) {
"The provided ORT result file '${ortFile.canonicalPath}' has no content."
}

val analyzerResult = ortResult.analyzer?.result

if (analyzerResult == null) {
log.warn {
"The provided ORT result file '${ortFile.canonicalPath}' does not contain an analyzer result."
}

throw ProgramResult(0)
}

val packages = mutableListOf<Package>().apply {
Expand Down
10 changes: 6 additions & 4 deletions cli/src/main/kotlin/commands/EvaluatorCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ import org.ossreviewtoolkit.GroupTypes.StringType
import org.ossreviewtoolkit.evaluator.Evaluator
import org.ossreviewtoolkit.model.FileFormat
import org.ossreviewtoolkit.model.OrtResult
import org.ossreviewtoolkit.model.PackageCuration
import org.ossreviewtoolkit.model.Severity
import org.ossreviewtoolkit.model.config.CopyrightGarbage
import org.ossreviewtoolkit.model.config.LicenseFilenamePatterns
import org.ossreviewtoolkit.model.config.RepositoryConfiguration
import org.ossreviewtoolkit.model.config.createFileArchiver
import org.ossreviewtoolkit.model.config.orEmpty
import org.ossreviewtoolkit.model.licenses.DefaultLicenseInfoProvider
Expand Down Expand Up @@ -239,12 +241,12 @@ class EvaluatorCommand : CliktCommand(name = "evaluate", help = "Evaluate ORT re
}
}

repositoryConfigurationFile?.let {
ortResultInput = ortResultInput?.replaceConfig(it.readValue())
repositoryConfigurationFile?.readValue<RepositoryConfiguration>()?.let {
ortResultInput = ortResultInput?.replaceConfig(it)
}

packageCurationsFile?.let {
ortResultInput = ortResultInput?.replacePackageCurations(it.readValue())
packageCurationsFile?.readValue<List<PackageCuration>>()?.let {
ortResultInput = ortResultInput?.replacePackageCurations(it)
}

val finalOrtResult = requireNotNull(ortResultInput) {
Expand Down
11 changes: 8 additions & 3 deletions cli/src/main/kotlin/commands/ReporterCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import org.ossreviewtoolkit.GlobalOptions
import org.ossreviewtoolkit.model.OrtResult
import org.ossreviewtoolkit.model.config.CopyrightGarbage
import org.ossreviewtoolkit.model.config.LicenseFilenamePatterns
import org.ossreviewtoolkit.model.config.RepositoryConfiguration
import org.ossreviewtoolkit.model.config.Resolutions
import org.ossreviewtoolkit.model.config.createFileArchiver
import org.ossreviewtoolkit.model.config.orEmpty
Expand Down Expand Up @@ -200,14 +201,18 @@ class ReporterCommand : CliktCommand(
private val globalOptionsForSubcommands by requireObject<GlobalOptions>()

override fun run() {
var (ortResult, duration) = measureTimedValue { ortFile.readValue<OrtResult>() }
var (originalOrtResult, duration) = measureTimedValue { ortFile.readValue<OrtResult>() }

log.perf {
"Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms."
}

repositoryConfigurationFile?.let {
ortResult = ortResult.replaceConfig(it.readValue())
repositoryConfigurationFile?.readValue<RepositoryConfiguration>()?.let {
originalOrtResult = originalOrtResult?.replaceConfig(it)
}

val ortResult = requireNotNull(originalOrtResult) {
"The provided ORT result file '${ortFile.canonicalPath}' has no content."
}

val resolutionProvider = DefaultResolutionProvider()
Expand Down
2 changes: 1 addition & 1 deletion cli/src/main/kotlin/commands/UploadCurationsCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class UploadCurationsCommand : CliktCommand(
}

override fun run() {
val curations = inputFile.readValue<List<PackageCuration>>()
val curations = inputFile.readValue<List<PackageCuration>>().orEmpty()
val curationsToCoordinates = curations.associateWith { it.id.toClearlyDefinedCoordinates().toString() }
val definitions = service.call { getDefinitions(curationsToCoordinates.values) }

Expand Down
13 changes: 9 additions & 4 deletions cli/src/main/kotlin/commands/UploadResultToPostgresCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ class UploadResultToPostgresCommand : CliktCommand(
epilog = "EXPERIMENTAL: The command is still in development and usage will likely change in the near future. The " +
"command expects that a PostgresStorage for the scanner is configured."
) {
private val ortFile by option(
"--ort-file", "-i",
private val ortResultFile by option(
"--ort-result-file", "-i",
help = "The ORT result file to read as input."
).convert { it.expandTilde() }
.file(mustExist = true, canBeFile = true, canBeDir = false, mustBeWritable = false, mustBeReadable = true)
Expand All @@ -87,10 +87,15 @@ class UploadResultToPostgresCommand : CliktCommand(
private val globalOptionsForSubcommands by requireObject<GlobalOptions>()

override fun run() {
val (ortResult, duration) = measureTimedValue { ortFile.readValue<OrtResult>() }
val (ortResult, duration) = measureTimedValue { ortResultFile.readValue<OrtResult>() }

log.perf {
"Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms."
"Read ORT result from '${ortResultFile.name}' (${ortResultFile.formatSizeInMib}) in " +
"${duration.inMilliseconds}ms."
}

requireNotNull(ortResult) {
"The provided ORT result file '${ortResultFile.canonicalPath}' has no content."
}

val postgresConfig = globalOptionsForSubcommands.config.scanner.storages?.values
Expand Down
13 changes: 9 additions & 4 deletions cli/src/main/kotlin/commands/UploadResultToSw360Command.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ class UploadResultToSw360Command : CliktCommand(
epilog = "EXPERIMENTAL: The command is still in development and usage will likely change in the near future. The " +
"command expects that a Sw360Storage for the scanner is configured."
) {
private val ortFile by option(
"--ort-file", "-i",
private val ortResultFile by option(
"--ort-result-file", "-i",
help = "The ORT result file to read as input."
).convert { it.expandTilde() }
.file(mustExist = true, canBeFile = true, canBeDir = false, mustBeWritable = false, mustBeReadable = true)
Expand All @@ -76,10 +76,15 @@ class UploadResultToSw360Command : CliktCommand(
private val globalOptionsForSubcommands by requireObject<GlobalOptions>()

override fun run() {
val (ortResult, duration) = measureTimedValue { ortFile.readValue<OrtResult>() }
val (ortResult, duration) = measureTimedValue { ortResultFile.readValue<OrtResult>() }

log.perf {
"Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms."
"Read ORT result from '${ortResultFile.name}' (${ortResultFile.formatSizeInMib}) in " +
"${duration.inMilliseconds}ms."
}

requireNotNull(ortResult) {
"The provided ORT result file '${ortResultFile.canonicalPath}' has no content."
}

val sw360Config = globalOptionsForSubcommands.config.scanner.storages?.values
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,17 @@ internal class ExportLicenseFindingCurationsCommand : CliktCommand(
).flag()

override fun run() {
val localLicenseFindingCurations = ortFile
.readValue<OrtResult>()
val ortResult = requireNotNull(ortFile.readValue<OrtResult>()) {
"The provided ORT result file '${ortFile.canonicalPath}' has no content."
}

val localLicenseFindingCurations = ortResult
.replaceConfig(repositoryConfigurationFile)
.getRepositoryLicenseFindingCurations()

val globalLicenseFindingCurations = if (licenseFindingCurationsFile.isFile) {
licenseFindingCurationsFile.readValue<RepositoryLicenseFindingCurations>()
} else {
mapOf()
}
val globalLicenseFindingCurations = licenseFindingCurationsFile.takeIf {
it.isFile
}?.readValue<RepositoryLicenseFindingCurations>().orEmpty()

globalLicenseFindingCurations
.mergeLicenseFindingCurations(localLicenseFindingCurations, updateOnlyExisting = updateOnlyExisting)
Expand Down
13 changes: 6 additions & 7 deletions helper-cli/src/main/kotlin/commands/ExportPathExcludesCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,15 @@ internal class ExportPathExcludesCommand : CliktCommand(
).flag()

override fun run() {
val localPathExcludes = ortFile
.readValue<OrtResult>()
val ortResult = requireNotNull(ortFile.readValue<OrtResult>()) {
"The provided ORT result file '${ortFile.canonicalPath}' has no content."
}

val localPathExcludes = ortResult
.replaceConfig(repositoryConfigurationFile)
.getRepositoryPathExcludes()

val globalPathExcludes = if (pathExcludesFile.isFile) {
pathExcludesFile.readValue<RepositoryPathExcludes>()
} else {
mapOf()
}
val globalPathExcludes = pathExcludesFile.takeIf { it.isFile }?.readValue<RepositoryPathExcludes>().orEmpty()

globalPathExcludes
.mergePathExcludes(localPathExcludes, updateOnlyExisting = updateOnlyExisting)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ class ExtractRepositoryConfigurationCommand : CliktCommand(
.required()

override fun run() {
ortFile
.readValue<OrtResult>()
.repository
.config.writeAsYaml(repositoryConfigurationFile)
val ortResult = requireNotNull(ortFile.readValue<OrtResult>()) {
"The provided ORT result file '${ortFile.canonicalPath}' has no content."
}

ortResult.repository.config.writeAsYaml(repositoryConfigurationFile)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.github.ajalt.clikt.parameters.arguments.convert
import com.github.ajalt.clikt.parameters.types.file

import org.ossreviewtoolkit.helper.common.writeAsYaml
import org.ossreviewtoolkit.model.OrtResult
import org.ossreviewtoolkit.model.config.RepositoryConfiguration
import org.ossreviewtoolkit.model.readValue
import org.ossreviewtoolkit.utils.expandTilde
Expand All @@ -41,8 +42,10 @@ internal class FormatRepositoryConfigurationCommand : CliktCommand(
.convert { it.absoluteFile.normalize() }

override fun run() {
repositoryConfigurationFile
.readValue<RepositoryConfiguration>()
.writeAsYaml(repositoryConfigurationFile)
val repoConfig = requireNotNull(repositoryConfigurationFile.readValue<RepositoryConfiguration>()) {
"The provided ORT result file '${repositoryConfigurationFile.canonicalPath}' has no content."
}

repoConfig.writeAsYaml(repositoryConfigurationFile)
}
}
Loading

0 comments on commit 54b6bb6

Please sign in to comment.