| Age | Commit message (Collapse) | Author | Lines |
|
The slot lock was a POSIX record lock, which a process loses the moment
any descriptor on the file closes, and the fill puts the lock file on
stdout, which every exec filter and snapshot compressor closes with its
dup2. A second request on the slot could then rebuild it under the first
and splice the two pages. An flock holds until the last descriptor goes.
|
|
The slot being filled was forgotten before the page's final flush, so a
write that failed there, on a full disk for one, could not abandon the
fill: cgit died into the lock file instead and the visitor got nothing.
The mid-page path already delivered the page from the lock file.
|
|
Both pages hand the diff to git, whose own limit on an inlined blob is
512 MB, so a commit adding a blob the other views refuse was inflated
and diffed in full. The cap is passed through to git, which shows such a
blob as binary.
|
|
A quoted header value escaped only the quote, the backslash, CR and LF.
A web server refuses a response whose header holds any other control
byte, so a file named with one could not be downloaded at all.
|
|
The index stats the default branch below the repository to date it,
and a scanned repository sets its own defbranch, which was not held to
what a ref may hold, so one spelled as a path reached a file outside.
|
|
A tree can hold two entries of one name when fsck is off, and the walk
went on after the first answered: a second file put two responses in
one body, and a directory under the same name printed headers from the
mimetype string the first had already freed.
|
|
A signature is a note a pusher stored, and the download read it whole
without the size check every other blob a page inflates goes through.
|
|
The refs listing offers a tag's snapshot under the stem of its name, and
the lookup back from that name settled on whatever ref matched first,
so a branch spelled like the stem was archived in the tag's place. Every
candidate is now tried as a tag before any is tried as a branch.
|
|
A pusher can point refs/notes/commits or a signature notes ref at any
object, and git dies loading one that is no tree, which ended every page
of the repository, the dumb transport included. Such a ref now counts
as absent.
|
|
A date past what the system holds, a zone that is no hhmm offset, or a
date earlier than its own westward offset all made git die inside
show_date, which took the summary, refs, log, commit and feed pages of
the repository down. They are now clamped as git's own log clamps them.
|
|
The chrome renders on an error page too, where the id had just been
refused for using the wider revision syntax, and then looked it up
anyway. A :/pattern id walks the whole history for a match.
|
|
The object path check let any run of safe characters through, so a
spelling such as info//alternates or info/./alternates reached the
alternates file the exact name was refused for. Only a loose object, a
pack with its index and info/http-alternates are served now, and any
other path is not found.
|
|
setup_revisions compiles the pattern itself, and the literal type cgit
set afterwards came too late, so text that was no valid regular
expression, such as an unbalanced bracket, ended in a 500.
|
|
Index sorting, the commit graph, the stats periods past a week, the hex
dump of a binary file and a Lua filter's html_url_arg and html_include
ran in no test.
|
|
skip_line stopped at a NUL as well as at a newline, so the rest of the
comment after one was read as a setting.
|
|
The index built its paths from a NULL repo.path, which the C library
prints as "(null)", so it looked for refs under that name in the working
directory.
|
|
Past fifteen single directories the row stopped after writing the next
separator, which left it ending in a dangling " / ".
|
|
A symlink to /etc/passwd was resolved against the tree and linked to
etc/passwd inside it, a different file or none at all.
|
|
With no PATH in the environment, the check that a compressor exists
gave up and refused every compressed snapshot, though execvp would have
found it on the system's default path.
|
|
A name that was all suffix, such as .tar, settled on a ref called v
with an empty prefix, and an empty snapshot-prefix did the same for a
snapshot asked for by id, so every member of the archive started at /.
|
|
A readme past max-blob-size is never read, which left the about page
with an empty block and no word of why.
|
|
The tag page offered a download for a tag of a tree or a blob, which
only led to a "Not a commit" page. The refs listing already checks.
|
|
A feed path starting with a colon reached git as pathspec magic, so an
unknown magic word ended the request in a 500 and a known one changed
what the path matched, while the log answers both with a 400.
|
|
The idle column falls back on the mtime of the branch's loose ref or of
packed-refs, and a reftable repository has neither, so its cell stayed
empty. Git rewrites reftable/tables.list on every ref update.
|
|
A reftable repository keeps only a placeholder in its HEAD file, so a
dumb clone was told HEAD named refs/heads/.invalid and checked nothing
out. HEAD is now answered the way git's http-backend answers it.
|
|
The index description was cut at a byte count, which could split a
multibyte character and leave an invalid sequence on the page. Commit
subjects already backed up to the start of the character, so html_ntxt
now does that for every caller.
|
|
A Lua build replaces write, and git can write before cmd_main reaches
cgit_init_filters, as it does when GIT_TRACE2 is set, which called
through a null pointer and crashed every request.
|
|
summary-branches, summary-tags and max-ref-count already listed every
ref at 0, but a negative value reached qsort as a count and crashed the
summary and refs pages, and emptied the branch switcher.
|
|
Each row of a followed log moves ctx.qry.vpath to the name its commit
knew the file by, and the pager built its links from that, so past a
rename both links named the old file and led to an empty page.
|
|
A followed log diffs each commit against its parent to learn whether
the file changed there, and a root commit was skipped rather than
diffed against the empty tree, so a file created in the first commit
never showed that commit.
|
|
Tag links carry the tag name as the head, so on any page reached from
an annotated tag the about tab vanished and the about page redirected
to the summary.
|
|
Links built from the repository url, among them the description link
on the index and the Atom and refs links, wrote it as configured, so a
name holding a space, '#' or '?' broke them. The feed link in the page
head did the same with the branch, which turned a '+' into a space.
|
|
A script raising anything but a string handed die a null to print, and
a Lua state that could not be created was used anyway once the filter
closed.
|
|
A script's top level runs before cgit hooks stdout for it, and the
unhook html() began with tripped an assert that aborted cgit.
|
|
luaossl from release 20260910 and luaposix load under Lua 5.5, and cgit
renders the same pages under it as under LuaJIT. Running the suites
there already caught a write to a for loop's control variable, which
5.5 makes read-only.
|
|
Scintillua's detect reads the first line as well as the name, and
without it hooks, bin scripts and anything else lacking an extension
stayed plain.
|
|
An unedited copy sent every #123, Closes: and Bug: mark to
bugs.example.com, a link that is wrong for every site.
|
|
Without the prefix any host under the same domain could set a cgitauth
cookie of its own, signing a visitor in as someone else or out.
|
|
A session stayed good for its whole week after the password changed or
the account went away, which is when ending it matters most.
|
|
Required at the top, a missing luaossl or luaposix failed every request
to the site, public pages included, and each public page paid to load
both.
|
|
The fixed SHA-512 stand-in matched only the documented setup, so a site
hashing with yescrypt, other rounds or bcrypt answered for missing and
real names in different times, and on OpenBSD it failed at once.
|
|
SHA-crypt hashes the password in most of its rounds, so the 4 KB that
cgit's POST limit lets through cost about fifteen ordinary logins per
anonymous attempt.
|
|
Splitting the header with patterns that backtrack over spaces cost a
quarter of a second per request at the 8 KB line most web servers
allow, and a second at 16 KB, without any login. auth-file's trim had
the same shape and now reads the cookie as well.
|
|
The 13 pixel icon came out blurred on the high density screens most
phones and laptops have.
|
|
Gravatar's documentation now describes SHA-256 hashes on gravatar.com
alone, and Libravatar has long accepted them beside MD5.
|
|
A screen reader announced the service's name before every author.
|
|
An author email of 16,000 "<" took three quarters of a second per log
row, and one of 64,000 took twelve seconds.
|
|
The require at the top raised as cgit loaded the filter, so every page
that lists an author stopped at its first author cell with an error.
|
|
The footer lost the time it was generated at in 2018, and both runs
come from the same binary, so the two pages have nothing to differ in.
|
|
It was a bare table.list with no name, section or label, the one
listing that broke what the README promises a theme.
|