diff options
Diffstat (limited to 'custom')
| -rw-r--r-- | custom/cgitrc | 102 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | custom/extensions/about-render.lua | 91 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | custom/extensions/auth-file.lua | 73 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | custom/extensions/auth-inline.lua | 66 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | custom/extensions/email-gravatar.lua | 22 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | custom/extensions/email-libravatar.lua | 19 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | custom/extensions/link-commits.lua | 53 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rw-r--r-- | custom/extensions/syntax-highlight.lua | 67 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rwxr-xr-x | custom/hooks/post-receive.cgit-cache | 7 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
9 files changed, 203 insertions, 297 deletions
diff --git a/custom/cgitrc b/custom/cgitrc index c522b90..8cb1831 100644 --- a/custom/cgitrc +++ b/custom/cgitrc @@ -10,17 +10,13 @@ # list repositories by hand in the per-repository section at the end of this # file. # -# About pages (markdown, man and plain-text readmes) render through the bundled -# about-render.lua about-filter, see the filter section below. Source syntax +# About pages (markdown, man and plain-text readmes) can render through the +# bundled about-render.lua about-filter in the filter section below. Source +# syntax # highlighting is optional and ships as a source-filter there too. # # One key=value pair per line. Lines starting with # are comments. - -## -## Cache -## - # Maximum number of entries in the cgit output cache. A value of 0 disables # caching. Value is an integer. Default is 0. cache-size=0 @@ -44,7 +40,7 @@ cache-summary-ttl=5 cache-scan-ttl=15 # Minutes to cache repo pages requested with a fixed SHA1. A negative value -# never expires. Value is an integer number of minutes. Default is -1. +# keeps the page forever. Value is an integer number of minutes. Default is -1. cache-static-ttl=-1 # Minutes to cache repo pages requested without a fixed SHA1. Value is an @@ -63,11 +59,6 @@ cache-snapshot-ttl=5 # requested. Values are 0 or 1. Default is 0. enable-cache-list=0 - -## -## Site appearance -## - # Heading text on the repository index page. Value is any text. Default is Git # repository browser. #root-title=Git repository browser @@ -84,8 +75,8 @@ enable-cache-list=0 # is one or more [ref]path entries. Default is none. #readme=:README.md -# CSS document urls added to the head of every page. Value is one or more urls. -# Default is /cgit.css. +# CSS document urls added to the head of every page. An empty value disables +# it. Value is one or more urls. Default is /cgit.css. #css=/cgit.css # JavaScript document urls included on every page. An empty value disables it. @@ -133,11 +124,6 @@ embedded=0 # format string taking path and sha1. Default is none. #module-link=/%s/commit/?id=%s - -## -## Repository discovery -## - # Directory scanned for git repositories at parse time. Value is a filesystem # path that may use macros. Default is none. #scan-path=/var/lib/git @@ -184,11 +170,6 @@ enable-git-config=0 # filesystem path that may use macros. Default is none. #include=/etc/cgitrc.d/extra - -## -## Features -## - # Provide a blame page for files and links to it. Values are 0 or 1. Default is # 0. enable-blame=0 @@ -251,13 +232,9 @@ enable-tree-group-dirs=0 # year. Default is unset. #max-stats=year - -## -## Snapshots and cloning -## - -# Default set of snapshot archive formats to offer. Value is a space list of tar -# tar.gz tar.bz2 tar.lz tar.xz tar.zst zip, or the word all. Default is none. +# Default set of snapshot archive formats to offer. Value is a space-separated +# list of tar tar.gz tar.bz2 tar.lz tar.xz tar.zst zip, or the word all. Default +# is none. #snapshots=tar.gz tar.xz zip # Act as a dumb HTTP endpoint for git clones. Values are 0 or 1. Default is 1. @@ -272,15 +249,10 @@ enable-http-clone=1 # space-separated url templates that may use macros. Default is none. #clone-url=https://example.com/$CGIT_REPO_URL git://example.com/$CGIT_REPO_URL - -## -## Filters -## -# # A filter is an external command cgit runs to transform a piece of content. # Prefix the command with lua: to run it through the built-in Lua interpreter, # which avoids a fork per call, or with exec: to run a normal program. The -# commands below that point at /usr/share/cgit/extensions/ use scripts this +# commands below that point at /usr/local/lib/cgit/filters/ use scripts this # repository ships under custom/extensions/. The ones written as # /path/to/your-command mark where your own command goes. @@ -291,36 +263,29 @@ enable-filter-overrides=0 # Filter command used to format about-page content. The bundled about-render.lua # renders markdown, man pages and plain text. Value is a command optionally # prefixed with exec or lua. Default is none. -#about-filter=lua:/usr/share/cgit/extensions/about-render.lua +#about-filter=lua:/usr/local/lib/cgit/filters/about-render.lua # Filter command used to format commit messages, for example to turn object # names and issue numbers into links. Value is a command optionally prefixed # with exec or lua. Default is none. -#commit-filter=lua:/usr/share/cgit/extensions/link-commits.lua +#commit-filter=lua:/usr/local/lib/cgit/filters/link-commits.lua # Filter command used to format author and committer emails, for example to add # avatar images. Value is a command optionally prefixed with exec or lua. # Default is none. -#email-filter=lua:/usr/share/cgit/extensions/email-gravatar.lua +#email-filter=lua:/usr/local/lib/cgit/filters/email-gravatar.lua -# Filter command used to format plaintext blobs in the tree view. Without it -# cgit serves the text plain. For syntax highlighting, the shipped filter below -# uses the Scintillua lexers and needs the lpeg module installed too, on Debian -# that is "apt install lua-lpeg". Missing either dependency means plain -# uncolored text, not an error. See the comments in that file. Value is a -# command optionally prefixed with exec or lua. Default is none. -#source-filter=lua:/usr/share/cgit/extensions/syntax-highlight.lua +# Filter command used to format plaintext blobs in the tree view. The shipped +# filter uses the Scintillua lexers and needs lpeg, and missing either means +# plain uncolored text, not an error. +# Value is a command optionally prefixed with exec or lua. Default is none. +#source-filter=lua:/usr/local/lib/cgit/filters/syntax-highlight.lua # Filter command invoked to authenticate access, gating repositories behind a # login. See custom/extensions/auth-inline.lua and # custom/extensions/auth-file.lua. Value is a command optionally prefixed with # exec or lua. Default is none. -#auth-filter=lua:/usr/share/cgit/extensions/auth-inline.lua - - -## -## Limits and safety -## +#auth-filter=lua:/usr/local/lib/cgit/filters/auth-inline.lua # Number of items to display in atom feeds. Value is an integer. Default is 10. max-atom-items=10 @@ -337,7 +302,7 @@ max-repodesc-length=80 # value of 0 disables the limit. Value is an integer. Default is 10240. max-blob-size=10240 -# Number of repos listed per page on the index. A value of 0 or negative shows +# Number of repos listed per page on the index. Zero or a negative value shows # all repos. Value is an integer. Default is 50. max-repo-count=50 @@ -369,11 +334,6 @@ max-ref-count=200 # compile-time value. Value is an integer. Default is -1. rename-limit=-1 - -## -## Presentation -## - # Number of log entries shown in the summary view. Value is an integer. Default # is 10. summary-log=10 @@ -408,8 +368,8 @@ branch-sort=name # Sort items in the repo list case-sensitively. Values are 0 or 1. Default is 1. case-sensitive-sort=1 -# Show full author email addresses beside names. Set to 0 to hide them. Values -# are 0 or 1. Default is 1. +# Show full author email addresses beside names. Values are 0 or 1. Default is +# 1. enable-plain-email=1 # File giving the timestamp of the youngest commit. Value is a path relative to @@ -429,16 +389,10 @@ enable-plain-email=1 #mimetype.png=image/png #mimetype.svg=image/svg+xml - -## -## Per-repository overrides -## -# -# Each repository is introduced by a repo.url line, which must be the first -# setting of the block. All following repo.* settings apply to that repo until -# the next repo.url line. When repos are discovered via scan-path the repo. -# prefix is dropped inside each repo cgitrc and repo.url and repo.path are not -# allowed there. +# Each repository is introduced by a repo.url line. All following repo.* +# settings apply to that repo until the next repo.url line. When repos are +# discovered via scan-path the repo. prefix is dropped inside each repo cgitrc +# and repo.url and repo.path are not allowed there. # Relative url for a repo. Must be the first setting of each repo block. Value # is a relative url path. Default is none. @@ -566,7 +520,7 @@ enable-plain-email=1 # Per-repo override of the commit-filter. Only honoured when # enable-filter-overrides is 1. Value is a command. Default is the global # commit-filter value. -#repo.commit-filter=lua:/usr/share/cgit/extensions/link-commits.lua +#repo.commit-filter=lua:/usr/local/lib/cgit/filters/link-commits.lua # Per-repo override of the source-filter. Only honoured when # enable-filter-overrides is 1. Value is a command. Default is the global @@ -576,4 +530,4 @@ enable-plain-email=1 # Per-repo override of the email-filter. Only honoured when # enable-filter-overrides is 1. Value is a command. Default is the global # email-filter value. -#repo.email-filter=lua:/usr/share/cgit/extensions/email-gravatar.lua +#repo.email-filter=lua:/usr/local/lib/cgit/filters/email-gravatar.lua diff --git a/custom/extensions/about-render.lua b/custom/extensions/about-render.lua index ea13746..f4e7685 100644 --- a/custom/extensions/about-render.lua +++ b/custom/extensions/about-render.lua @@ -1,20 +1,15 @@ -- Server-side rendering of a repository's about page, named by the -- about-filter setting in cgitrc and run inside cgit's embedded Lua --- interpreter so a readme costs no extra process per request. --- Markdown, man pages and plain text are the three formats, chosen from the --- readme's file extension, and anything that fails to parse falls back to --- escaped plain text. Adding a format takes a render function and a row in --- the handler table at the foot of this file, and nothing else. The wrappers --- it emits carry the classes that assets/cgit.css styles. It runs on Lua 5.1 --- through 5.4 and LuaJIT. +-- interpreter so a readme costs no extra process per request. Markdown, man +-- pages and plain text are the three formats, chosen from the readme's file +-- extension, and anything that fails to parse falls back to escaped plain +-- text. The wrappers it emits carry the classes that assets/cgit.css styles. +-- It runs on Lua 5.1 through 5.4 and LuaJIT. -- --- about-filter=lua:/usr/lib/cgit/filters/about-render.lua +-- about-filter=lua:/usr/local/lib/cgit/filters/about-render.lua --- Markdown and man pages are parsed with lpeg grammars, so where the parsing --- module is missing both fall back to escaped plain text and only plain text --- still renders. It has to be built for the Lua cgit is linked against. --- cgit's syntax highlighter needs it too, so a cgit that colours source --- already has it. +-- Markdown and man pages need lpeg, built for the Lua cgit is linked +-- against. Without it both fall back to escaped plain text. -- -- # Debian and Ubuntu -- sudo apt install lua-lpeg @@ -42,9 +37,8 @@ local function trim(text) return (text:gsub("^%s+", ""):gsub("%s+$", "")) end --- Split on newlines after normalising CRLF and CR, returning the lines --- without their terminators. A trailing newline yields a final empty line, --- which every caller treats as blank. +-- Normalise CRLF and CR to newlines, then split. A trailing newline yields +-- a final empty line, which every caller treats as blank. local function split_lines(text) text = text:gsub("\r\n?", "\n") local lines, start = {}, 1 @@ -59,8 +53,6 @@ local function split_lines(text) end end --- Split a table row into trimmed cells, dropping one optional leading and one --- optional trailing pipe. local function split_cells(row) row = trim(row):gsub("^|", ""):gsub("|$", "") local cells = {} @@ -70,11 +62,10 @@ local function split_cells(row) return cells end --- Return the URL if its scheme is safe, else nil. Control and whitespace --- bytes are stripped anywhere first because a browser ignores them when --- resolving the scheme, so "java\nscript:" must still be caught as --- javascript. The class is %c%s rather than a literal 0x00 range so it is --- safe on Lua 5.1, where an embedded zero byte ends a pattern. +-- Control and whitespace bytes are stripped before the scheme check because +-- a browser ignores them when resolving it, so "java\nscript:" must still be +-- caught as javascript. The class is %c%s rather than a literal 0x00 range +-- so it is safe on Lua 5.1, where an embedded zero byte ends a pattern. local function safe_url(url) url = url:gsub("[%c%s]", "") -- A leading "//" or "/\" is scheme-relative, which a browser @@ -94,14 +85,10 @@ local function safe_url(url) end --- The about page renders untrusted repository content, so the rule the two --- functions below keep is that every run of text reaches the page through --- cgit's own html_txt, every attribute value through html_attr, and every --- link or image target through safe_url before html_attr. Those three come --- from cgit's Lua filter host rather than from here, and the only thing --- passed to html is literal tag scaffolding. Because all output is routed --- through those sinks by construction, a bug in the parser can only --- mis-render, never inject markup or a URL with a javascript scheme. +-- The page renders untrusted repository content. Every run of text goes out +-- through cgit's html_txt, every attribute value through html_attr, and +-- every link or image target through safe_url before html_attr. html() only +-- ever gets literal tag scaffolding. local emit_inline @@ -198,16 +185,12 @@ local function render_plaintext(text) end --- Markdown here is a deliberate subset rather than CommonMark, covering --- headings, thematic breaks, fenced and inline code, blockquotes, pipe --- tables, single-level lists, links, images and emphasis, and leaving out --- reference links, raw HTML passthrough, nested lists and setext headings. --- Emphasis does not span a hard line break inside a paragraph. Man rendering --- covers the common macros, that is section headings, filled and no-fill --- paragraphs, bold and italic and the font escapes, and drops the rest. Both --- are parsed with lpeg into the node trees emit_blocks and emit_inline above --- consume, and parsing only builds a tree, so a parse that fails falls back --- to plain text without leaving half a page behind. +-- Markdown is a deliberate subset rather than CommonMark, leaving out +-- reference links, raw HTML passthrough, nested lists and setext headings, +-- and emphasis does not span a hard line break. Man rendering covers the +-- common macros and drops the rest. Both parse into a node tree before +-- anything is emitted, so a failed parse falls back to plain text without +-- leaving half a page behind. local render_markdown, render_man @@ -223,8 +206,6 @@ if has_lpeg then -- Bound the link and image inner scans. Without a cap a readme of -- unclosed brackets ("[[[[...") makes every position scan to the -- end of the line for a "]" that never comes, which is quadratic. - -- Real link text and urls sit far under this, and anything longer - -- simply renders as plain text. local max_scan = 512 local parse_inline @@ -275,8 +256,6 @@ if has_lpeg then return nodes end - -- Line matchers. Each is anchored at the start of a single line and - -- returns its captures, or nil when the line is not of that kind. local lang_char = R("az", "AZ", "09") + S("_.+#-") local heading_line = C(P("#") * P("#") ^ -5) * space ^ 1 * C(P(1) ^ 0) local function thematic(mark) @@ -434,20 +413,24 @@ if has_lpeg then html("</div>") end - -- Macro lines are matched with lpeg, and the roff inline font and - -- character escapes are a grammar producing a flat token list that - -- a fold turns into the same inline nodes markdown emits. Bold and - -- italic are the current font, which carries across a run rather - -- than being opened and closed, so the inline pass tokenises and - -- folds instead of nesting the way markdown does. + -- Roff fonts are a current state carried across a run rather than + -- opened and closed, so the inline pass tokenises to a flat list + -- and folds it into the nodes markdown emits, instead of nesting. local macro_line = S(".'") * space ^ 0 * C((1 - space) ^ 1) * space ^ 0 * C(P(1) ^ 0) local one_font = { B = "B", I = "I" } local two_font = { CB = "B", BI = "B", CI = "I" } local man_chars = { - aq = "'", cq = "'", oq = "'", dq = '"', lq = '"', rq = '"', - hy = "-", en = "-", em = "-", + aq = "'", + cq = "'", + oq = "'", + dq = '"', + lq = '"', + rq = '"', + hy = "-", + en = "-", + em = "-", } local backslash = P("\\") local function font_token(name) return { kind = "font", font = name } end @@ -610,7 +593,7 @@ function filter_write(str) end -- cgit takes filter output through a C string sink that stops at the first --- NUL byte, so a readme holding one is truncated there. +-- NUL byte, so a write holding one loses everything from the NUL on. function filter_close() local text = table.concat(chunks) chunks = {} diff --git a/custom/extensions/auth-file.lua b/custom/extensions/auth-file.lua index 74a04b6..957bd49 100644 --- a/custom/extensions/auth-file.lua +++ b/custom/extensions/auth-file.lua @@ -11,11 +11,9 @@ -- be the same Lua that cgit was built against. Lua 5.5 will not do, because -- luaossl has no 5.5 build. -- --- Serve cgit over HTTPS and terminate TLS in the web server in front of it. --- The session cookie is marked Secure by default, so a browser only sends it --- back over HTTPS, and on an instance served over plain HTTP with no TLS --- anywhere the cookie never comes back and login appears to loop until --- cookie_insecure below is set. +-- The session cookie is marked Secure by default, so a browser only sends +-- it back over HTTPS. On an instance served over plain HTTP login loops +-- until cookie_insecure below is set. -- -- Two libraries are needed. luaossl provides openssl.rand and openssl.hmac and -- lives at <https://github.com/wahern/luaossl>, and luaposix provides @@ -42,16 +40,10 @@ -- luarocks install luaossl OPENSSL_DIR="$(brew --prefix openssl)" -- luarocks install luaposix -- --- Some distributions package both as well, for example lua-luaossl and --- lua-posix on Debian, and such a package has to be built for the same Lua --- version as cgit. --- --- The cookie carries only a user name and there is no server-side session --- store, so deleting an account does not revoke a cookie already issued until --- it expires, and instances that share a secret file accept each other's --- cookies. The login form carries no CSRF token. Both are acceptable for --- gating read access to a git browser, so weigh them before guarding anything --- more sensitive. +-- There is no server-side session store and no CSRF token, so a deleted +-- account's cookie stays valid until it expires and instances sharing a +-- secret file accept each other's cookies. That is acceptable for gating +-- read access to a git browser, so weigh it before guarding anything more. local sysstat = require("posix.sys.stat") local unistd = require("posix.unistd") @@ -59,7 +51,6 @@ local rand = require("openssl.rand") local hmac = require("openssl.hmac") -- The values that follow are the configuration and are meant to be edited. --- Nothing below them needs changing for ordinary use. -- Accounts live one per line as username:hash. Generate a hash with -- mkpasswd -m sha-512 -R 300000 @@ -73,7 +64,7 @@ local groups_filename = "/etc/cgit-auth/groups" -- Per-repository access lives one per line as reponame:group1,group2 and so -- on. A repository named here is protected and one that is not named is -- public. The repository name has to match exactly, while group and user names --- match whatever their case. +-- match regardless of case. local repos_filename = "/etc/cgit-auth/repos" -- Where the cookie-signing secret is stored, created on first use. It must be @@ -91,8 +82,7 @@ local cookie_name = "cgitauth" -- more tightly. local cookie_path = "/" --- Leave this false so the cookie is marked Secure and only travels over HTTPS. --- Set it true only if cgit is served over plain HTTP with no TLS anywhere. +-- Set this true only if cgit is served over plain HTTP with no TLS anywhere. local cookie_insecure = false -- A throwaway hash of the documented shape, used only to spend the same work @@ -104,9 +94,8 @@ local dummy_hash = "$6$rounds=300000$0000000000000000$" -- open decodes is kept here for the calls that follow. local action, http, cgit, post --- The two lookups below, account_hash and repo_userset, are the only part of --- this script that differs from auth-inline.lua. Replacing them is all it --- takes to keep accounts somewhere else. +-- The two lookups below, account_hash and repo_userset, are the only part +-- of this script that differs from auth-inline.lua. local function trim(s) return (string.gsub(s, "^%s*(.-)%s*$", "%1")) @@ -118,14 +107,12 @@ local function add_names(list, set) end end --- A missing or unreadable users file is not fatal, and neither is a line that --- does not parse, so a broken file turns every login down rather than failing --- the request outright. +-- A missing, unreadable or unparsable users file turns every login down +-- rather than failing the request outright. -- --- The hash is trimmed as well as the name because reading by line strips the --- newline but not a carriage return, so a users file saved with CRLF endings --- would otherwise hand crypt a hash with a trailing \r and fail every login --- with nothing in the log to say why. +-- The hash is trimmed as well as the name because reading by line strips +-- the newline but not a carriage return, so a CRLF users file would hand +-- crypt a hash with a trailing \r and fail every login. function account_hash(user) if user == nil then return nil @@ -224,14 +211,9 @@ local function pattern_escape(s) return (string.gsub(s, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1")) end --- The stored token was already URL encoded by secure_value, so it comes back --- verbatim and the write path in set_cookie stays symmetric with this read --- path. Decoding it here would break the signature check for any value --- carrying a percent escape. --- --- The name is escaped because it lands in a pattern. A cookie_name holding a --- magic character, say "cgit-auth", would otherwise read as a pattern and stop --- matching its own cookie while matching names nobody configured. +-- The token comes back still URL encoded by secure_value. Decoding it here +-- would break the signature check for any value carrying a percent escape. +-- The name is escaped because it lands in a Lua pattern. function get_cookie(cookies, name) cookies = string.gsub(";" .. (cookies or "") .. ";", "%s*;%s*", ";") return string.match(cookies, ";" .. pattern_escape(name) .. "=(.-);") @@ -516,18 +498,21 @@ function body() html_attr(secure_value("redirect", target, 0)) html("'>") html("<table>") - html("<tr><td><label for='username'>Username:</label></td><td><input id='username' name='username' autocomplete='username' autofocus></td></tr>") - html("<tr><td><label for='password'>Password:</label></td><td><input id='password' name='password' type='password' autocomplete='current-password'></td></tr>") - html("<tr><td colspan='2'><input value='Login' type='submit'></td></tr>") + html("<tr><td><label for='username'>Username:</label></td><td>") + html("<input id='username' name='username'") + html(" autocomplete='username' autofocus></td></tr>") + html("<tr><td><label for='password'>Password:</label></td><td>") + html("<input id='password' name='password' type='password'") + html(" autocomplete='current-password'></td></tr>") + html("<tr><td colspan='2'>") + html("<input value='Login' type='submit'></td></tr>") html("</table></form>") return 0 end --- cgit calls filter_open with the action name followed by the request fields --- in a fixed order, so they are unpacked here into the tables the functions --- above read. Only a post reaches filter_write, carrying the form body, and --- filter_close is where the action finally runs and answers cgit. +-- filter_open unpacks the action and request fields cgit passes in fixed +-- order, filter_write collects a post body, and filter_close runs the action. local actions = {} actions["authenticate-post"] = authenticate_post diff --git a/custom/extensions/auth-inline.lua b/custom/extensions/auth-inline.lua index aa4b9f1..5489189 100644 --- a/custom/extensions/auth-inline.lua +++ b/custom/extensions/auth-inline.lua @@ -11,11 +11,9 @@ -- be the same Lua that cgit was built against. Lua 5.5 will not do, because -- luaossl has no 5.5 build. -- --- Serve cgit over HTTPS and terminate TLS in the web server in front of it. --- The session cookie is marked Secure by default, so a browser only sends it --- back over HTTPS, and on an instance served over plain HTTP with no TLS --- anywhere the cookie never comes back and login appears to loop until --- cookie_insecure below is set. +-- The session cookie is marked Secure by default, so a browser only sends +-- it back over HTTPS. On an instance served over plain HTTP login loops +-- until cookie_insecure below is set. -- -- Two libraries are needed. luaossl provides openssl.rand and openssl.hmac and -- lives at <https://github.com/wahern/luaossl>, and luaposix provides @@ -42,16 +40,10 @@ -- luarocks install luaossl OPENSSL_DIR="$(brew --prefix openssl)" -- luarocks install luaposix -- --- Some distributions package both as well, for example lua-luaossl and --- lua-posix on Debian, and such a package has to be built for the same Lua --- version as cgit. --- --- The cookie carries only a user name and there is no server-side session --- store, so deleting an account does not revoke a cookie already issued until --- it expires, and instances that share a secret file accept each other's --- cookies. The login form carries no CSRF token. Both are acceptable for --- gating read access to a git browser, so weigh them before guarding anything --- more sensitive. +-- There is no server-side session store and no CSRF token, so a deleted +-- account's cookie stays valid until it expires and instances sharing a +-- secret file accept each other's cookies. That is acceptable for gating +-- read access to a git browser, so weigh it before guarding anything more. local sysstat = require("posix.sys.stat") local unistd = require("posix.unistd") @@ -59,13 +51,11 @@ local rand = require("openssl.rand") local hmac = require("openssl.hmac") -- The values that follow are the configuration and are meant to be edited. --- Nothing below them needs changing for ordinary use. -- Protected repositories and the users allowed into each. A repository named -- here is protected and one that is not named is public. The repository key --- has to match exactly, while user names match whatever their case. Replace --- the examples below with your own. They are commented out, so an unedited --- copy protects nothing and grants no accounts. +-- has to match exactly, while user names match regardless of case. The +-- examples are commented out, so an unedited copy protects nothing. local protected_repos = { -- ["secret-repo"] = { alice = true, bob = true }, -- ["another"] = { alice = true }, @@ -73,8 +63,6 @@ local protected_repos = { -- Accounts as name and hash. Generate a hash with -- mkpasswd -m sha-512 -R 300000 --- Replace the examples below. They are not real credentials and must not be --- deployed as they stand. local users = { -- alice = "$6$rounds=300000$REPLACE_THIS_SALT$REPLACE_THIS_HASH", -- bob = "$6$rounds=300000$REPLACE_THIS_SALT$REPLACE_THIS_HASH", @@ -95,8 +83,7 @@ local cookie_name = "cgitauth" -- more tightly. local cookie_path = "/" --- Leave this false so the cookie is marked Secure and only travels over HTTPS. --- Set it true only if cgit is served over plain HTTP with no TLS anywhere. +-- Set this true only if cgit is served over plain HTTP with no TLS anywhere. local cookie_insecure = false -- A throwaway hash of the documented shape, used only to spend the same work @@ -108,9 +95,8 @@ local dummy_hash = "$6$rounds=300000$0000000000000000$" -- open decodes is kept here for the calls that follow. local action, http, cgit, post --- The two lookups below, account_hash and repo_userset, are the only part of --- this script that differs from auth-file.lua. Replacing them is all it takes --- to keep accounts somewhere else. +-- The two lookups below, account_hash and repo_userset, are the only part +-- of this script that differs from auth-file.lua. -- The configured tables are folded to lowercased user names once, so that a -- lookup matches whatever case the login form was filled in with, the way @@ -186,14 +172,9 @@ local function pattern_escape(s) return (string.gsub(s, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1")) end --- The stored token was already URL encoded by secure_value, so it comes back --- verbatim and the write path in set_cookie stays symmetric with this read --- path. Decoding it here would break the signature check for any value --- carrying a percent escape. --- --- The name is escaped because it lands in a pattern. A cookie_name holding a --- magic character, say "cgit-auth", would otherwise read as a pattern and stop --- matching its own cookie while matching names nobody configured. +-- The token comes back still URL encoded by secure_value. Decoding it here +-- would break the signature check for any value carrying a percent escape. +-- The name is escaped because it lands in a Lua pattern. function get_cookie(cookies, name) cookies = string.gsub(";" .. (cookies or "") .. ";", "%s*;%s*", ";") return string.match(cookies, ";" .. pattern_escape(name) .. "=(.-);") @@ -478,18 +459,21 @@ function body() html_attr(secure_value("redirect", target, 0)) html("'>") html("<table>") - html("<tr><td><label for='username'>Username:</label></td><td><input id='username' name='username' autocomplete='username' autofocus></td></tr>") - html("<tr><td><label for='password'>Password:</label></td><td><input id='password' name='password' type='password' autocomplete='current-password'></td></tr>") - html("<tr><td colspan='2'><input value='Login' type='submit'></td></tr>") + html("<tr><td><label for='username'>Username:</label></td><td>") + html("<input id='username' name='username'") + html(" autocomplete='username' autofocus></td></tr>") + html("<tr><td><label for='password'>Password:</label></td><td>") + html("<input id='password' name='password' type='password'") + html(" autocomplete='current-password'></td></tr>") + html("<tr><td colspan='2'>") + html("<input value='Login' type='submit'></td></tr>") html("</table></form>") return 0 end --- cgit calls filter_open with the action name followed by the request fields --- in a fixed order, so they are unpacked here into the tables the functions --- above read. Only a post reaches filter_write, carrying the form body, and --- filter_close is where the action finally runs and answers cgit. +-- filter_open unpacks the action and request fields cgit passes in fixed +-- order, filter_write collects a post body, and filter_close runs the action. local actions = {} actions["authenticate-post"] = authenticate_post diff --git a/custom/extensions/email-gravatar.lua b/custom/extensions/email-gravatar.lua index 85947c4..6eb5376 100644 --- a/custom/extensions/email-gravatar.lua +++ b/custom/extensions/email-gravatar.lua @@ -27,29 +27,25 @@ -- luarocks install luaossl OPENSSL_DIR="$(brew --prefix openssl)" -- -- Every page view sends the visitor's IP address and a hash of each --- committer's email to a third-party service, so leave this filter off if that --- is not acceptable for your instance. Addresses are hashed with MD5, which --- Gravatar still accepts. Gravatar also supports SHA-256 now, so change the --- digest in hash_hex if you prefer it. +-- committer's email to a third-party service, so leave this filter off if +-- that is not acceptable for your instance. Addresses are hashed with MD5, +-- which Gravatar still accepts. local digest = require("openssl.digest") --- These are the values to change. The size is in pixels and serves both as the --- image asked of the service and as the width and height attributes. The --- default image is the style Gravatar draws for an address it has never seen, --- and its documented choices include retro, identicon, monsterid and mp. The --- endpoint is https so the icon is not blocked as mixed content on an https --- page. +-- The size is in pixels and serves both as the image asked of the service +-- and as the width and height attributes. The default image is what +-- Gravatar draws for an address it has never seen. The endpoint is https so +-- the icon is not blocked as mixed content on an https page. local avatar_size = 13 local default_image = "retro" local base_url = "https://www.gravatar.com/avatar/" local alt_text = "Gravatar" --- cgit calls filter_open once, then filter_write for each piece of the name, --- then filter_close, so what one call works out has to be left here for the --- next one. +-- One name reaches this filter as an open, writes and a close, so what the +-- open works out is kept here for the close. local buffer = "" local avatar_hash = nil diff --git a/custom/extensions/email-libravatar.lua b/custom/extensions/email-libravatar.lua index e958346..9b3d595 100644 --- a/custom/extensions/email-libravatar.lua +++ b/custom/extensions/email-libravatar.lua @@ -26,27 +26,24 @@ -- luarocks install luaossl OPENSSL_DIR="$(brew --prefix openssl)" -- -- Every page view sends the visitor's IP address and a hash of each --- committer's email to a third-party service, so leave this filter off if that --- is not acceptable for your instance. Addresses are hashed with MD5. +-- committer's email to a third-party service, so leave this filter off if +-- that is not acceptable for your instance. Addresses are hashed with MD5. local digest = require("openssl.digest") --- These are the values to change. The size is in pixels and serves both as the --- image asked of the service and as the width and height attributes. The --- default image is the style Libravatar draws for an address it has never --- seen, and its documented choices include retro, identicon, monsterid and mm. --- The endpoint is the secure CDN so the icon loads over https and is not --- blocked as mixed content on an https page. +-- The size is in pixels and serves both as the image asked of the service +-- and as the width and height attributes. The default image is what +-- Libravatar draws for an address it has never seen. The endpoint is the +-- secure CDN so the icon is not blocked as mixed content on an https page. local avatar_size = 13 local default_image = "retro" local base_url = "https://seccdn.libravatar.org/avatar/" local alt_text = "Libravatar" --- cgit calls filter_open once, then filter_write for each piece of the name, --- then filter_close, so what one call works out has to be left here for the --- next one. +-- One name reaches this filter as an open, writes and a close, so what the +-- open works out is kept here for the close. local buffer = "" local avatar_hash = nil diff --git a/custom/extensions/link-commits.lua b/custom/extensions/link-commits.lua index 3f2429d..42252f3 100644 --- a/custom/extensions/link-commits.lua +++ b/custom/extensions/link-commits.lua @@ -10,12 +10,10 @@ -- Object names are handled apart from the rules below because the length --- bound on them cannot be written as a plain Lua pattern. Recognition is by --- shape, since a commit-filter cannot ask the repository whether a hash is --- real, so any hex run within the bounds is linked whatever mix of digits and --- letters it has and abbreviated and all-digit names are both caught. The --- cost is that a long hex-looking number now and then links to an object that --- does not exist, which cgit renders as a harmless "bad object name" page. +-- bound on them cannot be written as a plain Lua pattern. A commit-filter +-- cannot ask the repository whether a hash is real, so matching is by shape +-- and a long hex number may link to an object that does not exist, which +-- cgit renders as a harmless "Bad object id" page. local objects = { -- Set false to stop linking bare hashes. enabled = true, @@ -32,24 +30,23 @@ local objects = { -- Text-reference rules, each one a Lua pattern with a single capture and a -- URL where %s is replaced by that capture, percent-encoded. The whole match -- is what gets shown and the capture is only what goes into the URL. Rules are --- tried in order and the leftmost match on the line wins, so put the more --- specific patterns first, and an empty list leaves only object names linked. +-- tried in order and the leftmost match wins, so put the more specific +-- patterns first, and an empty list leaves only object names linked. -- --- Lua patterns are not regular expressions. There is no alternation and no --- {n,m} repetition, %d is a digit, %a a letter, %w a letter or digit, %x a --- hex digit, and a literal magic character is escaped with %, so a literal --- dash is '%-'. The whole set is in the reference manual at +-- Lua patterns are not regular expressions. The reference is -- https://www.lua.org/manual/5.1/manual.html#5.4.1 -- --- Patterns run against the escaped message, so '&', '<' and '>' reach them as --- '&', '<' and '>'. Match those entity spellings rather than the --- bare character, and keep a pattern from ending part way through one, since --- the matched run is what gets wrapped in the anchor. +-- Patterns run against the escaped message, so match the entity spellings +-- '&', '<' and '>' rather than the bare characters, and keep a +-- pattern from ending part way through one. local rules = { { pattern = "#(%d+)", url = "https://bugs.example.com/?bug=%s" }, - -- { pattern = "CVE%-(%d%d%d%d%-%d+)", url = "https://www.cve.org/CVERecord?id=CVE-%s" }, - -- { pattern = "!(%d+)", url = "https://gitlab.example.com/group/repo/-/merge_requests/%s" }, - -- { pattern = "RFC%s?(%d+)", url = "https://www.rfc-editor.org/rfc/rfc%s" }, + -- { pattern = "CVE%-(%d%d%d%d%-%d+)", + -- url = "https://www.cve.org/CVERecord?id=CVE-%s" }, + -- { pattern = "!(%d+)", + -- url = "https://gitlab.example.com/my/repo/-/merge_requests/%s" }, + -- { pattern = "RFC%s?(%d+)", + -- url = "https://www.rfc-editor.org/rfc/rfc%s" }, } @@ -68,7 +65,9 @@ end -- for a gsub reference. local function make_link(url_template, capture, display) local encoded = url_encode(capture) - local href = string.gsub(url_template, "%%s", function() return encoded end) + local href = string.gsub(url_template, "%%s", function() + return encoded + end) return "<a href='" .. href .. "'>" .. display .. "</a>" end @@ -89,7 +88,9 @@ local function collect(text) capture = string.sub(text, start, stop) end candidates[#candidates + 1] = { - start = start, stop = stop, priority = priority, + start = start, + stop = stop, + priority = priority, link = make_link(rule.url, capture, string.sub(text, start, stop)), } @@ -106,9 +107,12 @@ local function collect(text) local start, stop, run = string.find(text, "%f[%w](%x+)%f[%W]", init) if not start then break end - if #run >= objects.min_length and #run <= objects.max_length then + if #run >= objects.min_length + and #run <= objects.max_length then candidates[#candidates + 1] = { - start = start, stop = stop, priority = priority, + start = start, + stop = stop, + priority = priority, link = make_link(objects.url, run, run), } end @@ -141,7 +145,8 @@ function filter_close() -- A candidate reaching back into one already emitted is -- dropped, so no run of text is ever wrapped twice. if candidate.start >= pos then - out[#out + 1] = string.sub(text, pos, candidate.start - 1) + out[#out + 1] = + string.sub(text, pos, candidate.start - 1) out[#out + 1] = candidate.link pos = candidate.stop + 1 end diff --git a/custom/extensions/syntax-highlight.lua b/custom/extensions/syntax-highlight.lua index 862965a..e2032aa 100644 --- a/custom/extensions/syntax-highlight.lua +++ b/custom/extensions/syntax-highlight.lua @@ -1,16 +1,13 @@ --- Server-side syntax highlighting for cgit's tree and blob views, run inside --- cgit's embedded Lua interpreter so a coloured blob costs no extra process --- per request. Colouring is deliberately left out of cgit itself, which --- serves plain escaped text on its own, so this filter is named by the --- source-filter setting and any other program could take its place. Tokens --- come from the Scintillua lexers and reach the page wrapped in span elements --- carrying the hl- classes that assets/cgit.css styles. Whenever a piece is --- missing or will not load, from lpeg down to a single lexer, the file falls --- back to plain escaped text instead of failing, so uncoloured code means a --- missing dependency rather than an error. It runs on Lua 5.1 through 5.5 and +-- Server-side syntax highlighting for cgit's tree and blob views, named by +-- the source-filter setting and run inside cgit's embedded Lua interpreter +-- so a coloured blob costs no extra process per request. Tokens come from the +-- Scintillua lexers and reach the page wrapped in span elements carrying the +-- hl- classes that assets/cgit.css styles. Whenever a piece is missing or +-- will not load, from lpeg down to a single lexer, the filter falls back to +-- plain escaped text instead of failing. It runs on Lua 5.1 through 5.5 and -- LuaJIT. -- --- source-filter=lua:/usr/lib/cgit/extensions/syntax-highlight.lua +-- source-filter=lua:/usr/local/lib/cgit/filters/syntax-highlight.lua -- Files larger than this many bytes are served escaped but unhighlighted, so @@ -28,12 +25,10 @@ local scintillua_env = "CGIT_SCINTILLUA_PATH" -- Directories probed for the lexers when that variable is not set, tried -- after the directory of $CGIT_CONFIG, so placing or symlinking a scintillua --- directory next to cgitrc is enough to be found. Scintillua is the lexer --- collection from the Textadept editor, around 160 languages as plain .lua --- files with nothing to compile, from --- https://orbitalquark.github.io/scintillua/. It does not bundle lpeg, which --- it needs and which has to be built for the Lua cgit is linked against, and --- forgetting that is the usual reason nothing is coloured. +-- directory next to cgitrc is enough for it to be found. The lexers come +-- from https://orbitalquark.github.io/scintillua/ and need lpeg, built for +-- the Lua cgit is linked against. Forgetting that is the usual reason +-- nothing is coloured. -- -- # Debian and Ubuntu -- sudo apt install lua-lpeg @@ -76,15 +71,23 @@ local css = { ["function"] = "hl-func", } --- Extension to lexer name fixes for the fallback path, reached only when this --- Scintillua has no detect(). Most extensions already equal their lexer name --- and these are the frequent exceptions. A wrong guess only falls back to --- plain text, so a best-effort entry costs nothing. +-- Extension to lexer name fixes for the fallback path, reached only when +-- this Scintillua has no detect(). Most extensions already equal their lexer +-- name and these are the frequent exceptions. local ext_lexer = { - py = "python", js = "javascript", ts = "typescript", - rb = "ruby", pl = "perl", pm = "perl", sh = "bash", - md = "markdown", htm = "html", yml = "yaml", - rs = "rust", c = "ansi_c", h = "ansi_c", + py = "python", + js = "javascript", + ts = "typescript", + rb = "ruby", + pl = "perl", + pm = "perl", + sh = "bash", + md = "markdown", + htm = "html", + yml = "yaml", + rs = "rust", + c = "ansi_c", + h = "ansi_c", } @@ -108,7 +111,8 @@ local function scintillua_path() if config then local dir = string.match(config, "^(.*)/[^/]+$") if dir then - candidates[#candidates + 1] = dir .. "/scintillua/lexers" + candidates[#candidates + 1] = + dir .. "/scintillua/lexers" end end for _, dir in ipairs(scintillua_dirs) do @@ -159,9 +163,6 @@ local function load_lexer_name(name) return nil end --- Resolve a lexer for the file, preferring Scintillua's own filename --- detection where this version provides it, then the extension map above, --- then the raw extension. local function lexer_for(name) if type(scintillua.detect) == "function" then local ok, lang = pcall(scintillua.detect, name) @@ -200,7 +201,8 @@ local function highlight(text) local part = escape(string.sub(text, pos, stop - 1)) local class = css[string.match(tag, "^[%w_]+")] if class and part ~= "" then - part = "<span class='" .. class .. "'>" .. part .. "</span>" + part = "<span class='" .. class .. "'>" + .. part .. "</span>" end out[#out + 1] = part pos = stop @@ -223,8 +225,9 @@ function filter_write(str) end -- cgit takes filter output through a C string sink that stops at the first --- NUL byte, so a blob holding one is truncated there. That reaches binary --- files which slip past cgit's text detection, not ordinary source. +-- NUL byte, so a write holding one loses everything from the NUL on. That +-- reaches binary files which slip past cgit's text detection, not ordinary +-- source. function filter_close() local text = table.concat(chunks) chunks = {} diff --git a/custom/hooks/post-receive.cgit-cache b/custom/hooks/post-receive.cgit-cache index 235de27..4825a44 100755 --- a/custom/hooks/post-receive.cgit-cache +++ b/custom/hooks/post-receive.cgit-cache @@ -4,7 +4,7 @@ # show up right away instead of once the cache-*-ttl minutes have passed. # # This only matters when cache-size in your cgitrc is above 0, which turns -# the cache on. With it off the hook does nothing and costs one stat call. +# the cache on. # # cgit names each cache slot after a hash of the request url, so there is no # way to expire one repository's pages on their own and this clears the lot. @@ -16,9 +16,8 @@ # change the value in your cgitrc then you must also change it here. # # The web server owns the cache root, so the pushing user needs write access -# to it. Making the directory group writable and putting both users in that -# group is usually enough. Nothing here fails a push if that access is -# missing, since a stale page is not worth rejecting a push over. +# to it. Nothing here exits nonzero when that access is missing, so the +# pusher is not shown an error over a stale page. # # To install the hook, copy (or link) it to the file "hooks/post-receive" in # each of your repositories. Git runs one post-receive per repository, so |
