Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Javadoc exposes absolute paths in dokka-configuration.json #3958

Open
TWiStErRob opened this issue Dec 17, 2024 · 2 comments · May be fixed by #3961
Open

Javadoc exposes absolute paths in dokka-configuration.json #3958

TWiStErRob opened this issue Dec 17, 2024 · 2 comments · May be fixed by #3961
Assignees
Labels
bug runner: Gradle plugin An issue/PR related to Dokka's Gradle plugin

Comments

@TWiStErRob
Copy link
Contributor

Describe the bug

Just migrated to Dokka 2.0.0, and I was diffing the artifacts of publishToMavenLocal. I found that the new javadoc jar contains the absolute paths of the source files and classpaths.

This means the resulting artifacts are not reproducible.

There might be also a security risk as some companies use Dokka to generate javadoc for public APIs and publish them online. These could leak internal implementation details of their systems, and the paths could be used to learn about their build machines. This could in theory aid attackers to exploit vulnerabilities more easily.

Expected behaviour

Relative paths or paths with env vars or no paths at all?

(Note re relative paths: my Gradle and Project paths are on separate Windows drive letters, so there's no way to navigate between them with ../. Even if that was possible the depth of the folders would still make it not reproducible.)

Screenshots
I replaced my local absolute paths with GRADLE_USER_HOME and PROJECT_CHECKOUT_DIR.

{
  "moduleName": "my-module",
  "moduleVersion": "<version>-SNAPSHOT",
  "outputDir": "%PROJECT_CHECKOUT_DIR%\\my\\module\\build\\dokka\\javadoc",
  "cacheRoot": null,
  "offlineMode": false,
  "sourceSets": [
    {
      "displayName": "jvm",
      "sourceSetID": {
        "scopeId": ":my:module",
        "sourceSetName": "main"
      },
      "classpath": [
        "%GRADLE_USER_HOME%\\caches\\8.8\\generated-gradle-jars\\gradle-api-8.8.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-ant-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-astbuilder-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-console-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-datetime-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-dateutil-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-groovydoc-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-json-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-nio-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-sql-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-templates-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-test-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-xml-3.0.21.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\javaparser-core-3.17.0.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\kotlin-reflect-1.9.22.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\kotlin-stdlib-1.9.22.jar",
        "%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\gradle-installation-beacon-8.8.jar",
        "%PROJECT_CHECKOUT_DIR%\\my\\module\\build\\classes\\java\\main",
        "%PROJECT_CHECKOUT_DIR%\\my\\module\\build\\classes\\kotlin\\main",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.kotlin\\kotlin-stdlib-jdk8\\1.4.32\\3302f9ec8a5c1ed220781dbd37770072549bd333\\kotlin-stdlib-jdk8-1.4.32.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.kotlin\\kotlin-reflect\\1.4.32\\ce852b166d97f0f1991b5130c2bb02e2ef6c554e\\kotlin-reflect-1.4.32.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.kotlin\\kotlin-stdlib-jdk7\\1.4.32\\3546900a3ebff0c43f31190baf87a9220e37b7ea\\kotlin-stdlib-jdk7-1.4.32.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.kotlin\\kotlin-stdlib\\1.4.32\\461367948840adbb0839c51d91ed74ef4a9ccb52\\kotlin-stdlib-1.4.32.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.gradle\\gradle-kotlin-dsl\\6.1.1\\4f811c43a0688fb76681c357033c734fa740d898\\gradle-kotlin-dsl-6.1.1.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\gradle\\8.6.1\\39f7fafdf840259a73a7107af8c64109086ed429\\gradle-8.6.1.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.kotlin\\kotlin-stdlib-common\\1.4.32\\ef50bfa2c0491a11dcc35d9822edbfd6170e1ea2\\kotlin-stdlib-common-1.4.32.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains\\annotations\\13.0\\919f0dfe192fb4e063e7dacadee7f8bb9a2672a9\\annotations-13.0.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\builder\\8.6.1\\3ede92b2242a7a5b214479bd81c75c6c894308e8\\builder-8.6.1.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\builder-model\\8.6.1\\f4e5827bbddac07172f97f5d629911a4d49620a2\\builder-model-8.6.1.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\gradle-api\\8.6.1\\1dde4ab125287658b1793e4a023e6249e017d358\\gradle-api-8.6.1.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\manifest-merger\\31.6.1\\74d2b65c9e2b55d6f7de18cced38aa6c777f63d5\\manifest-merger-31.6.1.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android\\zipflinger\\8.6.1\\de8e3267995699af356740cf562cbedb485f5763\\zipflinger-8.6.1.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\apksig\\8.6.1\\f005788487574c7d6ba23dea63bf8cb3a4f164a6\\apksig-8.6.1.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\apkzlib\\8.6.1\\d656b52facbb301b8bdc1e40a5ae008bcf335fe9\\apkzlib-8.6.1.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.squareup\\javawriter\\2.5.0\\81241ff7078ef14f42ea2a8995fa09c096256e6b\\javawriter-2.5.0.jar",
        "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm\\9.6\\aa205cf0a06dbd8e04ece91c0b37c3f5d567546a\\asm-9.6.jar"
      ],
      "sourceRoots": [
        "%PROJECT_CHECKOUT_DIR%\\my\\module\\src\\main\\kotlin"
      ],
      "dependentSourceSets": [
      ],
      "samples": [
      ],
      "includes": [
      ],
      "includeNonPublic": false,
      "reportUndocumented": false,
      "skipEmptyPackages": true,
      "skipDeprecated": false,
      "jdkVersion": 11,
      "sourceLinks": [
      ],
      "perPackageOptions": [
      ],
      "externalDocumentationLinks": [
        {
          "url": "https://docs.oracle.com/en/java/javase/11/docs/api/",
          "packageListUrl": "https://docs.oracle.com/en/java/javase/11/docs/api/element-list"
        },
        {
          "url": "https://kotlinlang.org/api/core/",
          "packageListUrl": "https://kotlinlang.org/api/core/package-list"
        }
      ],
      "languageVersion": null,
      "apiVersion": null,
      "noStdlibLink": false,
      "noJdkLink": false,
      "suppressedFiles": [
      ],
      "analysisPlatform": "jvm",
      "documentedVisibilities": [
        "PUBLIC"
      ]
    }
  ],
  "pluginsClasspath": [
    "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.dokka\\javadoc-plugin\\2.0.0\\602a87960edaa602969fa4922ad9efc02ed3a39d\\javadoc-plugin-2.0.0.jar",
    "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.dokka\\templating-plugin\\2.0.0\\2c817817579cd8c92ded6f33fd9e6b746ecf01c7\\templating-plugin-2.0.0.jar",
    "%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.dokka\\dokka-base\\2.0.0\\dcce26b10e9af3b3f2eba0403d6a9561e6da9098\\dokka-base-2.0.0.jar"
  ],
  "pluginsConfiguration": [
    {
      "fqPluginName": "org.jetbrains.dokka.base.DokkaBase",
      "serializationFormat": "JSON",
      "values": "{\"customAssets\":[],\"customStyleSheets\":[],\"separateInheritedMembers\":false,\"mergeImplicitExpectActualDeclarations\":false}"
    },
    {
      "fqPluginName": "org.jetbrains.dokka.versioning.VersioningPlugin",
      "serializationFormat": "JSON",
      "values": "{\"olderVersions\":[],\"renderVersionsNavigationOnAllPages\":true}"
    }
  ],
  "modules": [
  ],
  "failOnWarning": false,
  "delayTemplateSubstitution": false,
  "suppressObviousFunctions": true,
  "includes": [
  ],
  "suppressInheritedMembers": false,
  "finalizeCoroutines": false
}

To Reproduce
gradlew dokkaGeneratePublicationJavadoc and inspect the javadoc jar.

Dokka configuration

plugins {
	id("org.jetbrains.dokka")
	id("org.jetbrains.dokka-javadoc")
}

Workaround
(For this users have to notice that this is happening so that they can action it.)

See https://github.com/Kotlin/dokka/blob/v2.0.0/dokka-runners/dokka-gradle-plugin/src/main/kotlin/tasks/DokkaGenerateTask.kt#L99-L106

Attempt 1

Follow docs...

tasks.withType<DokkaGenerateTask>().configureEach {
	@OptIn(InternalDokkaGradlePluginApi::class)
	dokkaConfigurationJsonFile.set(null as File?)
	// or
	dokkaConfigurationJsonFile.unset()
}

Tried also wrapping in afterEvaluate, neither worked.

Attempt 2

Delete file at the "right" time.

tasks.withType<DokkaGenerateTask>().configureEach {
	doLast {
		@OptIn(InternalDokkaGradlePluginApi::class)
		dokkaConfigurationJsonFile.orNull?.asFile?.delete()
	}
}

but this is way too hacky.

Attempt 3

Hail Mary... based on some random intuition.

tasks.withType<DokkaGenerateTask>().configureEach {
	@OptIn(InternalDokkaGradlePluginApi::class)
	dokkaConfigurationJsonFile.unsetConvention()
	// or
	dokkaConfigurationJsonFile.convention(null as RegularFile?)
}

Bingo!

Installation

  • Operating system: Windows 10
  • Build tool: Gradle v8.12 RC
  • Dokka version: 2.0.0
@TWiStErRob TWiStErRob added the bug label Dec 17, 2024
@adam-enko
Copy link
Member

Hi, thanks for the report. I agree that the dokka-configuration.json file should not be included in the final output. It's only intended for debugging purposes on a local or CI machine, and shouldn't be shared.

For some context: I recently changed the dokkaConfigurationJsonFile property to be an explicit task output to help with debugging tricky issues with KMP on CI. This is an unintended consequence I didn't anticipate.

To Reproduce
gradlew dokkaGeneratePublicationJavadoc and inspect the javadoc jar.

The dokkaGeneratePublicationJavadoc task doesn't produce a JAR file (there's currently no official Dokka task that will produce a JAR). I assume your project has some custom Javadoc JAR task defined?

