When the -L argument to "git log" is passed the degenerate regular expression "$" (as in "-L :$:line-range.c"), this results in an infinite loop in find_funcname_matching_regexp(). Modify find_funcname_matching_regexp to correctly match the entire line instead of the zero-width match at eol and update the loop condition to prevent an infinite loop in the event of other undiscovered corner cases. Originally reported in <https://stackoverflow.com/q/74690545/147356>. Signed-off-by: Lars Kellogg-Stedman <lars@xxxxxxxxxx> --- This modifies my earlier patch so that instead of failing, the regular expression '$' correctly matches any function name (and so always returns the first function in the named file). This makes '$' behave the same as '.' and '^'. The primary change is that we pre-decrement the beginning-of-line marker ('bol') before comparing it to '\n'. In the case of '$', where we start with bol == eol, this ensures that bol will find the beginning of the line on which the match occurred. line-range.c | 6 +++--- t/t4211-line-log.sh | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/line-range.c b/line-range.c index 955a8a9535..b0e26e7f9d 100644 --- a/line-range.c +++ b/line-range.c @@ -135,7 +135,7 @@ static const char *find_funcname_matching_regexp(xdemitconf_t *xecfg, const char { int reg_error; regmatch_t match[1]; - while (1) { + while (*start) { const char *bol, *eol; reg_error = regexec(regexp, start, 1, match, 0); if (reg_error == REG_NOMATCH) @@ -148,8 +148,7 @@ static const char *find_funcname_matching_regexp(xdemitconf_t *xecfg, const char /* determine extent of line matched */ bol = start+match[0].rm_so; eol = start+match[0].rm_eo; - while (bol > start && *bol != '\n') - bol--; + while (bol > start && *--bol != '\n'); if (*bol == '\n') bol++; while (*eol && *eol != '\n') @@ -161,6 +160,7 @@ static const char *find_funcname_matching_regexp(xdemitconf_t *xecfg, const char return bol; start = eol; } + return NULL; } static const char *parse_range_funcname( diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh index ac9e4d0928..19db07a8df 100755 --- a/t/t4211-line-log.sh +++ b/t/t4211-line-log.sh @@ -315,4 +315,26 @@ test_expect_success 'line-log with --before' ' test_cmp expect actual ' +test_expect_success 'setup tests for zero-width regular expressions' ' + cat > expect <<-EOF + Modify func1() in file.c + Add func1() and func2() in file.c + EOF +' + +test_expect_success 'zero-width regex $ matches any function name' ' + git log --format="%s" --no-patch "-L:$:file.c" >actual && + test_cmp expect actual +' + +test_expect_success 'zero-width regex ^ matches any function name' ' + git log --format="%s" --no-patch "-L:^:file.c" >actual && + test_cmp expect actual +' + +test_expect_success 'zero-width regex . matches any function name' ' + git log --format="%s" --no-patch "-L:.:file.c" >actual && + test_cmp expect actual +' + test_done -- 2.38.1