Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/src/org/labkey/api/data/dialect/PkMetaDataReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ public int getKeySeq() throws SQLException

public String getKeyName() throws SQLException
{
return _rsCols.getString("pk_name");
return _rsCols.getString("PK_NAME");
}
}
60 changes: 60 additions & 0 deletions core/src/org/labkey/core/wiki/MarkdownServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@
import org.commonmark.ext.image.attributes.ImageAttributesExtension;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlNodeRendererContext;
import org.commonmark.renderer.html.HtmlRenderer;
import org.commonmark.renderer.html.CoreHtmlNodeRenderer;
import org.commonmark.node.HtmlInline;
import org.commonmark.node.HtmlBlock;
import org.labkey.api.markdown.MarkdownService;

import java.util.List;
import java.util.Set;

public class MarkdownServiceImpl implements MarkdownService
{
Expand Down Expand Up @@ -55,10 +60,65 @@ public MarkdownServiceImpl()
.softbreak("<br>\n") // See Issue #34169
.sanitizeUrls(true)
.escapeHtml(true)
.nodeRendererFactory(CommentNodeRenderer::new)
.extensions(extensions)
.build();
}

private static class CommentNodeRenderer extends CoreHtmlNodeRenderer
{
private final HtmlNodeRendererContext _context;

public CommentNodeRenderer(HtmlNodeRendererContext context)
{
super(context);
_context = context;
}

@Override
public Set<Class<? extends Node>> getNodeTypes()
{
return Set.of(HtmlInline.class, HtmlBlock.class);
}

@Override
public void render(Node node)
{
if (node instanceof HtmlInline inline)
{
String literal = inline.getLiteral();
if (isComment(literal))
{
_context.getWriter().raw(literal);
}
else
{
_context.getWriter().text(literal);
}
}
else if (node instanceof HtmlBlock block)
{
String literal = block.getLiteral();
if (isComment(literal))
{
_context.getWriter().raw(literal);
}
else
{
_context.getWriter().tag("p");
_context.getWriter().text(literal);
_context.getWriter().tag("/p");
_context.getWriter().line();
}
}
}

private boolean isComment(String literal)
{
return literal != null && literal.trim().startsWith("<!--") && literal.trim().endsWith("-->");
}
}

@Override
public String toHtml(String mdText)
{
Expand Down
27 changes: 21 additions & 6 deletions core/src/org/labkey/core/wiki/MarkdownTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class MarkdownTestCase extends Assert
@Test
public void testMdHeadingToHtml()
{
MarkdownService markdownService = MarkdownService.get();
MarkdownService markdownService = new MarkdownServiceImpl();
String testMdText = "# This is a H1 header";
String expectedHtmlText = "<div class=\"lk-markdown-container\"><h1 id=\"this-is-a-h1-header\">This is a H1 header</h1>\n</div>";
String htmlText = markdownService.toHtml(testMdText);
Expand All @@ -28,7 +28,7 @@ public void testMdHeadingToHtml()
@Test
public void testMdBoldToHtml()
{
MarkdownService markdownService = MarkdownService.get();
MarkdownService markdownService = new MarkdownServiceImpl();
String testMdText = "**This is bold text**";
String expectedHtmlText = "<div class=\"lk-markdown-container\"><p><strong>This is bold text</strong></p>\n</div>";
String htmlText = markdownService.toHtml(testMdText);
Expand All @@ -41,11 +41,10 @@ public void testMdBoldToHtml()
@Test
public void testMdHtmlTags()
{
MarkdownService markdownService = MarkdownService.get();

MarkdownService markdownService = new MarkdownServiceImpl();
String testMdText = "<h2>header</h2>";
String expectedHtmlText = "<div class=\"lk-markdown-container\"><p>&lt;h2&gt;header&lt;/h2&gt;</p>\n</div>";
String htmlText = markdownService.toHtml(testMdText);
String expectedHtmlText = "<div class=\"lk-markdown-container\"><p>&lt;h2&gt;header&lt;/h2&gt;</p>\n</div>";
assertEquals("The MarkdownService failed to correctly escape html tags.", expectedHtmlText, htmlText);

testMdText = "<script>alert()</script>";
Expand All @@ -60,7 +59,7 @@ public void testMdHtmlTags()
@Test
public void testMdComplexToHtml()
{
MarkdownService markdownService = MarkdownService.get();
MarkdownService markdownService = new MarkdownServiceImpl();
// this sample of markdown and translation taken from part of: https://markdown-it.github.io/
String testMdText = """
---
Expand Down Expand Up @@ -341,4 +340,20 @@ public void testMdComplexToHtml()
String htmlText = markdownService.toHtml(testMdText);
assertEquals("The MarkdownService failed to correctly translate complex markdown text to html.", expectedHtmlText, htmlText);
}
@Test
public void testHtmlComments()
{
MarkdownService markdownService = new MarkdownServiceImpl();

String testMdText = "Text before <!-- comment --> text after";
String htmlText = markdownService.toHtml(testMdText);

assertTrue("Comment was encoded: " + htmlText, htmlText.contains("<!-- comment -->"));
assertFalse("Comment should not be encoded: " + htmlText, htmlText.contains("&lt;!--"));

// Verification for <script> still being encoded
String scriptMd = "<script>alert('hi')</script>";
String scriptHtml = markdownService.toHtml(scriptMd);
assertTrue("Script tags should still be encoded: " + scriptHtml, scriptHtml.contains("&lt;script&gt;"));
}
}
4 changes: 2 additions & 2 deletions issues/src/org/labkey/issue/model/IssueManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ public HttpView getCustomSearchResult(User user, @NotNull String resourceIdentif
return null;
}

final IssueObject issue = getIssue(null, user, issueId);
final IssueObject issue = getIssue(null, user, issueId, false);
if (null == issue)
return null;
Container c = issue.lookupContainer();
Expand Down Expand Up @@ -1305,7 +1305,7 @@ public static WebdavResource resolve(String id)
return null;
}

final IssueObject issue = getIssue(null, User.getSearchUser(), issueId);
final IssueObject issue = getIssue(null, User.getSearchUser(), issueId, false);
if (null == issue)
return null;

Expand Down