diff options
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Let character references through to the browser
Decoding them here instead would mean carrying every named reference HTML defines, while the browser already knows them all.
Diffstat (limited to '')
-rw-r--r--custom/extensions/about-render.lua19
1 file changed, 17 insertions, 2 deletions
diff --git a/custom/extensions/about-render.lua b/custom/extensions/about-render.lua
index 3c92252..4e4b50b 100644
--- a/custom/extensions/about-render.lua
+++ b/custom/extensions/about-render.lua
@@ -157,7 +157,8 @@ end
-- The page renders untrusted repository content. Every run of text goes out
-- through cgit's html_txt, every attribute value through html_attr or, for a
-- path in the tree, html_url_path, and every link target through safe_url
--- first. html() only ever gets literal tag scaffolding.
+-- first. html() only ever gets literal tag scaffolding and the character
+-- references whose shape the markdown grammar checked.
local emit_inline
@@ -166,6 +167,8 @@ emit_inline = function(list)
local kind = node.kind
if kind == "text" then
html_txt(node.text)
+ elseif kind == "reference" then
+ html(node.text)
elseif kind == "break" then
html("<br>")
elseif kind == "code" then
@@ -294,7 +297,7 @@ if has_lpeg then
local whitespace = S(" \t\r\n\f\v")
local eol = P(-1)
- local marker = S("`![*_<\\")
+ local marker = S("`![*_<\\&")
local punctuation = S("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")
local url_char = 1 - S(")") - whitespace
-- Bound the link and image inner scans. Without a cap a readme of
@@ -323,6 +326,9 @@ if has_lpeg then
local function node_image()
return { kind = "image" }
end
+ local function node_reference(text)
+ return { kind = "reference", text = text }
+ end
local function node_autolink(url)
return { kind = "link", kids = { node_text(url) }, url = url }
end
@@ -339,6 +345,14 @@ if has_lpeg then
local address = (alnum + S(".!#$%&'*+/=?^_`{|}~-")) ^ 1
* P("@") * alnum * (alnum + S(".-")) ^ 0
+ -- A character reference passes through for the browser to decode,
+ -- within CommonMark's lengths. Its shape leaves no room for markup, and
+ -- a name the browser does not know shows as written.
+ local digit, hex = R("09"), R("09", "af", "AF")
+ local reference = P("&") * (R("az", "AZ") * alnum ^ -31
+ + P("#") * digit * digit ^ -6
+ + P("#") * S("xX") * hex * hex ^ -5) * P(";")
+
local label = P("[") * C((1 - P("]")) ^ (-max_scan)) * P("]")
local target = P("(") * space ^ 0 * C(url_char * url_char ^ (-max_scan))
* (1 - P(")")) ^ (-max_scan) * P(")")
@@ -349,6 +363,7 @@ if has_lpeg then
local inline_grammar = Ct((
(P("`") * C((1 - P("`")) ^ 1) * P("`")) / node_code
+ (P("\\") * C(punctuation)) / node_text
+ + C(reference) / node_reference
+ (P("<") * C(uri) * P(">")) / node_autolink
+ (P("<") * C(address) * P(">")) / node_mail
+ (P("[!") * label * target * P("]") * target) / node_image