Skip to content

Commit 6e68575

Browse files
committed
refactor(scanner): Generally relativize paths returned by scanners
Do not leave it to the scanner implementation to relativize paths (to not expose any information about the system running ORT), but do it generally when anyway post-processing license findings. Signed-off-by: Sebastian Schuberth <[email protected]>
1 parent 25d09fe commit 6e68575

File tree

6 files changed

+38
-46
lines changed

6 files changed

+38
-46
lines changed

model/src/main/kotlin/TextLocation.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
package org.ossreviewtoolkit.model
2121

22+
import java.io.File
23+
2224
import kotlin.math.abs
2325
import kotlin.math.min
2426

@@ -90,4 +92,20 @@ data class TextLocation(
9092
linesOverlapWith(other) -> 0
9193
else -> min(abs(other.startLine - endLine), abs(startLine - other.endLine))
9294
}
95+
96+
/**
97+
* Return a [TextLocation] whose path is relative to [basePath], or throw an [IllegalArgumentException] if the paths
98+
* have different roots.
99+
*/
100+
fun withRelativePath(basePath: File): TextLocation {
101+
val pathAsFile = File(path)
102+
103+
val relativePath = when {
104+
!pathAsFile.isAbsolute -> pathAsFile
105+
basePath.isFile -> pathAsFile.relativeTo(basePath.parentFile)
106+
else -> pathAsFile.relativeTo(basePath)
107+
}
108+
109+
return copy(path = relativePath.invariantSeparatorsPath)
110+
}
93111
}

plugins/scanners/askalono/src/main/kotlin/Askalono.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,23 +75,19 @@ class Askalono internal constructor(
7575
if (stderr.isNotBlank()) logger.debug { stderr }
7676
if (isError) throw ScanException(errorMessage)
7777

78-
generateSummary(startTime, endTime, path, stdout)
78+
generateSummary(startTime, endTime, stdout)
7979
}
8080
}
8181

