From e1bf539be92d36ab1ab05544ce74f2447b49ecaf Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Fri, 28 Aug 2026 06:39:59 -1000 Subject: Release v2.6.0 --- CHANGELOG.txt | 460 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- 2 files changed, 461 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG.txt diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 0000000..35a300d --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,460 @@ +cgit - Changelog +================ + +Notable changes to this fork, newest release first. History before v2.0.0 +belongs to upstream cgit and is not covered here. + + +v2.6.0 (2026-08-28) +------------------- + +A cleanup release. Output is ASCII only and deterministic, the statistics page +drops its language breakdown, and two bugs a cross-compiler review found are +fixed. + +Added +..... + +* README.txt documents how cgit urls are built, both url forms, every query + parameter, the endpoints that are not pages, and worked examples. +* tests/README.txt describes the suite layout, numbering and traps. +* Pages carry a meta description, from the repository or root description. +* Submodule links resolve through .gitmodules, and submodule rows are set apart + in the tree listing. + +Changed +....... + +* Output is ASCII only. The truncation marker is an ellipsis, the title path + separator is plain, and unrepresentable bytes print as a question mark. +* Non-breaking space padding is done with CSS. +* Pages are byte for byte deterministic. The footer drops its clock and an + empty atom feed is dated at the epoch. +* The charset is spelled UTF-8 everywhere. +* Snapshots use registered media types, so application/gzip, application/zip + and application/zstd replace their x- forms. +* Status lines use the standard HTTP reason phrases. +* Table header and image attributes follow the usual order. +* Test scripts are renumbered into themed ranges and prefer POSIX forms. + +Removed +....... + +* The statistics page no longer breaks the tree down by language. The built-in + extension table was a standing maintenance cost, classifying by extension + misleads, and the tree walk it needed was the only part of the page reading + object sizes. The commits-per-author table is unchanged. + +Fixed +..... + +* The statistics page no longer reads past its argument list when given a path. + The array handed to git's revision setup lacked a trailing null, so a url + such as /repo/stats/dir read whatever followed it on the stack. +* A detached head stays selected in the branch switcher. Browsing at a raw + commit or tag left it resting on the first branch, so switch moved away. + + +v2.5.0 (2026-08-23) +------------------- + +A correctness and conformance release. The generated markup moves fully to +HTML5, cgit stops emitting HTTP headers a front-end server should own, the page +cache and repository scan get real locking, and pages pinned to a commit now say +so. + +Added +..... + +* Pages pinned to a commit via the id parameter show it. The branch switcher + gains a "(detached)" entry, the page title carries the short hash, and the + path strip gains a rev crumb linking back to the branch tip. +* The shipped server configs gain Permissions-Policy, cross-origin isolation + headers and form-action in the CSP, and enable HSTS. The nginx config adds + catch-all blocks that drop requests for hostnames the site does not serve, + since cgit keys its cache on Host. +* Operators get log lines for two previously silent failures, a cache too small + for its keys and a repository scan lock that fails for reasons other than + contention. +* The documentation now spells out that the cache directory must be pre-created, + owned by the web server account and mode 0700. +* Login forms carry autocomplete hints for password managers, and avatar images + load lazily. + +Changed +....... + +* Atom feeds conform to the RFC. They are served as application/atom+xml with an + XML declaration, invalid bytes are replaced instead of emitted, and every + entry carries an author name. +* Dates render as HTML time elements with strict ISO 8601 values. +* Markup is fully HTML5. Complete documents everywhere, real table header cells, + no XHTML self-closing slashes and no HTML comments in the output. The plain + directory listing gets a doctype so browsers leave quirks mode. +* cgit no longer sends Last-Modified, Expires or ETag. Front-end caching policy + lives in the server configs, which now append headers rather than replace + cgit's own. +* Only a full object id qualifies for cache-static-ttl, since the id parameter + accepts any rev git can resolve. +* Percentages in the diffstat bars and language table print from integers, so a + filter that switches the numeric locale cannot corrupt the output. +* URL encoding is tightened. Ampersands and plus signs are percent-encoded in + paths, and query strings are escaped at each sink instead of being + pre-escaped. +* The responsive breakpoints only hide or restack chrome and never change font + sizes or gutters. Narrow screens drop the search box, branch switcher and + author columns, and diff tables scroll inside their own box. +* The client-side age refresher uses the same bucket arithmetic as the server, + so refreshed ages no longer drift from rendered ones. +* The example agefile hook was renamed to post-receive.cgit-age. + +Removed +....... + +* The repository homepage feature, including repo.homepage, the gitweb.homepage + mapping and the homepage tab. +* The post-update.update-server-info example hook. + +Fixed +..... + +* Error pages are no longer cached, so requesting a commit before it is pushed + can no longer pin a 404 into the cache forever. +* An abandoned cache fill no longer appends a second page to the response, + publishes its lock file or leaves a stale copy to be served. +* A crashed repository scan no longer freezes the index forever. Scan and cache + locks are fcntl locks released by the kernel with the process, and lock + holders re-verify their lock file after acquiring it, closing a race that + could truncate a live file. +* Blobs containing a NUL byte anywhere are treated as binary in tree and blame + views, and the raw path substitutes replacement characters instead of + truncating at the NUL. +* An annotated tag whose tagger has no email no longer passes NULL to the email + filter, repositories without an owner no longer render an empty link, + single-page logs drop the pager, and filler rows use correct colspan values. +* The dev preview server splits CGI headers at the earliest blank line, so DOS + line endings in page output no longer swallow the document head. + + +v2.4.0 (2026-08-08) +------------------- + +A performance and robustness release. Output is buffered instead of written +fragment by fragment, the hot paths shed repeated work, and a cluster of fixes +closes crashes reachable from repository-controlled content. + +Changed +....... + +* The bundled Git is updated from 2.54.0 to 2.55.0, with NO_RUST set so Cargo + does not become a silent build requirement. +* Page output is collected in a 64 KB buffer and written in whole blocks instead + of one write per HTML fragment. +* Blame and tree line numbers, hex dump rows and intra-line diff highlights are + emitted in batches rather than per line or character. +* The diff view renders each file while it is already open and replays it after + the diffstat, replacing a second full tree walk. +* Blame reuses a commit's rendered detail across its entries, the index resolves + repository ages once before sorting, and the stats page computes its period + labels once. +* Side-by-side tab expansion is a single pass, where it was previously quadratic + on tab-heavy lines. +* Search queries are clamped to 512 characters, bounding the matching work one + request can demand and the size of cache keys. +* The sources compile as gnu17 so their meaning does not drift with compiler + defaults, and the release script probes each hardening flag, preferring + FORTIFY_SOURCE level 3. + +Fixed +..... + +* A repository under scan-path could supply its own module-link template, which + was handed straight to printf. Surplus conversions could crash cgit or read + stack memory into the page. Templates are now expanded manually. +* Sorting branches by age crashed when a branch ref pointed at a tag or tree + object. +* Hunks whose header omits a length, as git writes for single-line hunks, were + numbered from zero in side-by-side diffs and lost their links. +* A request whose cache key was too long to read back could never hit, + regenerating the page every time while still writing an unusable slot. Such + requests now skip the cache and log it. +* Git config isolation ran from a constructor attribute that some compilers + silently discard. It now runs from main. +* A memory leak of deferred side-by-side lines and an integer-truncation bug in + the stats author ordering. + + +v2.3.0 (2026-08-05) +------------------- + +A consolidation release focused on how the project is laid out, deployed and +operated. Everything an operator ships or edits now lives under custom/, the +server configs became complete standalone files, and the hooks and auth filters +were hardened. + +Added +..... + +* New enable-relative-dates option, default 1. Set to 0 to always show calendar + dates in the age columns instead of elapsed times. +* New date-format option controlling those calendar dates, accepting git's date + format names plus strftime formats. +* New example hook post-receive.cgit-cache that clears cgit's output cache after + a push, so new commits appear immediately instead of after the cache TTL. +* New CGIT_EXTRA_CFLAGS make variable applying extra compiler flags to cgit's + own objects only, not the bundled git. + +Changed +....... + +* The tree was reorganized. The git submodule moved to vendor/git, and the + example cgitrc, Lua filters, hooks and server configs moved into custom/. + Operators following old paths must update them. +* Repositories with no commits get a dedicated page with working clone URLs + instead of a bare notice with dead tabs. +* A description file still holding git's "Unnamed repository" boilerplate is + treated as no description. +* The theme is applied before first paint, so pages no longer flash the wrong + theme, and the header no longer shifts as the page loads. +* The nginx, Apache and lighttpd configs are complete, runnable files carrying + their own top-level directives, rather than snippets assuming a distro base. +* The agefile hook uses committer dates from branches only, writes atomically + and keeps its output readable by the web server. The update-server-info hook + likewise forces a safe umask. +* The auth filters' secret moved from /var/cache/cgit to /var/lib/cgit, so + pruning the cache no longer invalidates every live session. +* The dev preview server forwards cookies, referers and request bodies, so the + auth filters can be exercised locally, and decodes escaped repository names. + +Removed +....... + +* The built-in help page and its enable-help option. +* GitHub Actions CI, the release workflow and the make dist target. + +Fixed +..... + +* Ordinary working trees found by scan-path are listed as repo instead of + repo/.git. +* The auth filters match cookie names containing pattern magic characters, and + auth-file tolerates a users file saved with CRLF line endings. + + +v2.2.0 (2026-07-25) +------------------- + +A hardening release that puts explicit ceilings on the work a single request can +provoke, reworks the statistics page, and overhauls the bundled Lua filters. + +Added +..... + +* The stats page gains a language breakdown, sizing the tree at HEAD by file + extension without ever loading blob contents. +* New enable-stats option, default 0, as the dedicated switch for the statistics + page. +* New max-patch-count option, default 50, bounding how many commits the patch + view emits as a series. +* New about-filter script about-render.lua, a server-side renderer for markdown, + man pages and plain text, falling back to escaped text when its dependencies + are missing. +* New make dist target staging the release tarball, so local and released + tarballs are identical. + +Changed +....... + +* max-stats no longer enables the stats page, it only bounds the coarsest + period. Instances relying on it must now also set enable-stats=1. +* The auth filters are hardened. Cookies are Secure by default, redirect targets + are validated so a login cannot bounce to another origin, password checks are + constant time even for unknown users, and a protected repository with no + resolvable users denies everyone. +* The avatar filters skip missing addresses instead of hashing garbage, + normalize the rest, and expose size, style and URL settings. +* link-commits.lua takes a user-editable list of pattern and URL rules instead + of a hardcoded issue reference, resolving all matches in one pass. +* The syntax highlighter falls back through an extension map when lexer + detection fails and emits its plain-text fallback in slices instead of one + full-size copy. +* The masthead reserves the logo column so the header no longer shifts while the + logo loads, and the logo and favicon were redrawn at higher resolution. + +Removed +....... + +* The client-side markdown renderer and the enable-markdown option. Rendered + readmes now require about-filter pointed at about-render.lua. +* The PDF documentation targets. + +Fixed +..... + +* A file name containing a quote could break out of the link attributes in + side-by-side diffs. Paths are now percent-encoded. +* A commit with no message no longer crashes the history views. +* max-blob-size also bounds the diff path, so a huge blob is reported as binary + instead of inflated into memory, and dangling refs are skipped instead of + dereferenced. +* The diff size caps are no longer silently disabled when follow is active. +* The header branch switcher respects max-ref-count instead of emitting an + option per branch on every page. +* zstd snapshots run single-threaded, so one request cannot fan out across every + core. +* The stats walk is pruned by date instead of visiting all history, and a commit + whose date cannot be represented is dropped rather than indexing a month table + out of bounds. +* The cache listing bounds its key output, and a malformed cgitrc line no longer + discards the rest of the file. +* The build no longer triggers a section-alignment warning on every macOS link. + + +v2.1.0 (2026-07-19) +------------------- + +A release about behaving well on large repositories and under a strict +Content-Security-Policy. Syntax highlighting moves out of the browser and into +an optional server-side filter. + +Added +..... + +* New max-ref-count option, default 200, capping how many branches and tags each + refs section lists, with independent pagination on the dedicated branch and + tag pages. +* New max-diff-files option, default 200. A commit touching more files renders + only its diffstat, with a notice pointing at the per-file diffs and the patch + view. +* New max-diff-lines option, default 1000. A single file exceeding it within a + whole-commit view links to its own diff page instead of rendering inline. + Single-file diffs, rawdiff and patch are never capped. +* An optional server-side syntax highlighter, syntax-highlight.lua, built on the + Scintillua lexers with around 120 languages, degrading to plain escaped text + when its dependencies are absent. +* A built-in help page documenting the site's URL patterns, behind the new + enable-help option. Removed again in v2.3.0. +* URL fragments highlight the targeted source line in blob and blame views, + support ranges like #n5-n12, and land the target mid-viewport. + +Changed +....... + +* The auto-submitting select controls drop their inline onchange handlers and + are wired up from cgit.js, so the option forms work under a CSP without + unsafe-inline. +* A plaintext readme keeps its line structure instead of collapsing into a + run-on paragraph. +* Syntax highlighting of source views moved from the browser to the optional + filter. Without a source-filter, code is served plain, and the client-side + highlighter is deleted. +* Font sizes were evened out across the interface, and the external-link icon + follows the tab's text color in both themes. +* The mobile layout hides the author and size columns, the search form and the + branch switcher, so nothing forces sideways scrolling. + +Removed +....... + +* The owner-filter hook and its per-repository override. Owners always render as + plain linked text. + +Fixed +..... + +* Release binaries no longer ship with an empty version string when git describe + fails in a shallow clone. + + +v2.0.0 (2026-07-16) +------------------- + +First release of this fork, cut from upstream cgit v1.3.1. The page chrome is +rebuilt as semantic HTML with dark mode and a phone layout, the runtime sheds +its external interpreters and crypto libraries, and around two dozen security +and correctness fixes land. + +Added +..... + +* Built-in client-side syntax highlighting in cgit.js for roughly 33 languages, + used when no source-filter is configured. +* Built-in client-side markdown rendering for about pages behind the new + enable-markdown option, restricted to safe link and image targets. +* A light and dark theme with a toggle cycling auto, light and dark, persisted + in localStorage and invisible without JavaScript. +* A responsive layout for phones and small screens, with stacking panels and a + repository index that collapses to name and age. +* New enable-tree-group-dirs option listing directories before files in the tree + view. +* New enable-cache-list option, default 0, gating the previously unprotected + cache listing page. +* A fully commented example cgitrc listing every option at its default, and + complete nginx, Apache and lighttpd examples with security headers. +* An example post-update hook running update-server-info, needed because the + built-in clone support speaks dumb HTTP. +* tools/serve.py, a dependency-free local preview server, and + tools/release-build.sh, a hardened Linux release build. +* CI covering gcc and clang, the test suite under ASan and UBSan, sparse, and a + hardened PIE build, plus a tag-triggered release workflow shipping hardened + tarballs with checksums. +* Accessible names on the search field, branch switcher and breadcrumb + navigation, and contextual titles on the nav tabs. + +Changed +....... + +* max-blob-size defaults to 10 MB instead of unlimited, and now caps everything + cgit reads into memory to serve, including plain and blob output. Oversized + objects return a 413 page. +* section-sort defaults to 0, so the order repositories are written in cgitrc is + respected rather than alphabetized. +* Repository age on the index is derived from HEAD instead of a hardcoded + refs/heads/master, so repositories on main show an age. +* The page chrome is semantic HTML instead of nested tables, keeping the + existing class and id names so custom themes still match. +* The filter scripts moved to a Lua-only set. simple-authentication.lua became + auth-inline.lua, file-authentication.lua became auth-file.lua and + commit-links.sh became link-commits.lua. +* Lua is optional and autodetected through pkg-config, preferring LuaJIT. + NO_LUA=1 forces a self-contained binary. +* The sources were reorganized into source/, libraries/, assets/, extensions/, + examples/, tools/ and tests/, with all generated output under build/. +* The auth filters compare cookie HMACs in constant time, set SameSite=Lax, and + strip header injection from Set-Cookie and Location values. + +Removed +....... + +* OpenSSL is no longer a build dependency, and libcurl is not required. +* Every Python filter script, including the Pygments highlighter, the markdown + and rst converters and the Python gravatar filter. +* The Gentoo LDAP auth filter, owner-example.lua, about-formatting.sh and the + man and txt about converters. +* The unused name query parameter and the never-read cache-max-create-time and + max-lock-attempts settings. + +Fixed +..... + +* An unauthenticated arbitrary file write through the log id parameter, which + reached git's revision parser as an option. Revisions beginning with a dash + are rejected. +* Cache poisoning through a spoofed Host header. The scheme and host are now + part of the cache key. +* Stored XSS from about pages, which were written as raw HTML when no + about-filter was configured. They are now escaped. +* Two path traversals, one past the about-path prefix check via a sibling + directory sharing a name prefix, and one through a crafted HEAD ref. +* max-blob-size is enforced before a blob is read into memory, not after. +* A signed-comparison bypass of the authentication POST size limit, and an + unbounded history walk from a crafted ofs value, now clamped. +* Every snapshot was undecompressable whenever a global git config existed, + because git's error output was compressed into the archive. +* Numerous crashes, among them out-of-bounds accesses on short paths and empty + URLs, NULL dereferences on odd blobs and authorless commits, a division by + zero in the diffstat and undefined ctype behavior on negative chars. +* Truncated pages after stat-only diffs and binary blames, a 200 instead of a + 404 for unknown blob paths, submodule hashes losing digits in diffs, pager + links dropping search terms containing reserved characters, a missing updated + element in empty atom feeds and negative ages from the age refresher. diff --git a/Makefile b/Makefile index fe8ef8a..f97d120 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ GIT_URL = https://www.kernel.org/pub/software/scm/git/git-$(GIT_VERSION).tar.xz # Compiled-in cgit defaults, all overridable through cgit.conf. Every one # carries the CGIT_ prefix except CACHE_ROOT, which is inherited from upstream # under that name. -CGIT_VERSION = v2.5.0 +CGIT_VERSION = v2.6.0 CGIT_SCRIPT_NAME = cgit.cgi CGIT_SCRIPT_PATH = /var/www/htdocs/cgit CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH) -- cgit v2.8.0