Compare commits

...

7 commits

Author SHA1 Message Date
8157440847 Merge remote-tracking branch 'upstream/master' 2022-06-30 15:37:14 -04:00
Hiltjo Posthuma
2890451154 Revert "remain compatible with slightly older libgit versions for now"
This reverts commit 70541c5e2c.

Reported by Anton:
The last commit[1] is not correct as GIT_OPT_SET_OWNER_VALIDATION is not
a preprocessor directive but rather an enum. Causing the branch to never
be entered.
2022-05-27 21:29:14 +02:00
Hiltjo Posthuma
70541c5e2c remain compatible with slightly older libgit versions for now 2022-05-24 14:07:27 +02:00
Anton Lindqvist
1357ad5181 Allow git to run on an other user repository
Reported by Anton:

"Recent versions of libgit2 broke stagit for me due to the added opt-out
GIT_OPT_SET_OWNER_VALIDATION configuration knob. My repositories are owned by
root:vcs and I run stagit as another user which happens to be in vcs group but
not the owner of the repository. Disabling the validation makes stagit work as
expected again."

Some notes:

When using regular git it also provides a knob. This is due to a security
concern in some cases, which is not applicable to stagit.

	git log somerepo

	fatal: unsafe repository ('somerepo' is owned by someone else)
	To add an exception for this directory, call:

	        git config --global --add safe.directory somerepo

See also / related:
- https://github.blog/2022-04-12-git-security-vulnerability-announced/
2022-05-24 11:09:05 +02:00
Hiltjo Posthuma
a8a5e9c3b3 bump version to 1.1 2022-04-02 17:35:47 +02:00
Hiltjo Posthuma
d0e36eb6ab improve stream read and write error handling 2022-03-19 12:51:40 +01:00
Hiltjo Posthuma
7c419a8bac add dark mode support for the example stylesheet 2022-03-19 12:23:16 +01:00
3 changed files with 47 additions and 10 deletions

View file

@ -1,7 +1,7 @@
.POSIX:
NAME = stagit
VERSION = 1.0
VERSION = 1.1
# paths
PREFIX = /usr/local

View file

@ -16,6 +16,16 @@ static char description[255] = "Repositories";
static char *name = "";
static char owner[255];
/* Handle read or write errors for a FILE * stream */
void
checkfileerror(FILE *fp, const char *name, int mode)
{
if (mode == 'r' && ferror(fp))
errx(1, "read error: %s", name);
else if (mode == 'w' && (fflush(fp) || ferror(fp)))
errx(1, "write error: %s", name);
}
void
joinpath(char *buf, size_t bufsiz, const char *path, const char *path2)
{
@ -178,6 +188,8 @@ main(int argc, char *argv[])
git_libgit2_init();
for (i = 1; i <= GIT_CONFIG_LEVEL_APP; i++)
git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, i, "");
/* do not require the git repository to be owned by the current user */
git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 0);
#ifdef __OpenBSD__
if (pledge("stdio rpath", NULL) == -1)
@ -214,6 +226,7 @@ main(int argc, char *argv[])
if (fp) {
if (!fgets(description, sizeof(description), fp))
description[0] = '\0';
checkfileerror(fp, "description", 'r');
fclose(fp);
}
@ -227,8 +240,9 @@ main(int argc, char *argv[])
if (fp) {
if (!fgets(owner, sizeof(owner), fp))
owner[0] = '\0';
owner[strcspn(owner, "\n")] = '\0';
checkfileerror(fp, "owner", 'r');
fclose(fp);
owner[strcspn(owner, "\n")] = '\0';
}
writelog(stdout);
}
@ -238,5 +252,7 @@ main(int argc, char *argv[])
git_repository_free(repo);
git_libgit2_shutdown();
checkfileerror(stdout, "<stdout>", 'w');
return ret;
}

View file

