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 == """"""
+
+ let input2 = dedent """.. image:: /images/myimage.jpg
+ :target: javascript://bar.com
+ :alt: Alt text for the image"""
+ let output2 = input2.toHtml
+ check output2 == """"""
+
+ let input3 = dedent """.. image:: /images/myimage.jpg
+ :target: bar.com
+ :alt: Alt text for the image"""
+ let output3 = input3.toHtml
+ check output3 == """"""
+
+ test "invalid links":
+ check("(([Nim](https://nim-lang.org/)))".toHtml ==
+ """((Nim))""")
+ check("(([Nim](javascript://nim-lang.org/)))".toHtml ==
+ """((Nim))""")