aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2026-04-06 15:42:51 -0700
committerJunio C Hamano <gitster@pobox.com>2026-04-06 15:42:51 -0700
commitfbd0428cc3011e93a87d02314dc392b06d60877d (patch)
tree35f67248fffbb4eef520204c6923c6da16566fd0
parent87972f30017cc82ea9bab8e20e85bcf1fe84e1d2 (diff)
parentd385845d55e0e3a775fc47ac8d73a5ec41308db3 (diff)
downloadgit-fbd0428cc3011e93a87d02314dc392b06d60877d.tar.xz
Merge branch 'jk/c23-const-preserving-fixes'
Adjust the codebase for C23 that changes functions like strchr() that discarded constness when they return a pointer into a const string to preserve constness. * jk/c23-const-preserving-fixes: config: store allocated string in non-const pointer rev-parse: avoid writing to const string for parent marks revision: avoid writing to const string for parent marks rev-parse: simplify dotdot parsing revision: make handle_dotdot() interface less confusing
-rw-r--r--builtin/config.c7
-rw-r--r--builtin/rev-parse.c40
-rw-r--r--revision.c67
3 files changed, 58 insertions, 56 deletions
diff --git a/builtin/config.c b/builtin/config.c
index 7c4857be62..cf4ba0f7cc 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -838,6 +838,7 @@ static int get_urlmatch(const struct config_location_options *opts,
const char *var, const char *url)
{
int ret;
+ char *section;
char *section_tail;
struct config_display_options display_opts = *_display_opts;
struct string_list_item *item;
@@ -851,8 +852,8 @@ static int get_urlmatch(const struct config_location_options *opts,
if (!url_normalize(url, &config.url))
die("%s", config.url.err);
- config.section = xstrdup_tolower(var);
- section_tail = strchr(config.section, '.');
+ config.section = section = xstrdup_tolower(var);
+ section_tail = strchr(section, '.');
if (section_tail) {
*section_tail = '\0';
config.key = section_tail + 1;
@@ -886,7 +887,7 @@ static int get_urlmatch(const struct config_location_options *opts,
string_list_clear(&values, 1);
free(config.url.url);
- free((void *)config.section);
+ free(section);
return ret;
}
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 01a62800e8..218b5f34d6 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -267,21 +267,20 @@ static int show_file(const char *arg, int output_prefix)
static int try_difference(const char *arg)
{
- char *dotdot;
+ const char *dotdot;
struct object_id start_oid;
struct object_id end_oid;
const char *end;
const char *start;
+ char *to_free;
int symmetric;
static const char head_by_default[] = "HEAD";
if (!(dotdot = strstr(arg, "..")))
return 0;
+ start = to_free = xmemdupz(arg, dotdot - arg);
end = dotdot + 2;
- start = arg;
symmetric = (*end == '.');
-
- *dotdot = 0;
end += symmetric;
if (!*end)
@@ -295,7 +294,7 @@ static int try_difference(const char *arg)
* Just ".."? That is not a range but the
* pathspec for the parent directory.
*/
- *dotdot = '.';
+ free(to_free);
return 0;
}
@@ -308,7 +307,7 @@ static int try_difference(const char *arg)
a = lookup_commit_reference(the_repository, &start_oid);
b = lookup_commit_reference(the_repository, &end_oid);
if (!a || !b) {
- *dotdot = '.';
+ free(to_free);
return 0;
}
if (repo_get_merge_bases(the_repository, a, b, &exclude) < 0)
@@ -318,16 +317,16 @@ static int try_difference(const char *arg)
show_rev(REVERSED, &commit->object.oid, NULL);
}
}
- *dotdot = '.';
+ free(to_free);
return 1;
}
- *dotdot = '.';
+ free(to_free);
return 0;
}
static int try_parent_shorthands(const char *arg)
{
- char *dotdot;
+ const char *mark;
struct object_id oid;
struct commit *commit;
struct commit_list *parents;
@@ -335,38 +334,39 @@ static int try_parent_shorthands(const char *arg)
int include_rev = 0;
int include_parents = 0;
int exclude_parent = 0;
+ char *to_free;
- if ((dotdot = strstr(arg, "^!"))) {
+ if ((mark = strstr(arg, "^!"))) {
include_rev = 1;
- if (dotdot[2])
+ if (mark[2])
return 0;
- } else if ((dotdot = strstr(arg, "^@"))) {
+ } else if ((mark = strstr(arg, "^@"))) {
include_parents = 1;
- if (dotdot[2])
+ if (mark[2])
return 0;
- } else if ((dotdot = strstr(arg, "^-"))) {
+ } else if ((mark = strstr(arg, "^-"))) {
include_rev = 1;
exclude_parent = 1;
- if (dotdot[2]) {
+ if (mark[2]) {
char *end;
- exclude_parent = strtoul(dotdot + 2, &end, 10);
+ exclude_parent = strtoul(mark + 2, &end, 10);
if (*end != '\0' || !exclude_parent)
return 0;
}
} else
return 0;
- *dotdot = 0;
+ arg = to_free = xmemdupz(arg, mark - arg);
if (repo_get_oid_committish(the_repository, arg, &oid) ||
!(commit = lookup_commit_reference(the_repository, &oid))) {
- *dotdot = '^';
+ free(to_free);
return 0;
}
if (exclude_parent &&
exclude_parent > commit_list_count(commit->parents)) {
- *dotdot = '^';
+ free(to_free);
return 0;
}
@@ -387,7 +387,7 @@ static int try_parent_shorthands(const char *arg)
free(name);
}
- *dotdot = '^';
+ free(to_free);
return 1;
}
diff --git a/revision.c b/revision.c
index 31808e3df0..fda405bf65 100644
--- a/revision.c
+++ b/revision.c
@@ -2038,41 +2038,32 @@ static void prepare_show_merge(struct rev_info *revs)
free(prune);
}
-static int dotdot_missing(const char *arg, char *dotdot,
+static int dotdot_missing(const char *full_name,
struct rev_info *revs, int symmetric)
{
if (revs->ignore_missing)
return 0;
- /* de-munge so we report the full argument */
- *dotdot = '.';
die(symmetric
? "Invalid symmetric difference expression %s"
- : "Invalid revision range %s", arg);
+ : "Invalid revision range %s", full_name);
}
-static int handle_dotdot_1(const char *arg, char *dotdot,
+static int handle_dotdot_1(const char *a_name, const char *b_name,
+ const char *full_name, int symmetric,
struct rev_info *revs, int flags,
int cant_be_filename,
struct object_context *a_oc,
struct object_context *b_oc)
{
- const char *a_name, *b_name;
struct object_id a_oid, b_oid;
struct object *a_obj, *b_obj;
unsigned int a_flags, b_flags;
- int symmetric = 0;
unsigned int flags_exclude = flags ^ (UNINTERESTING | BOTTOM);
unsigned int oc_flags = GET_OID_COMMITTISH | GET_OID_RECORD_PATH;
- a_name = arg;
if (!*a_name)
a_name = "HEAD";
- b_name = dotdot + 2;
- if (*b_name == '.') {
- symmetric = 1;
- b_name++;
- }
if (!*b_name)
b_name = "HEAD";
@@ -2081,15 +2072,13 @@ static int handle_dotdot_1(const char *arg, char *dotdot,
return -1;
if (!cant_be_filename) {
- *dotdot = '.';
- verify_non_filename(revs->prefix, arg);
- *dotdot = '\0';
+ verify_non_filename(revs->prefix, full_name);
}
a_obj = parse_object(revs->repo, &a_oid);
b_obj = parse_object(revs->repo, &b_oid);
if (!a_obj || !b_obj)
- return dotdot_missing(arg, dotdot, revs, symmetric);
+ return dotdot_missing(full_name, revs, symmetric);
if (!symmetric) {
/* just A..B */
@@ -2103,7 +2092,7 @@ static int handle_dotdot_1(const char *arg, char *dotdot,
a = lookup_commit_reference(revs->repo, &a_obj->oid);
b = lookup_commit_reference(revs->repo, &b_obj->oid);
if (!a || !b)
- return dotdot_missing(arg, dotdot, revs, symmetric);
+ return dotdot_missing(full_name, revs, symmetric);
if (repo_get_merge_bases(the_repository, a, b, &exclude) < 0) {
commit_list_free(exclude);
@@ -2132,16 +2121,23 @@ static int handle_dotdot(const char *arg,
int cant_be_filename)
{
struct object_context a_oc = {0}, b_oc = {0};
- char *dotdot = strstr(arg, "..");
+ const char *dotdot = strstr(arg, "..");
+ char *tmp;
+ int symmetric = 0;
int ret;
if (!dotdot)
return -1;
- *dotdot = '\0';
- ret = handle_dotdot_1(arg, dotdot, revs, flags, cant_be_filename,
- &a_oc, &b_oc);
- *dotdot = '.';
+ tmp = xmemdupz(arg, dotdot - arg);
+ dotdot += 2;
+ if (*dotdot == '.') {
+ symmetric = 1;
+ dotdot++;
+ }
+ ret = handle_dotdot_1(tmp, dotdot, arg, symmetric, revs, flags,
+ cant_be_filename, &a_oc, &b_oc);
+ free(tmp);
object_context_release(&a_oc);
object_context_release(&b_oc);
@@ -2151,7 +2147,10 @@ static int handle_dotdot(const char *arg,
static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt)
{
struct object_context oc = {0};
- char *mark;
+ const char *mark;
+ char *arg_minus_at = NULL;
+ char *arg_minus_excl = NULL;
+ char *arg_minus_dash = NULL;
struct object *object;
struct object_id oid;
int local_flags;
@@ -2178,18 +2177,17 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
mark = strstr(arg, "^@");
if (mark && !mark[2]) {
- *mark = 0;
- if (add_parents_only(revs, arg, flags, 0)) {
+ arg_minus_at = xmemdupz(arg, mark - arg);
+ if (add_parents_only(revs, arg_minus_at, flags, 0)) {
ret = 0;
goto out;
}
- *mark = '^';
}
mark = strstr(arg, "^!");
if (mark && !mark[2]) {
- *mark = 0;
- if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM), 0))
- *mark = '^';
+ arg_minus_excl = xmemdupz(arg, mark - arg);
+ if (add_parents_only(revs, arg_minus_excl, flags ^ (UNINTERESTING | BOTTOM), 0))
+ arg = arg_minus_excl;
}
mark = strstr(arg, "^-");
if (mark) {
@@ -2203,9 +2201,9 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
}
}
- *mark = 0;
- if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM), exclude_parent))
- *mark = '^';
+ arg_minus_dash = xmemdupz(arg, mark - arg);
+ if (add_parents_only(revs, arg_minus_dash, flags ^ (UNINTERESTING | BOTTOM), exclude_parent))
+ arg = arg_minus_dash;
}
local_flags = 0;
@@ -2240,6 +2238,9 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
out:
object_context_release(&oc);
+ free(arg_minus_at);
+ free(arg_minus_excl);
+ free(arg_minus_dash);
return ret;
}