@ -79,6 +79,16 @@ static char lastoidstr[GIT_OID_HEXSZ + 2]; /* id + newline + NUL byte */
static FILE *rcachefp, *wcachefp;
static const char *cachefile;
/* Handle read or write errors for a FILE * stream */
void
checkfileerror(FILE *fp, const char *name, int mode)
{
if (mode == 'r' && ferror(fp))
errx(1, "read error: %s", name);
else if (mode == 'w' && (fflush(fp) || ferror(fp)))
errx(1, "write error: %s", name);
}
void
joinpath(char *buf, size_t bufsiz, const char *path, const char *path2)
{
@ -814,6 +824,7 @@ writelog(FILE *fp, const git_oid *oid)
printshowfile(fpfile, ci);
fputs("</pre>\n", fpfile);
writefooter(fpfile);
checkfileerror(fpfile, path, 'w');
fclose(fpfile);
}
err:
@ -963,14 +974,13 @@ writeblob(git_object *obj, const char *fpath, const char *filename, size_t files
fprintf(fp, " (%zuB)", filesize);
fputs("</p><hr/>", fp);
if (git_blob_is_binary((git_blob *)obj)) {
if (git_blob_is_binary((git_blob *)obj))
fputs("<p>Binary file.</p>\n", fp);
} else {
else
lc = writeblobhtml(fp, (git_blob *)obj);
if (ferror(fp))
err(1, "fwrite");
}
writefooter(fp);
checkfileerror(fp, fpath, 'w');
fclose(fp);
relpath = "";
@ -1225,6 +1235,8 @@ main(int argc, char *argv[])
git_libgit2_init();
for (i = 1; i <= GIT_CONFIG_LEVEL_APP; i++)
git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, i, "");
/* do not require the git repository to be owned by the current user */
git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 0);
#ifdef __OpenBSD__
if (unveil(repodir, "r") == -1)
@ -1276,6 +1288,7 @@ main(int argc, char *argv[])
if (fpread) {
if (!fgets(description, sizeof(description), fpread))
description[0] = '\0';
checkfileerror(fpread, path, 'r');
fclose(fpread);
}
@ -1288,8 +1301,9 @@ main(int argc, char *argv[])
if (fpread) {
if (!fgets(cloneurl, sizeof(cloneurl), fpread))
cloneurl[0] = '\0';
cloneurl[strcspn(cloneurl, "\n")] = '\0';
checkfileerror(fpread, path, 'r');
fclose(fpread);
cloneurl[strcspn(cloneurl, "\n")] = '\0';
}
/* check LICENSE */
@ -1349,13 +1363,15 @@ main(int argc, char *argv[])
while (!feof(rcachefp)) {
n = fread(buf, 1, sizeof(buf), rcachefp);
if (ferror(rcachefp))
err(1, "fread");
break;
if (fwrite(buf, 1, n, fp) != n ||
fwrite(buf, 1, n, wcachefp) != n)
err(1, "fwrite");
break;
}
checkfileerror(rcachefp, cachefile, 'r');
fclose(rcachefp);
}
checkfileerror(wcachefp, tmppath, 'w');
fclose(wcachefp);
} else {
if (head)
@ -1364,6 +1380,7 @@ main(int argc, char *argv[])
fputs("</tbody></table>", fp);
writefooter(fp);
checkfileerror(fp, "log.html", 'w');
fclose(fp);
/* files for HEAD */
@ -1372,6 +1389,7 @@ main(int argc, char *argv[])
if (head)
writefiles(fp, head);
writefooter(fp);
checkfileerror(fp, "files.html", 'w');
fclose(fp);
/* summary page with branches and tags */
@ -1379,16 +1397,19 @@ main(int argc, char *argv[])
writeheader(fp, "Refs");
writerefs(fp);
writefooter(fp);
checkfileerror(fp, "refs.html", 'w');
fclose(fp);
/* Atom feed */
fp = efopen("atom.xml", "w");
writeatom(fp, 1);
checkfileerror(fp, "atom.xml", 'w');
fclose(fp);
/* Atom feed for tags / releases */
fp = efopen("tags.xml", "w");
writeatom(fp, 0);
checkfileerror(fp, "tags.xml", 'w');
fclose(fp);
/* rename new cache file on success */