diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Leave images and badges out of rendered readmes
A relative image loaded from below the about page, which answers 404
now, and a remote one had every visitor's browser call a third party.
A badge also came out as a link to its own image, wrapped in stray
brackets.
| -rw-r--r-- | custom/extensions/about-render.lua | 49 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | tests/extensions/test-about-render.lua | 13 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 files changed, 35 insertions, 27 deletions
diff --git a/custom/extensions/about-render.lua b/custom/extensions/about-render.lua index a3932af..9d5f72d 100644 --- a/custom/extensions/about-render.lua +++ b/custom/extensions/about-render.lua @@ -156,8 +156,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 or image target through --- safe_url first. html() only ever gets literal tag scaffolding. +-- path in the tree, html_url_path, and every link target through safe_url +-- first. html() only ever gets literal tag scaffolding. local emit_inline @@ -181,19 +181,22 @@ emit_inline = function(list) else emit_inline(node.kids) end - elseif kind == "image" then - local target = safe_url(node.url) - if target then - html("<img src='") - html_attr(target) - html("' alt='") - html_attr(node.alt) - html("'>") - else - html_txt("![" .. node.alt .. "]") + end + end +end + +-- Whether a paragraph has anything to show once images are left out, so a +-- row of badges leaves no empty paragraph behind. +local function shows_something(lines) + for _, line in ipairs(lines) do + for _, node in ipairs(line) do + local blank = node.kind == "text" and not node.text:find("%S") + if node.kind ~= "image" and not blank then + return true end end end + return false end local emit_blocks @@ -248,7 +251,7 @@ emit_blocks = function(blocks) html("</li>") end html("</" .. tag .. ">") - elseif kind == "para" then + elseif kind == "para" and shows_something(block.lines) then html("<p>") for i, line in ipairs(block.lines) do if i > 1 then @@ -310,18 +313,22 @@ if has_lpeg then local function node_link(text, url) return { kind = "link", kids = parse_inline(text), url = url } end - local function node_image(alt, url) - return { kind = "image", alt = alt, url = url } + local function node_image() + return { kind = "image" } end + 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(")") + + -- Images are parsed only to be left out, along with the link around a + -- badge. The about page serves no files for a relative one to load, and + -- a remote one would have every visitor's browser call a third party. local inline_grammar = Ct(( (P("`") * C((1 - P("`")) ^ 1) * P("`")) / node_code - + (P("![") * C((1 - P("]")) ^ (-max_scan)) * P("]") * P("(") - * space ^ 0 * C(url_char * url_char ^ (-max_scan)) - * (1 - P(")")) ^ (-max_scan) * P(")")) / node_image - + (P("[") * C((1 - P("]")) ^ (-max_scan)) * P("]") * P("(") - * space ^ 0 * C(url_char * url_char ^ (-max_scan)) - * (1 - P(")")) ^ (-max_scan) * P(")")) / node_link + + (P("[!") * label * target * P("]") * target) / node_image + + (P("!") * label * target) / node_image + + (label * target) / node_link + (P("**") * C((1 - P("**")) ^ 1) * P("**")) / node_strong + (P("__") * C((1 - P("__")) ^ 1) * P("__")) / node_strong + (P("*") * C((1 - whitespace) * (1 - P("*")) ^ 0) * P("*")) / node_em diff --git a/tests/extensions/test-about-render.lua b/tests/extensions/test-about-render.lua index 4f8b532..801cc45 100644 --- a/tests/extensions/test-about-render.lua +++ b/tests/extensions/test-about-render.lua @@ -159,13 +159,14 @@ h.excludes("a scheme relative link renders no anchor", out, "<a ") out = render("README.md", "[q](https://example.com/a'b)") h.contains("a quote in a link target is escaped", out, "href='https://example.com/a'b'") -out = render("README.md", "") -h.contains("an image renders with its alt text escaped", out, - "<img src='https://example.com/i.png' alt='a & b'>") +out = render("README.md", "an  image") +h.contains("an image is left out", out, "<p>an image</p>") -out = render("README.md", "") -h.excludes("an unsafe image renders no tag", out, "<img") -h.contains("its alt text is kept as text", out, "![alt]") +out = render("README.md", "a [](https://ci.example/) badge") +h.contains("a badge is left out with its link", out, "<p>a badge</p>") + +out = render("README.md", "[](y)\n\n\ntext") +h.contains("a paragraph of badges leaves nothing behind", out, "<div class='markdown'><p>text</p></div>") out = render("README.md", "```lua\nlocal x = 1 < 2\n```\nafter") h.contains("a fenced block carries its language", out, |
