Skip to content
Permalink
Browse files Browse the repository at this point in the history
#000 - Escape filenames in artifact tab
  • Loading branch information
arvindsv committed Oct 19, 2021
1 parent 60ff524 commit f5c1d2a
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 6 deletions.
1 change: 1 addition & 0 deletions common/build.gradle
Expand Up @@ -26,6 +26,7 @@ dependencies {
api project.deps.dom4j
api project.deps.apacheHttpMime
api project.deps.commonsCollections4
api project.deps.commonsText
api project.deps.springTx
implementation project.deps.jodaTime
annotationProcessor project.deps.lombok
Expand Down
Expand Up @@ -33,7 +33,7 @@ public class DirectoryEntries extends ArrayList<DirectoryEntry> implements HtmlR
@Override
public void render(HtmlRenderer renderer) {
if (isArtifactsDeleted || isEmpty()) {
HtmlElement element = p().content("Artifacts for this job instance are unavailable as they may have been <a href='" +
HtmlElement element = p().unsafecontent("Artifacts for this job instance are unavailable as they may have been <a href='" +
CurrentGoCDVersion.docsUrl("configuration/delete_artifacts.html") +
"' target='blank'>purged by Go</a> or deleted externally. "
+ "Re-run the stage or job to generate them again.");
Expand Down
Expand Up @@ -30,7 +30,7 @@ protected HtmlRenderable htmlBody() {
return HtmlElement.li().content(
HtmlElement.span(HtmlAttribute.cssClass("artifact")).content(
HtmlElement.a(HtmlAttribute.href(getUrl()))
.content(getFileName())
.safecontent(getFileName())
)
);

Expand Down
Expand Up @@ -41,7 +41,7 @@ protected HtmlRenderable htmlBody() {
HtmlElement.div(cssClass("dir-container")).content(
HtmlElement.span(cssClass("directory")).content(
HtmlElement.a(onclick("BuildDetail.tree_navigator(this)"))
.content(getFileName())
.safecontent(getFileName())
)
),
HtmlElement.div(cssClass("subdir-container"), style("display:none"))
Expand Down
Expand Up @@ -19,6 +19,7 @@
import java.util.List;

import com.thoughtworks.go.server.presentation.models.HtmlRenderer;
import org.apache.commons.text.StringEscapeUtils;

public class HtmlElement implements HtmlRenderable {
public static HtmlElement div(HtmlAttribute... attributes) { return new HtmlElement("div", attributes); }
Expand All @@ -37,10 +38,14 @@ private HtmlElement(String elementName, HtmlAttribute... attributes) {
this.attributes = attributes;
}

public HtmlElement content(String body) {
public HtmlElement unsafecontent(String body) {
return content(new TextElement(body));
}

public HtmlElement safecontent(String body) {
return content(new TextElement(StringEscapeUtils.escapeHtml4(body)));
}

public HtmlElement content(HtmlRenderable... elements) {
for (HtmlRenderable element : elements) {
addToBody(element);
Expand Down Expand Up @@ -80,5 +85,4 @@ public void render(HtmlRenderer renderer) {
renderer.append("</" + elementName + ">\n");
}
}

}
@@ -0,0 +1,34 @@
/*
* Copyright 2021 ThoughtWorks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.thoughtworks.go.domain;

import com.thoughtworks.go.server.presentation.models.HtmlRenderer;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class FileDirectoryEntryTest {
@Test
void shouldEscapeFilename() {
FileDirectoryEntry entry = new FileDirectoryEntry("<div>Hello</div>", "https://www.example.com");
HtmlRenderer renderer = new HtmlRenderer("");
entry.htmlBody().render(renderer);

assertTrue(renderer.asString().contains("&lt;div&gt;Hello&lt;/div&gt;"));
assertFalse(renderer.asString().contains("<div>Hello</div>"));
}
}
Expand Up @@ -15,10 +15,11 @@
*/
package com.thoughtworks.go.domain;

import com.thoughtworks.go.server.presentation.models.HtmlRenderer;
import org.junit.jupiter.api.Test;

import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class FolderDirectoryEntryTest {
@Test
Expand All @@ -28,4 +29,16 @@ public void shouldAddFile() throws Exception {
entry.addFile("file", "path");
assertThat(subDirectory, hasItem(new FileDirectoryEntry("file", "path")));
}

@Test
public void shouldEscapeFolderName() throws Exception {
DirectoryEntries subDirectory = new DirectoryEntries();
FolderDirectoryEntry entry = new FolderDirectoryEntry("<div>Hello</div>", "url", subDirectory);

HtmlRenderer renderer = new HtmlRenderer("");
entry.htmlBody().render(renderer);

assertThat(renderer.asString(), containsString("&lt;div&gt;Hello&lt;/div&gt;"));
assertThat(renderer.asString(), not(containsString("<div>Hello</div>")));
}
}
@@ -0,0 +1,34 @@
/*
* Copyright 2021 ThoughtWorks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.thoughtworks.go.server.presentation.html;

import com.thoughtworks.go.server.presentation.models.HtmlRenderer;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class HtmlElementTest {
@Test
void shouldEscapeContent() {
HtmlElement element = HtmlElement.span().safecontent("<div>Hello</div>");
HtmlRenderer renderer = new HtmlRenderer("");

element.render(renderer);

assertEquals("<span>\n&lt;div&gt;Hello&lt;/div&gt;\n</span>\n", renderer.asString());
}
}
2 changes: 2 additions & 0 deletions dependencies.gradle
Expand Up @@ -48,6 +48,7 @@ final Map<String, String> libraries = [
commonsLang : 'commons-lang:commons-lang:2.6',
commonsLang3 : 'org.apache.commons:commons-lang3:3.12.0',
commonsPool : 'org.apache.commons:commons-pool2:2.11.1',
commonsText : 'org.apache.commons:commons-text:1.8',
dbunit : 'org.dbunit:dbunit:2.7.2',
dom4j : 'dom4j:dom4j:1.6.1',
ehcache : 'net.sf.ehcache:ehcache:2.10.9.2',
Expand Down Expand Up @@ -131,6 +132,7 @@ final Map<String, String> v = [
commonsLang : versionOf(libraries.commonsLang),
commonsLang3 : versionOf(libraries.commonsLang3),
commonsPool : versionOf(libraries.commonsPool),
commonsText : versionOf(libraries.commonsText),
dom4j : versionOf(libraries.dom4j),
ehcache : versionOf(libraries.ehcache),
felix : versionOf(libraries.felix),
Expand Down
1 change: 1 addition & 0 deletions server/build.gradle
Expand Up @@ -817,6 +817,7 @@ task verifyWar(type: VerifyJarTask) {
"commons-io-${project.versions.commonsIO}.jar",
"commons-lang-${project.versions.commonsLang}.jar",
"commons-lang3-${project.versions.commonsLang3}.jar",
"commons-text-${project.versions.commonsText}.jar",
"commons-pool2-${project.versions.commonsPool}.jar",
"config-api-${project.version}.jar",
"config-server-${project.version}.jar",
Expand Down

0 comments on commit f5c1d2a

Please sign in to comment.