From 36e69fcd4dc827f0542fb2cd0739a5d5e3bab7e5 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Sun, 20 Aug 2023 20:53:20 +0200 Subject: [PATCH] Trying to parse the standard library as dependency --- .../frontends/golang/GoLanguageFrontend.kt | 22 ++++++++---- .../golang/GoLanguageFrontendTest.kt | 34 +++++++++++++++++++ .../test/resources/golang-std/fmt/print.go | 6 ++++ 3 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 cpg-language-go/src/test/resources/golang-std/fmt/print.go diff --git a/cpg-language-go/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/GoLanguageFrontend.kt b/cpg-language-go/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/GoLanguageFrontend.kt index ee93f364308..9ae1d1ff4a7 100644 --- a/cpg-language-go/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/GoLanguageFrontend.kt +++ b/cpg-language-go/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/GoLanguageFrontend.kt @@ -79,12 +79,18 @@ class GoLanguageFrontend(language: Language, ctx: Translatio @Throws(TranslationException::class) override fun parse(file: File): TranslationUnitDeclaration { + val dependency = + ctx.config.includePaths.firstOrNull() { + file.absolutePath.contains(it.toAbsolutePath().toString()) + } + // Make sure, that our top level is set either way val topLevel = - if (config.topLevel != null) { - config.topLevel - } else { - file.parentFile + // If this file is part of an include, we set the top level to the root of the include + when { + dependency != null -> dependency.toFile() + config.topLevel != null -> config.topLevel + else -> file.parentFile }!! val std = GoStandardLibrary.INSTANCE @@ -120,8 +126,12 @@ class GoLanguageFrontend(language: Language, ctx: Translatio // module path as well as the current directory in relation to the topLevel var packagePath = file.parentFile.relativeTo(topLevel) - // If we are in a module, we need to prepend the module path to it - currentModule?.let { packagePath = File(it.module.mod.path).resolve(packagePath) } + // If we are in a module, we need to prepend the module path to it. There is an + // exception if we are in the "std" module, which represents the standard library + val modulePath = currentModule?.module?.mod?.path + if (modulePath != null && modulePath != "std") { + packagePath = File(modulePath).resolve(packagePath) + } p.path = packagePath.path } catch (ex: IllegalArgumentException) { diff --git a/cpg-language-go/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/GoLanguageFrontendTest.kt b/cpg-language-go/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/GoLanguageFrontendTest.kt index a6afc3c4754..972776b3f1b 100644 --- a/cpg-language-go/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/GoLanguageFrontendTest.kt +++ b/cpg-language-go/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/golang/GoLanguageFrontendTest.kt @@ -41,6 +41,7 @@ import de.fraunhofer.aisec.cpg.graph.statements.expressions.* import de.fraunhofer.aisec.cpg.graph.types.FunctionType import de.fraunhofer.aisec.cpg.graph.types.ObjectType import de.fraunhofer.aisec.cpg.graph.types.PointerType +import java.io.File import java.nio.file.Path import kotlin.test.* @@ -790,4 +791,37 @@ class GoLanguageFrontendTest : BaseTest() { assertNotNull(g) assertLocalName("string", g.type) } + + @Test + fun testResolveStdLibImport() { + val stdLib = Path.of("src", "test", "resources", "golang-std") + val topLevel = Path.of("src", "test", "resources", "golang") + val tu = + analyzeAndGetFirstTU( + listOf( + topLevel.resolve("function.go").toFile(), + stdLib.resolve("fmt").toFile(), + ), + topLevel, + true + ) { + it.registerLanguage() + it.includePath("src/test/resources/golang-std") + } + + assertNotNull(tu) + + val p = tu.namespaces["p"] + assertNotNull(p) + + val main = p.functions["main"] + assertNotNull(main) + + val printfCall = main.calls["fmt.Printf"] + assertNotNull(printfCall) + + val printf = printfCall.invokes.firstOrNull() + assertNotNull(printf) + assertEquals("print.go", File(printf.location?.artifactLocation?.uri?.path.toString()).name) + } } diff --git a/cpg-language-go/src/test/resources/golang-std/fmt/print.go b/cpg-language-go/src/test/resources/golang-std/fmt/print.go new file mode 100644 index 00000000000..b9b025641d6 --- /dev/null +++ b/cpg-language-go/src/test/resources/golang-std/fmt/print.go @@ -0,0 +1,6 @@ +package fmt + +func Printf(format string, a ...any) (n int, err error) { + // Not a real implementation, and we are ignoring it anyway + return 0, nil +}