diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 2e45bda4ce41..e2f05946136b 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -40,7 +40,7 @@ ## can be done by simply searching for [footnoteName]. import strutils, os, hashes, strtabs, rstast, rst, highlite, tables, sequtils, - algorithm, parseutils, std/strbasics + algorithm, parseutils, std/strbasics, strscans import ../../std/private/since @@ -823,6 +823,16 @@ proc renderOverline(d: PDoc, n: PRstNode, result: var string) = rstnodeToRefname(n).idS, tmp, $chr(n.level - 1 + ord('A')), tocName]) +proc safeProtocol(linkStr: var string) = + var protocol = "" + if scanf(linkStr, "$w:", protocol): + # if it has a protocol at all, ensure that it's not 'javascript:' or worse: + if cmpIgnoreCase(protocol, "http") == 0 or cmpIgnoreCase(protocol, "https") == 0 or + cmpIgnoreCase(protocol, "ftp") == 0: + discard "it's fine" + else: + linkStr = "" + proc renderTocEntry(d: PDoc, e: TocEntry, result: var string) = dispA(d.target, result, "
  • $2
  • \n", @@ -887,6 +897,8 @@ proc renderImage(d: PDoc, n: PRstNode, result: var string) = # support for `:target:` links for images: var target = esc(d.target, getFieldValue(n, "target").strip(), escMode=emUrl) + safeProtocol(target) + if target.len > 0: # `htmlOut` needs to be of the following format for link to work for images: # @@ -1187,6 +1199,7 @@ proc renderHyperlink(d: PDoc, text, link: PRstNode, result: var string, external d.escMode = emUrl renderRstToOut(d, link, linkStr) d.escMode = mode + safeProtocol(linkStr) var textStr = "" renderRstToOut(d, text, textStr) if external: diff --git a/tests/stdlib/trstgen.nim b/tests/stdlib/trstgen.nim index 867677404342..ee499166f6cc 100644 --- a/tests/stdlib/trstgen.nim +++ b/tests/stdlib/trstgen.nim @@ -398,7 +398,7 @@ Some chapter Level2 ------ - + Level3 ~~~~~~ @@ -407,7 +407,7 @@ Some chapter More ~~~~ - + Another ------- @@ -683,7 +683,7 @@ Test1 test "RST line blocks": let input2 = dedent""" Paragraph1 - + | Paragraph2""" @@ -704,7 +704,7 @@ Test1 # check that '| ' with a few spaces is still parsed as new line let input4 = dedent""" | xxx - | + | | zzz""" let output4 = input4.toHtml @@ -1548,3 +1548,30 @@ suite "RST/Code highlight": check strip(rstToHtml(pythonCode, {}, newStringTable(modeCaseSensitive))) == strip(expected) + + +suite "invalid targets": + test "invalid image target": + let input1 = dedent """.. image:: /images/myimage.jpg + :target: https://bar.com + :alt: Alt text for the image""" + let output1 = input1.toHtml + check output1 == """Alt text for the image""" + + let input2 = dedent """.. image:: /images/myimage.jpg + :target: javascript://bar.com + :alt: Alt text for the image""" + let output2 = input2.toHtml + check output2 == """Alt text for the image""" + + let input3 = dedent """.. image:: /images/myimage.jpg + :target: bar.com + :alt: Alt text for the image""" + let output3 = input3.toHtml + check output3 == """Alt text for the image""" + + test "invalid links": + check("(([Nim](https://nim-lang.org/)))".toHtml == + """((Nim))""") + check("(([Nim](javascript://nim-lang.org/)))".toHtml == + """((Nim))""")