82-
private fun generateSummary(startTime: Instant, endTime: Instant, scanPath: File, result: String): ScanSummary {
82+
private fun generateSummary(startTime: Instant, endTime: Instant, result: String): ScanSummary {
8383
val licenseFindings = mutableSetOf<LicenseFinding>()
8484

8585
result.lines().forEach { line ->
8686
val root = jsonMapper.readTree(line)
8787
root["result"]?.let { result ->
8888
val licenseFinding = LicenseFinding(
8989
license = result["license"]["name"].textValue(),
90-
location = TextLocation(
91-
// Turn absolute paths in the native result into relative paths to not expose any information.
92-
relativizePath(scanPath, File(root["path"].textValue())),
93-
TextLocation.UNKNOWN_LINE
94-
),
90+
location = TextLocation(root["path"].textValue(), TextLocation.UNKNOWN_LINE),
9591
score = result["score"].floatValue()
9692
)
9793

plugins/scanners/boyterlc/src/main/kotlin/BoyterLc.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ class BoyterLc internal constructor(
8484
if (stderr.isNotBlank()) logger.debug { stderr }
8585
if (isError) throw ScanException(errorMessage)
8686

87-
generateSummary(startTime, endTime, path, resultFile).also {
87+
generateSummary(startTime, endTime, resultFile).also {
8888
resultFile.parentFile.safeDeleteRecursively(force = true)
8989
}
9090
}
9191
}
9292

93-
private fun generateSummary(startTime: Instant, endTime: Instant, scanPath: File, resultFile: File): ScanSummary {
93+
private fun generateSummary(startTime: Instant, endTime: Instant, resultFile: File): ScanSummary {
9494
val licenseFindings = mutableSetOf<LicenseFinding>()
9595
val result = resultFile.readTree()
9696

@@ -99,11 +99,7 @@ class BoyterLc internal constructor(
9999
file["LicenseGuesses"].map {
100100
LicenseFinding(
101101
license = it["LicenseId"].textValue(),
102-
location = TextLocation(
103-
// Turn absolute paths in the native result into relative paths to not expose any information.
104-
relativizePath(scanPath, filePath),
105-
TextLocation.UNKNOWN_LINE
106-
),
102+
location = TextLocation(filePath.invariantSeparatorsPath, TextLocation.UNKNOWN_LINE),
107103
score = it["Percentage"].floatValue()
108104
)
109105
}

scanner/src/main/kotlin/CommandLinePathScannerWrapper.kt

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919

2020
package org.ossreviewtoolkit.scanner
2121

22-
import java.io.File
23-
2422
import org.apache.logging.log4j.kotlin.Logging
2523

2624
import org.ossreviewtoolkit.model.ScannerDetails
@@ -38,22 +36,4 @@ abstract class CommandLinePathScannerWrapper(name: String) : PathScannerWrapper,
3836
abstract val configuration: String
3937

4038
override val details by lazy { ScannerDetails(name, getVersion(), configuration) }
41-
42-
/**
43-
* Return the invariant relative path of the [scanned file][scannedFilename] with respect to the
44-
* [scanned path][scanPath].
45-
*/
46-
protected fun relativizePath(scanPath: File, scannedFilename: File): String {
47-
val relativePathToScannedFile = if (scannedFilename.isAbsolute) {
48-
if (scanPath.isFile) {
49-
scannedFilename.relativeTo(scanPath.parentFile)
50-
} else {
51-
scannedFilename.relativeTo(scanPath)
52-
}
53-
} else {
54-
scannedFilename
55-
}
56-
57-
return relativePathToScannedFile.invariantSeparatorsPath
58-
}
5939
}

scanner/src/main/kotlin/Scanner.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,10 @@ class Scanner(
607607
val summaryWithMappedLicenses = summary.copy(
608608
licenseFindings = summary.licenseFindings.mapTo(mutableSetOf()) {
609609
val licenseString = it.license.toString()
610-
it.copy(license = licenseString.mapLicense(scannerConfig.detectedLicenseMapping).toSpdx())
610+
it.copy(
611+
license = licenseString.mapLicense(scannerConfig.detectedLicenseMapping).toSpdx(),
612+
location = it.location.withRelativePath(downloadDir)
613+
)
611614
}
612615
)
613616

scanner/src/testFixtures/kotlin/AbstractPathScannerWrapperFunTest.kt

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import io.kotest.core.spec.style.StringSpec
2525
import io.kotest.engine.spec.tempdir
2626
import io.kotest.inspectors.forAll
2727
import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder
28-
import io.kotest.matchers.file.shouldNotStartWithPath
28+
import io.kotest.matchers.file.aFile
29+
import io.kotest.matchers.shouldBe
2930

3031
import java.io.File
3132

@@ -63,23 +64,21 @@ abstract class AbstractPathScannerWrapperFunTest(testTags: Set<Tag> = emptySet()
6364
init {
6465
"Scanning a single file succeeds".config(tags = testTags) {
6566
val result = scanner.scanPath(inputDir.resolve("LICENSE"), scanContext)
67+
val findings = result.licenseFindings.map { it.copy(location = it.location.withRelativePath(inputDir)) }
6668

67-
with(result) {
68-
licenseFindings shouldContainExactlyInAnyOrder expectedFileLicenses
69-
licenseFindings.forAll {
70-
File(it.location.path) shouldNotStartWithPath inputDir
71-
}
69+
findings shouldContainExactlyInAnyOrder expectedFileLicenses
70+
findings.forAll {
71+
inputDir.resolve(it.location.path) shouldBe aFile()
7272
}
7373
}
7474

7575
"Scanning a directory succeeds".config(tags = testTags) {
7676
val result = scanner.scanPath(inputDir, scanContext)
77+
val findings = result.licenseFindings.map { it.copy(location = it.location.withRelativePath(inputDir)) }
7778

78-
with(result) {
79-
licenseFindings shouldContainExactlyInAnyOrder expectedDirectoryLicenses
80-
licenseFindings.forAll {
81-
File(it.location.path) shouldNotStartWithPath inputDir
82-
}
79+
findings shouldContainExactlyInAnyOrder expectedDirectoryLicenses
80+
findings.forAll {
81+
inputDir.resolve(it.location.path) shouldBe aFile()
8382
}
8483
}
8584
}

0 commit comments

Comments
 (0)