From 1b622d0846dad3a99a1943f5d7cfc47d0b0e7ddc Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Fri, 16 Oct 2026 17:58:29 -1000 Subject: 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. --- custom/extensions/about-render.lua | 49 ++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'custom') 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("")
-				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("") end html("") - elseif kind == "para" then + elseif kind == "para" and shows_something(block.lines) then html("

") 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 -- cgit