{"schema":"libjg2-1",
"vpath":"/git/",
"avatar":"/git/avatar/",
"alang":"",
"gen_ut":1745906798,
"reponame":"cgit",
"desc":"CGI gitweb",
"owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://warmcat.com/repo/cgit",
"f":3,
"items": [
{"schema":"libjg2-1",
"cid":"7e090539b76290934ec0965a63ae9050",
"commit": {"type":"commit",
"time": 1530115879,
"time_ofs": 120,
"oid_tree": { "oid": "8b4f71d0fb9ef478409109fbf485532ae90660f0", "alias": []},
"oid":{ "oid": "c712d5ac434b9ee8cb4e63a173a2538e1878637f", "alias": []},
"msg": "snapshot: support archive signatures",
"sig_commit": { "git_time": { "time": 1530115879, "offset": 120 }, "name": "Jason A. Donenfeld", "email": "Jason@zx2c4.com", "md5": "689e78dac56e3d77d7f74984912487d3" },
"sig_author": { "git_time": { "time": 1522509348, "offset": 60 }, "name": "John Keeping", "email": "john@keeping.me.uk", "md5": "aea7d8738c91da1cb0dfa9d86f2bbc47" }},
"body": "snapshot: support archive signatures\n\nRead signatures from the notes refs refs/notes/signatures/$FORMAT where\nFORMAT is one of our archive formats (\u0022tar\u0022, \u0022tar.gz\u0022, ...). The note\nis expected to simply contain the signature content to be returned when\nthe snapshot \u0022${filename}.asc\u0022 is requested, so the signature for\ncgit-1.1.tar.xz can be stored against the v1.1 tag with:\n\n\tgit notes --ref\u003drefs/notes/signatures/tar.xz add -C \u0022$(\n\t\tgpg --output - --armor --detach-sign cgit-1.1.tar.xz |\n\t\tgit hash-object -w --stdin\n\t)\u0022 v1.1\n\nand then downloaded by simply appending \u0022.asc\u0022 to the archive URL.\n\nSigned-off-by: John Keeping \u003cjohn@keeping.me.uk\u003e\nReviewed-by: Christian Hesse \u003cmail@eworm.de\u003e\n"
,
"diff": "diff --git a/cgit.h b/cgit.h\nindex 847cd2e..a686390 100644\n--- a/cgit.h\n+++ b/cgit.h\n@@ -374,6 +374,8 @@ extern void cgit_parse_url(const char *url);\n extern const char *cgit_repobasename(const char *reponame);\n \n extern int cgit_parse_snapshots_mask(const char *str);\n+extern const struct object_id *cgit_snapshot_get_sig(const char *ref,\n+\t\t\t\t\t\t const struct cgit_snapshot_format *f);\n \n extern int cgit_open_filter(struct cgit_filter *filter, ...);\n extern int cgit_close_filter(struct cgit_filter *filter);\ndiff --git a/ui-shared.c b/ui-shared.c\nindex 9d7ee3d..8a786e0 100644\n--- a/ui-shared.c\n+++ b/ui-shared.c\n@@ -1133,6 +1133,13 @@ void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref,\n \t\tstrbuf_addstr(\u0026filename, f-\u003esuffix);\n \t\tcgit_snapshot_link(filename.buf, NULL, NULL, NULL, NULL,\n \t\t\t\t filename.buf);\n+\t\tif (cgit_snapshot_get_sig(ref, f)) {\n+\t\t\tstrbuf_addstr(\u0026filename, \u0022.asc\u0022);\n+\t\t\thtml(\u0022 (\u0022);\n+\t\t\tcgit_snapshot_link(\u0022sig\u0022, NULL, NULL, NULL, NULL,\n+\t\t\t\t\t filename.buf);\n+\t\t\thtml(\u0022)\u0022);\n+\t\t}\n \t\thtml(separator);\n \t}\n \tstrbuf_release(\u0026filename);\ndiff --git a/ui-snapshot.c b/ui-snapshot.c\nindex abf8399..c7611e8 100644\n--- a/ui-snapshot.c\n+++ b/ui-snapshot.c\n@@ -94,6 +94,31 @@ const struct cgit_snapshot_format cgit_snapshot_formats[] \u003d {\n \t{ NULL }\n };\n \n+static struct notes_tree snapshot_sig_notes[ARRAY_SIZE(cgit_snapshot_formats)];\n+\n+const struct object_id *cgit_snapshot_get_sig(const char *ref,\n+\t\t\t\t\t const struct cgit_snapshot_format *f)\n+{\n+\tstruct notes_tree *tree;\n+\tstruct object_id oid;\n+\n+\tif (get_oid(ref, \u0026oid))\n+\t\treturn NULL;\n+\n+\ttree \u003d \u0026snapshot_sig_notes[f - \u0026cgit_snapshot_formats[0]];\n+\tif (!tree-\u003einitialized) {\n+\t\tstruct strbuf notes_ref \u003d STRBUF_INIT;\n+\n+\t\tstrbuf_addf(\u0026notes_ref, \u0022refs/notes/signatures/%s\u0022,\n+\t\t\t f-\u003esuffix + 1);\n+\n+\t\tinit_notes(tree, notes_ref.buf, combine_notes_ignore, 0);\n+\t\tstrbuf_release(\u0026notes_ref);\n+\t}\n+\n+\treturn get_note(tree, \u0026oid);\n+}\n+\n static const struct cgit_snapshot_format *get_format(const char *filename)\n {\n \tconst struct cgit_snapshot_format *fmt;\n@@ -129,6 +154,39 @@ static int make_snapshot(const struct cgit_snapshot_format *format,\n \treturn 0;\n }\n \n+static int write_sig(const struct cgit_snapshot_format *format,\n+\t\t const char *hex, const char *archive,\n+\t\t const char *filename)\n+{\n+\tconst struct object_id *note \u003d cgit_snapshot_get_sig(hex, format);\n+\tenum object_type type;\n+\tunsigned long size;\n+\tchar *buf;\n+\n+\tif (!note) {\n+\t\tcgit_print_error_page(404, \u0022Not found\u0022,\n+\t\t\t\t\u0022No signature for %s\u0022, archive);\n+\t\treturn 0;\n+\t}\n+\n+\tbuf \u003d read_sha1_file(note-\u003ehash, \u0026type, \u0026size);\n+\tif (!buf) {\n+\t\tcgit_print_error_page(404, \u0022Not found\u0022, \u0022Not found\u0022);\n+\t\treturn 0;\n+\t}\n+\n+\thtml(\u0022X-Content-Type-Options: nosniff\u005cn\u0022);\n+\thtml(\u0022Content-Security-Policy: default-src 'none'\u005cn\u0022);\n+\tctx.page.etag \u003d oid_to_hex(note);\n+\tctx.page.mimetype \u003d xstrdup(\u0022application/pgp-signature\u0022);\n+\tctx.page.filename \u003d xstrdup(filename);\n+\tcgit_print_http_headers();\n+\n+\thtml_raw(buf, size);\n+\tfree(buf);\n+\treturn 0;\n+}\n+\n /* Try to guess the requested revision from the requested snapshot name.\n * First the format extension is stripped, e.g. \u0022cgit-0.7.2.tar.gz\u0022 become\n * \u0022cgit-0.7.2\u0022. If this is a valid commit object name we've got a winner.\n@@ -185,6 +243,8 @@ void cgit_print_snapshot(const char *head, const char *hex,\n \t\t\t const char *filename, int dwim)\n {\n \tconst struct cgit_snapshot_format* f;\n+\tconst char *sig_filename \u003d NULL;\n+\tchar *adj_filename \u003d NULL;\n \tchar *prefix \u003d NULL;\n \n \tif (!filename) {\n@@ -193,6 +253,15 @@ void cgit_print_snapshot(const char *head, const char *hex,\n \t\treturn;\n \t}\n \n+\tif (ends_with(filename, \u0022.asc\u0022)) {\n+\t\tsig_filename \u003d filename;\n+\n+\t\t/* Strip \u0022.asc\u0022 from filename for common format processing */\n+\t\tadj_filename \u003d xstrdup(filename);\n+\t\tadj_filename[strlen(adj_filename) - 4] \u003d '\u005c0';\n+\t\tfilename \u003d adj_filename;\n+\t}\n+\n \tf \u003d get_format(filename);\n \tif (!f || !(ctx.repo-\u003esnapshots \u0026 f-\u003ebit)) {\n \t\tcgit_print_error_page(400, \u0022Bad request\u0022,\n@@ -216,6 +285,11 @@ void cgit_print_snapshot(const char *head, const char *hex,\n \tif (!prefix)\n \t\tprefix \u003d xstrdup(cgit_snapshot_prefix(ctx.repo));\n \n-\tmake_snapshot(f, hex, prefix, filename);\n+\tif (sig_filename)\n+\t\twrite_sig(f, hex, filename, sig_filename);\n+\telse\n+\t\tmake_snapshot(f, hex, prefix, filename);\n+\n \tfree(prefix);\n+\tfree(adj_filename);\n }\n","s":{"c":1745906798,"u": 2879}}
],"g": 4178,"chitpc": 0,"ehitpc": 0,"indexed":0
,
"ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}