From 821b552305b2afccee092ac08863ba4058badc72 Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Fri, 16 Oct 2026 06:21:33 -1000 Subject: Keep string literals behind const pointers Git's DEVELOPER=1 build turns on -Wwrite-strings as an error, and the literals stored through plain char pointers failed cgit's own objects there. The exec filter's argv takes the cast execvp needs once, the way git's run-command does. --- source/cgit.c | 2 +- source/cgit.h | 24 ++++++++++++------------ source/filter.c | 7 ++++--- source/filter.h | 8 ++++---- source/shared.c | 2 +- source/shared.h | 2 +- source/ui-diff.c | 4 ++-- source/ui-plain.c | 2 +- source/ui-repolist.c | 8 ++++---- source/ui-shared.c | 41 +++++++++++++++++------------------------ source/ui-snapshot.c | 12 ++++++------ 11 files changed, 53 insertions(+), 59 deletions(-) (limited to 'source') diff --git a/source/cgit.c b/source/cgit.c index 8dc90e6..2ef4cf1 100644 --- a/source/cgit.c +++ b/source/cgit.c @@ -1010,7 +1010,7 @@ static char *guess_defbranch(void) ref = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), "HEAD", 0, &oid, NULL); if (!ref || !skip_prefix(ref, "refs/heads/", &refname)) - return "master"; + return xstrdup("master"); return xstrdup(refname); } diff --git a/source/cgit.h b/source/cgit.h index 30f97c5..5b92632 100644 --- a/source/cgit.h +++ b/source/cgit.h @@ -84,7 +84,7 @@ struct cgit_repo { char *defbranch; char *module_link; struct string_list readme; - char *section; + const char *section; char *clone_url; char *logo; char *logo_link; @@ -166,7 +166,7 @@ struct cgit_query { int has_difftype; char *raw; char *repo; - char *page; + const char *page; char *search; char *grep; char *head; @@ -188,28 +188,28 @@ struct cgit_query { }; struct cgit_config { - char *agefile; - char *cache_root; + const char *agefile; + const char *cache_root; char *clone_prefix; char *clone_url; - char *favicon; + const char *favicon; char *footer; char *head_include; char *header; - char *logo; + const char *logo; char *logo_link; char *mimetype_file; char *module_link; char *project_list; struct string_list readme; struct string_list css; - char *robots; - char *root_title; - char *root_desc; + const char *robots; + const char *root_title; + const char *root_desc; char *root_readme; - char *script_name; - char *section; - char *repository_sort; + const char *script_name; + const char *section; + const char *repository_sort; // Always ends with a slash. char *virtual_root; char *strict_export; diff --git a/source/filter.c b/source/filter.c index 6e16537..3ffd077 100644 --- a/source/filter.c +++ b/source/filter.c @@ -47,7 +47,8 @@ static int open_exec_filter(struct cgit_filter *base, va_list ap) // cgit ignores SIGPIPE and the disposition survives exec, so a // filter that writes to a closed pipe would otherwise carry on. signal(SIGPIPE, SIG_DFL); - execvp(filter->cmd, filter->argv); + // execvp leaves argv alone, but its prototype predates const. + execvp(filter->cmd, (char *const *)filter->argv); // The child shares the parent's page buffer, cache lock and exit // handlers, so it must not die through them. fprintf(stderr, "[cgit] Unable to exec filter %s: %s\n", filter->cmd, strerror(errno)); @@ -95,7 +96,7 @@ static void cleanup_exec_filter(struct cgit_filter *base) free(filter->argv); filter->argv = NULL; - free(filter->cmd); + free((char *)filter->cmd); filter->cmd = NULL; } @@ -116,7 +117,7 @@ static struct cgit_filter *new_exec_filter(const char *cmd, int argument_count) return &filter->base; } -void cgit_exec_filter_init(struct cgit_exec_filter *filter, char *cmd, char **argv) +void cgit_exec_filter_init(struct cgit_exec_filter *filter, const char *cmd, const char **argv) { memset(filter, 0, sizeof(*filter)); filter->base.open = open_exec_filter; diff --git a/source/filter.h b/source/filter.h index 70fa4ff..2c8e7b7 100644 --- a/source/filter.h +++ b/source/filter.h @@ -26,16 +26,16 @@ struct cgit_filter { struct cgit_exec_filter { struct cgit_filter base; - char *cmd; - char **argv; + const char *cmd; + const char **argv; int old_stdout; int pid; }; extern struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype); -extern void cgit_exec_filter_init(struct cgit_exec_filter *filter, char *cmd, - char **argv); +extern void cgit_exec_filter_init(struct cgit_exec_filter *filter, const char *cmd, + const char **argv); /* * Redirect stdout into the filter and pass it the variadic arguments its type diff --git a/source/shared.c b/source/shared.c index a5c54ee..a6a5106 100644 --- a/source/shared.c +++ b/source/shared.c @@ -24,7 +24,7 @@ typedef struct { struct cgit_repolist cgit_repolist; struct cgit_context ctx; -char *cgit_default_repo_desc = "[no description]"; +char cgit_default_repo_desc[] = "[no description]"; // A diff line that arrived in pieces and is still waiting for its end, see // emit_line. diff --git a/source/shared.h b/source/shared.h index 13932c8..129cfb7 100644 --- a/source/shared.h +++ b/source/shared.h @@ -11,7 +11,7 @@ #include "cgit.h" -extern char *cgit_default_repo_desc; +extern char cgit_default_repo_desc[]; typedef void (*filepair_fn)(struct diff_filepair *pair); typedef void (*linediff_fn)(char *line, int len); diff --git a/source/ui-diff.c b/source/ui-diff.c index a5202b5..805733a 100644 --- a/source/ui-diff.c +++ b/source/ui-diff.c @@ -227,8 +227,8 @@ static char *abbrev_oid(const struct object_id *oid) return xstrdup(repo_find_unique_abbrev(the_repository, oid, DEFAULT_ABBREV)); } -static void print_file_header(const struct object_id *old_oid, char *old_path, unsigned old_mode, - const struct object_id *new_oid, char *new_path, unsigned new_mode) +static void print_file_header(const struct object_id *old_oid, const char *old_path, unsigned old_mode, + const struct object_id *new_oid, const char *new_path, unsigned new_mode) { char *old_abbrev, *new_abbrev; int subproject; diff --git a/source/ui-plain.c b/source/ui-plain.c index 6d02051..2463cfc 100644 --- a/source/ui-plain.c +++ b/source/ui-plain.c @@ -234,7 +234,7 @@ void cgit_print_plain(void) if (!path_items.match) { // The walk is never handed an entry for the top of the tree // itself, so the listing it would have opened is opened here. - path_items.match = ""; + paths.nr = 0; walk.dir_len = -1; print_dir("", 0, ""); walk.response = RESPONSE_LISTING; diff --git a/source/ui-repolist.c b/source/ui-repolist.c index 6dcc976..1394048 100644 --- a/source/ui-repolist.c +++ b/source/ui-repolist.c @@ -266,7 +266,7 @@ static void print_repo_row(const char *currenturl, int sublevel) static void print_pager(int total, int pagelen, char *search, char *sort) { int i, ofs; - char *class; + const char *class; html("