AgeCommit message (Collapse)AuthorLines
Give the trim timing check room for a slow hostBryce Kwon-2/+3
The about-render unit test bounds three renders at one second to catch the cubic trim coming back. They take 0.1 s natively and three seconds on an emulated x86_64 host, where the check failed, while the old code took minutes, so ten seconds still tells the two apart.
Isolate git from HOME before git's own setupBryce Kwon-3/+4
Git reads the global config for its trace settings before cmd_main is reached, so the isolation there came too late and every request probed $HOME/.gitconfig. The home-access test had passed on arm64 only because access is no syscall of its own there, so it now traces every call that takes a path.
Lock a cache slot with flockBryce Kwon-0/+38
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.
Abandon a fill whose last flush fails to writeBryce Kwon-0/+16
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.
Hold patch and rawdiff to max-blob-sizeBryce Kwon-0/+18
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.
Keep every control byte out of a header valueBryce Kwon-0/+14
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.
Hold a scanned defbranch to a ref nameBryce Kwon-0/+11
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.
Answer the plain view once for duplicate entriesBryce Kwon-0/+25
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.
Hold a signature download to max-blob-sizeBryce Kwon-0/+12
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.
Lead a snapshot name to its tag ahead of a branchBryce Kwon-0/+9
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.
Pass over a notes ref that names no treeBryce Kwon-0/+20
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.
Show an odd pushed date rather than die on itBryce Kwon-0/+39
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.
Check the id before the page chrome resolves itBryce Kwon-0/+12
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.
Serve only the files a dumb clone asks forBryce Kwon-5/+9
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.
Search the log literally as intendedBryce Kwon-0/+9
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.
Test the features the suite never reachedBryce Kwon-0/+75
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.
Run a config comment to the end of its lineBryce Kwon-0/+16
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.
Give a repository without a path no ageBryce Kwon-0/+10
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.
End a long directory chain on its last linkBryce Kwon-0/+27
Past fifteen single directories the row stopped after writing the next separator, which left it ending in a dangling " / ".
Show an absolute link target as textBryce Kwon-0/+26
A symlink to /etc/passwd was resolved against the tree and linked to etc/passwd inside it, a different file or none at all.
Find a compressor on the default path when unsetBryce Kwon-0/+14
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.
Keep snapshot members from starting at a slashBryce Kwon-0/+21
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 /.
Say why an oversized readme leaves about emptyBryce Kwon-0/+15
A readme past max-blob-size is never read, which left the about page with an empty block and no word of why.
Offer tag snapshots only for a tagged commitBryce Kwon-0/+14
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.
Refuse pathspec magic in the feed as in the logBryce Kwon-0/+9
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.
Date a reftable repository on the indexBryce Kwon-0/+5
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.
Answer dumb-clone HEAD from the ref storeBryce Kwon-0/+26
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.
Cut text between characters, never inside oneBryce Kwon-0/+24
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.
Find libc's write when git writes firstBryce Kwon-0/+8
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.
Read a negative ref count as no limitBryce Kwon-0/+20
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.
Page a followed log by the name asked forBryce Kwon-1/+9
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.
Show the root commit in a followed logBryce Kwon-0/+38
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.
Peel an annotated tag before looking for a readmeBryce Kwon-0/+14
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.
Encode repository urls and the feed branchBryce Kwon-2/+14
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.
Name every Lua filter failure in the logBryce Kwon-0/+13
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.
Let a Lua script write while it loadsBryce Kwon-0/+20
A script's top level runs before cgit hooks stdout for it, and the unhook html() began with tripped an assert that aborted cgit.
Claim and test Lua 5.5 for every extensionBryce Kwon-5/+5
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.
Find a script's lexer from its shebang lineBryce Kwon-4/+11
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.
Ship the example tracker links commented outBryce Kwon-19/+35
An unedited copy sent every #123, Closes: and Bug: mark to bugs.example.com, a link that is wrong for every site.
Name the auth cookie __Host- where it can beBryce Kwon-26/+51
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.
End a session when its account's hash changesBryce Kwon-4/+20
A session stayed good for its whole week after the password changed or the account went away, which is when ending it matters most.
Load auth libraries only when a request needs oneBryce Kwon-6/+43
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.
Spend a missing account's login on a real hashBryce Kwon-36/+68
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.
Turn down passwords past 256 bytes uncheckedBryce Kwon-0/+22
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.
Read the auth cookie in linear timeBryce Kwon-0/+10
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.
Offer avatars at twice the size to dense screensBryce Kwon-0/+1
The 13 pixel icon came out blurred on the high density screens most phones and laptops have.
Hash avatar addresses with SHA-256Bryce Kwon-7/+9
Gravatar's documentation now describes SHA-256 hashes on gravatar.com alone, and Libravatar has long accepted them beside MD5.
Mark avatar icons as decorativeBryce Kwon-3/+1
A screen reader announced the service's name before every author.
Unwrap an avatar address in linear timeBryce Kwon-0/+7
An author email of 16,000 "<" took three quarters of a second per log row, and one of 64,000 took twelve seconds.
Draw no avatar when luaossl is missingBryce Kwon-9/+33
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.