| 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.
|
|
A ttl in the tens of millions of minutes overflowed the int it was
multiplied in.
|
|
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.
|
|
Current xz uses a thread per core unless told otherwise, so a single
tar.xz request could keep every core busy, unlike the other compressors.
|
|
XDF_NEED_MINIMAL turns off the cost limit in xdiff, so a file whose
lines were reordered took time quadratic in its length: 2.1 s for one of
40000 lines, now 38 ms. Git leaves it off by default as well.
|
|
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.
|
|
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.
|
|
cgit_parse_url tested ctx.repo where the loop sets repo_end alongside
it, and the log's closing link kept a commit it never read. Clang's
analyzer tripped on both.
|
|
The row stopped at the error and left its cells open, so the rest of
the listing rendered inside 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.
|
|
The sparse rule put git's SPARSE_FLAGS last, and their -std=gnu99
overrode the gnu17 the sources are built as.
|
|
Neither cgit nor the bundled Git reads the macro it defined.
|
|
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.
|
|
Git 2.55 moved object sizes from unsigned long to size_t. The two are
the same type on 64-bit hosts, but not on a 32-bit one, where GCC 14
rejects the mismatched pointers, so cgit stopped compiling there.
|
|
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.
|
|
cgit builds against Lua 5.5 and serves the same pages with it, but a
host whose only Lua was 5.5 got a binary without Lua from the search.
|
|
It was a bare table.list with no name, section or label, the one
listing that broke what the README promises a theme.
|
|
With nothing below the about page, a readme's relative links have to be
written against the tree, and only cgit knows how this site spells the
url of a tree page and which ref the readme was read from. Both reach
the filter already escaped for a url, built by the same writer as
cgit's own links.
|
|
The about page served every file beside the readme as a page of its
own, through the about filter, and answered 200 for directories and
missing files alike. Images it passed through came from the root of the
default branch whatever the readme's own directory and ref. A readme on
disk exposed its whole directory this way.
|
|
|
|
Five copies of the test and four of the error page had to agree by
hand. The new check pins the four refusals, which no test covered.
|
|
With these and the two changes before them, cgit builds under git's
DEVELOPER=1 settings, which also annotate their own callbacks this way.
|
|
ISO C has no conversion between a function pointer and void *, so the
callbacks handed through git's data pointers and the write found by
dlsym stopped the pedantic half of a DEVELOPER=1 build.
|