]> git.ipfire.org Git - thirdparty/git.git/commitdiff
rev-parse: avoid writing to const string for parent marks
authorJeff King <peff@peff.net>
Thu, 26 Mar 2026 19:14:24 +0000 (15:14 -0400)
committerJunio C Hamano <gitster@pobox.com>
Thu, 26 Mar 2026 19:47:17 +0000 (12:47 -0700)
The previous commit cleared up some const confusion in handling parent
marks in revision.c, but we have roughly the same code duplicated in
rev-parse. This one is much easier to fix, because the handling of the
shortened string is all done in one place, after detecting any marks
(but without shortening the string between marks).

  As a side note, I suspect this means that it behaves differently than
  the revision.c parser for weird stuff like "foo^!^@^-", but that is
  outside the scope of this patch.

While we are here, let's also rename the variable "dotdot", which is
totally misleading (and which we already fixed in revision.c long ago
via f632dedd8d (handle_revision_arg: stop using "dotdot" as a generic
pointer, 2017-05-19)).

Doing that here makes the diff a little messier, but it also lets the
compiler help us make sure we did not miss any stray mentions of the
variable while we are changing its semantics.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/rev-parse.c

index 5da95371134027c98890847fb29a5306058643eb..218b5f34d6a893a942e846eb1fccaf781b77c448 100644 (file)
@@ -326,7 +326,7 @@ static int try_difference(const char *arg)
 
 static int try_parent_shorthands(const char *arg)
 {
-       char *dotdot;
+       const char *mark;
        struct object_id oid;
        struct commit *commit;
        struct commit_list *parents;
@@ -334,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;
        }
 
@@ -386,7 +387,7 @@ static int try_parent_shorthands(const char *arg)
                free(name);
        }
 
-       *dotdot = '^';
+       free(to_free);
        return 1;
 }