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 <sebastian.schuberth@bosch.io>
  • Loading branch information
sschuberth committed Apr 20, 2021
1 parent dee2deb commit 4d103f5
Show file tree
Hide file tree
Showing 50 changed files with 201 additions and 136 deletions.
4 changes: 4 additions & 0 deletions advisor/src/main/kotlin/Advisor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ class Advisor(
"Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms."
}

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

if (ortResult.analyzer == null) {
log.warn {
"Cannot run the advisor as the provided ORT result file '${ortFile.canonicalPath}' does not contain " +
Expand Down
2 changes: 1 addition & 1 deletion advisor/src/test/kotlin/advisors/VulnerableCodeTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ private fun resultFile(): File = File(TEST_FILES_ROOT).resolve(TEST_RESULT_NAME)
* Return a list with [Package]s from the analyzer result file that serve as input for the [VulnerableCode] advisor.
*/
private fun inputPackages(): List<Package> =
resultFile().readValue<OrtResult>().getPackages(false).map { it.pkg }
resultFile().readValue<OrtResult>()?.getPackages(false)?.map { it.pkg }.orEmpty()

/**
* Generate the JSON body of the request to query information about packages. It mainly consists of an array with the
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 @@ -223,7 +223,7 @@ open class Npm(

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

val json = file.readValue<ObjectNode>()
val json = file.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
26 changes: 14 additions & 12 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,21 @@ 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()
ortResult shouldNotBeNull {
val evaluator = Evaluator(
ortResult = this,
licenseInfoResolver = createLicenseInfoResolver(),
licenseClassifications = licenseFile.readValue() ?: LicenseClassifications()
)

val result = evaluator.run(script)
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")
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
4 changes: 4 additions & 0 deletions cli/src/main/kotlin/commands/DownloaderCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ class DownloaderCommand : CliktCommand(name = "download", help = "Fetch source c
"${duration.inMilliseconds}ms."
}

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

val analyzerResult = ortResult.analyzer?.result

if (analyzerResult == null) {
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.mapNotNull { curation ->
curation.id.toClearlyDefinedCoordinates()?.let { coordinates ->
curation to coordinates
Expand Down
4 changes: 4 additions & 0 deletions cli/src/main/kotlin/commands/UploadResultToPostgresCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ class UploadResultToPostgresCommand : CliktCommand(
"Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms."
}

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

val postgresConfig = globalOptionsForSubcommands.config.scanner.storages?.values
?.filterIsInstance<PostgresStorageConfiguration>()?.singleOrNull()

Expand Down
4 changes: 4 additions & 0 deletions cli/src/main/kotlin/commands/UploadResultToSw360Command.kt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ class UploadResultToSw360Command : CliktCommand(
"Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms."
}

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

val sw360Config = globalOptionsForSubcommands.config.scanner.storages?.values
?.filterIsInstance<Sw360StorageConfiguration>()?.singleOrNull()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,17 @@ internal class ExportLicenseFindingCurationsCommand : CliktCommand(
).flag()

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

val localLicenseFindingCurations = getLicenseFindingCurationsByRepository(
curations = ortResult.repository.config.curations.licenseFindings,
nestedRepositories = ortResult.repository.nestedRepositories
)

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 @@ -68,16 +68,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.write(repositoryConfigurationFile)
val ortResult = requireNotNull(ortFile.readValue<OrtResult>()) {
"The provided ORT result file '${ortFile.canonicalPath}' has no content."
}

ortResult.repository.config.write(repositoryConfigurationFile)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ internal class FormatRepositoryConfigurationCommand : CliktCommand(
.convert { it.absoluteFile.normalize() }

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

repoConfig.write(repositoryConfigurationFile)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,12 @@ internal class GenerateProjectExcludesCommand : CliktCommand(
.required()

override fun run() {
val repositoryConfiguration = if (repositoryConfigurationFile.isFile) {
repositoryConfigurationFile.readValue()
} else {
RepositoryConfiguration()
}
val repositoryConfiguration = repositoryConfigurationFile.takeIf { it.isFile }?.readValue()
?: RepositoryConfiguration()

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

val generatedPathExcludes = ortResult
.getProjects()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ internal class GenerateRuleViolationResolutionsCommand : CliktCommand(
).enum<Severity>().split(",").default(enumValues<Severity>().asList())

override fun run() {
val repositoryConfiguration = repositoryConfigurationFile.readValue<RepositoryConfiguration>()
val ortResult = ortFile.readValue<OrtResult>().replaceConfig(repositoryConfiguration)
val repositoryConfiguration = repositoryConfigurationFile.readValue() ?: RepositoryConfiguration()

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

val generatedResolutions = ortResult
.getUnresolvedRuleViolations()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,17 @@ internal class GenerateScopeExcludesCommand : CliktCommand(
.required()

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

val scopeExcludes = ortResult.generateScopeExcludes()

repositoryConfigurationFile
.readValue<RepositoryConfiguration>()
.replaceScopeExcludes(scopeExcludes)
.sortScopeExcludes()
.write(repositoryConfigurationFile)
val repoConfig = requireNotNull(repositoryConfigurationFile.readValue<RepositoryConfiguration>()) {
"The provided ORT result file '${repositoryConfigurationFile.canonicalPath}' has no content."
}

repoConfig.replaceScopeExcludes(scopeExcludes).sortScopeExcludes().write(repositoryConfigurationFile)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,15 @@ internal class GenerateTimeoutErrorResolutionsCommand : CliktCommand(
).flag()

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

val resolutionProvider = DefaultResolutionProvider().apply {
var resolutions = Resolutions()

resolutionsFile?.let {
resolutions = resolutions.merge(it.readValue())
resolutionsFile?.readValue<Resolutions>()?.let {
resolutions = resolutions.merge(it)
}

resolutions = resolutions.merge(ortResult.getResolutions())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,8 @@ internal class ImportCopyrightGarbageCommand : CliktCommand(
override fun run() {
val entriesToImport = inputCopyrightGarbageFile.readLines().filterNot { it.isBlank() }

val existingCopyrightGarbage = if (outputCopyrightGarbageFile.isFile) {
outputCopyrightGarbageFile.readValue<CopyrightGarbage>().items
} else {
emptySet<String>()
}
val existingCopyrightGarbage = outputCopyrightGarbageFile.takeIf { it.isFile }
?.readValue<CopyrightGarbage>()?.items.orEmpty()

val collator = Collator.getInstance(Locale("en", "US.utf-8", "POSIX"))
CopyrightGarbage((entriesToImport + existingCopyrightGarbage).toSortedSet(collator)).let {
Expand Down
Loading

0 comments on commit 4d103f5

Please sign in to comment.