Passing a tree OID to git-last-modified(1) would trigger BUG behavior.
git last-modified HEAD^{tree}
BUG: builtin/last-modified.c:456: paths remaining beyond boundary in last-modifiedFix this error by verifying the parsed revision is peels to a commit-ish.
While at it, also fix a memory leak in populate_paths_from_revs().
Reported-by: Gusted <gusted@codeberg.org> Signed-off-by: Toon Claes <toon@iotcl.com> --- Recently there was a bug reported[1] passing a tree OID triggers a BUG:
$ git last-modified fb06ce04173d47aaaa498385621cba8b8dfd7584
BUG: builtin/last-modified.c:456: paths remaining beyond boundary in last-modified
[1] 690163 IOT instruction (core dumped) git last-modified `fb06ce04173d47aaaa498385621cba8b8dfd7584` is the tree commit id of web_src. I
suppose this should've returned a nice error message or blank output.Fix this bug by checking the revision argument.
[1]: https://lore.kernel.org/git/03f96860-29fc-42a7-a220-c3ec65eb8516@codeberg.org/ --- builtin/last-modified.c | 15 +++++++++++---- t/t8020-last-modified.sh | 5 +++++ 2 files changed, 16 insertions(+), 4 deletions(-)
Show changes to 2 files +16 −4
builtin/last-modified.c, t/t8020-last-modified.sh
diff --git a/builtin/last-modified.c b/builtin/last-modified.c index c80f0535f6..cac94e384d 100644 --- a/builtin/last-modified.c +++ b/builtin/last-modified.c @@ -123,7 +123,7 @@ static void add_path_from_diff(struct diff_queue_struct *q, static int populate_paths_from_revs(struct last_modified *lm) { - int num_interesting = 0; + int num_interesting = 0, ret = 0; struct diff_options diffopt; /* @@ -145,8 +145,15 @@ static int populate_paths_from_revs(struct last_modified *lm) if (obj->item->flags & UNINTERESTING) continue; - if (num_interesting++) - return error(_("last-modified can only operate on one tree at a time")); + if (num_interesting++) { + ret = error(_("last-modified can only operate on one tree at a time")); + break; + } + + if (!repo_peel_to_type(lm->rev.repo, obj->path, 0, obj->item, OBJ_COMMIT)) { + ret = error(_("revision argument is not a commit-ish")); + break; + } diff_tree_oid(lm->rev.repo->hash_algo->empty_tree, &obj->item->oid, "", &diffopt); @@ -154,7 +161,7 @@ static int populate_paths_from_revs(struct last_modified *lm) } clear_pathspec(&diffopt.pathspec); - return 0; + return ret; } static void last_modified_emit(struct last_modified *lm, diff --git a/t/t8020-last-modified.sh b/t/t8020-last-modified.sh index 50f4312f71..d0d52add05 100755 --- a/t/t8020-last-modified.sh +++ b/t/t8020-last-modified.sh @@ -235,4 +235,9 @@ test_expect_success 'last-modified complains about unknown arguments' ' grep "unknown last-modified argument: --foo" err ' +test_expect_success 'last-modified expects commit-ish' ' + test_must_fail git last-modified HEAD^{tree} 2>err && + grep "revision argument is not a commit-ish" err +' + test_done --- base-commit: d529f3a197364881746f558e5652f0236131eb86 change-id: 20260112-toon-last-modified-tree-fdd96b2feaf7