When I run the library-publishing-example, it doesn't include the dokka-configuration.json file in the resulting JAR, but that's because it specifically selects the task output directory using from(tasks.dokkaGeneratePublicationJavadoc.flatMap { it.outputDirectory }).

val dokkaJavadocJar by tasks.registering(Jar::class) {
description = "A Javadoc JAR containing Dokka Javadoc"
from(tasks.dokkaGeneratePublicationJavadoc.flatMap { it.outputDirectory })
archiveClassifier.set("javadoc")
}

However, I think it's too easy to make a mistake. I'll see if I can find a better way to prevent the config file from being accidentally shared as an output.

@adam-enko adam-enko added the runner: Gradle plugin An issue/PR related to Dokka's Gradle plugin label Dec 17, 2024
@adam-enko adam-enko self-assigned this Dec 17, 2024
adam-enko added a commit that referenced this issue Dec 18, 2024
Dumping the Dokka config files is useful for debugging, but can interfere with task outputs.

Here we add a flag that disables the dumping the config file by default, but we enable it for our own tests.

Fix #3958
@adam-enko adam-enko linked a pull request Dec 18, 2024 that will close this issue
adam-enko added a commit that referenced this issue Dec 18, 2024
Dumping the Dokka config files is useful for debugging, but can interfere with task outputs.

Here we add a flag that disables the dumping the config file by default, but we enable it for our own tests.

Fix #3958
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug runner: Gradle plugin An issue/PR related to Dokka's Gradle plugin
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants