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

Do not leak unknown asset paths into HTML #3061

Merged
merged 3 commits into from Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -92,7 +92,7 @@ class DefaultTemplateModelFactory(val context: DokkaContext) : TemplateModelFact

private fun Appendable.resourcesForPage(pathToRoot: String, resources: List<String>): Unit =
resources.forEach {
append(with(createHTML()) {
val resourceHtml = with(createHTML()) {
when {
it.URIExtension == "css" ->
link(
Expand All @@ -112,7 +112,11 @@ class DefaultTemplateModelFactory(val context: DokkaContext) : TemplateModelFact
it.isImage() -> link(href = if (it.isAbsolute) it else "$pathToRoot$it")
else -> null
}
} ?: it)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bug was with ?: it

}

if (resourceHtml != null) {
append(resourceHtml)
}
}
}

Expand Down
91 changes: 91 additions & 0 deletions plugins/base/src/test/kotlin/resourceLinks/ResourceLinksTest.kt
Expand Up @@ -17,9 +17,11 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import utils.TestOutputWriterPlugin
import utils.assertContains
import java.io.File
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue

class ResourceLinksTest : BaseAbstractTest() {
class TestResourcesAppenderPlugin(val resources: List<String>) : DokkaPlugin() {
Expand Down Expand Up @@ -205,4 +207,93 @@ class ResourceLinksTest : BaseAbstractTest() {
}
}
}

@Test
fun `should not add unknown resources to the end of the head section`() {
IgnatBeresnev marked this conversation as resolved.
Show resolved Hide resolved
IgnatBeresnev marked this conversation as resolved.
Show resolved Hide resolved
val baseConfiguration = DokkaBaseConfiguration(
customAssets = listOf(File("test/relativePath.js"))
)

val configuration = dokkaConfiguration {
sourceSets {
sourceSet {
sourceRoots = listOf("src/main/kotlin")
}
}

pluginsConfigurations = mutableListOf(
PluginConfigurationImpl(
fqPluginName = "org.jetbrains.dokka.base.DokkaBaseConfiguration",
serializationFormat = DokkaConfiguration.SerializationFormat.JSON,
values = toJsonString(baseConfiguration)
)
)
}

val writerPlugin = TestOutputWriterPlugin()
testInline(
"""
|/src/main/kotlin/test/Test.kt
|package test
|
|class Test
""".trimMargin(),
configuration,
pluginOverrides = listOf(writerPlugin)
) {
renderingStage = { _, _ ->
val generatedFiles = writerPlugin.writer.contents

val testPageHeadHtml = generatedFiles
.getValue("root/test/-test/-test.html")
.let { Jsoup.parse(it) }
.select("head")
IgnatBeresnev marked this conversation as resolved.
Show resolved Hide resolved
.toString()

assertTrue {
testPageHeadHtml.endsWith(
"""
<script type="text/javascript" src="../../../scripts/symbol-parameters-wrapper_deferred.js" defer></script>
</head>
""".trimIndent()
)
}
}
}
}

@Test
fun `should load script as defer if name ending in _deferred`() {
val configuration = dokkaConfiguration {
sourceSets {
sourceSet {
sourceRoots = listOf("src/main/kotlin")
}
}
}

val writerPlugin = TestOutputWriterPlugin()
testInline(
"""
|/src/main/kotlin/test/Test.kt
|package test
|
|class Test
""".trimMargin(),
configuration,
pluginOverrides = listOf(writerPlugin)
) {
renderingStage = { _, _ ->
val generatedFiles = writerPlugin.writer.contents

assertContains(generatedFiles.keys, "scripts/symbol-parameters-wrapper_deferred.js")

val scripts = generatedFiles.getValue("root/test/-test/-test.html").let { Jsoup.parse(it) }.select("script")
val deferredScriptSources = scripts.filter { element -> element.hasAttr("defer") }.map { it.attr("src") }

// important to check symbol-parameters-wrapper_deferred specifically since it might break some features
assertContains(deferredScriptSources, "../../../scripts/symbol-parameters-wrapper_deferred.js")
}
}
}
}
Expand Up @@ -177,40 +177,6 @@ class PageTransformerBuilderTest : BaseAbstractTest() {
}
}

@Test
fun `should load script as defer if name ending in _deferred`() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote this test a while ago, and at the time I couldn't find a good place for it, but I think having it in ResourceLinksTest is better now, so I moved it there.

val configuration = dokkaConfiguration {
sourceSets {
sourceSet {
sourceRoots = listOf("src/main/kotlin")
}
}
}
val writerPlugin = TestOutputWriterPlugin()
testInline(
"""
|/src/main/kotlin/test/Test.kt
|package test
|
|class Test
""".trimMargin(),
configuration,
pluginOverrides = listOf(writerPlugin)
) {
renderingStage = { _, _ ->
val generatedFiles = writerPlugin.writer.contents

assertContains(generatedFiles.keys, "scripts/symbol-parameters-wrapper_deferred.js")

val scripts = generatedFiles.getValue("root/test/-test/-test.html").let { Jsoup.parse(it) }.select("script")
val deferredScriptSources = scripts.filter { element -> element.hasAttr("defer") }.map { it.attr("src") }

// important to check symbol-parameters-wrapper_deferred specifically since it might break some features
assertContains(deferredScriptSources, "../../../scripts/symbol-parameters-wrapper_deferred.js")
}
}
}

private fun <T> Collection<T>.assertCount(n: Int, prefix: String = "") =
assert(count() == n) { "${prefix}Expected $n, got ${count()}" }

Expand Down