Thread (31 messages) 31 messages, 5 authors, 1d ago
WARM1d

[PATCH v3 4/6] t: fix Lexer line count for $() inside double-quoted strings

From: Michael Montalbo via GitGitGadget <hidden>
Date: 2026-07-03 04:54:36
Subsystem: the rest · Maintainer: Linus Torvalds

From: Michael Montalbo <redacted>

scan_dqstring's post-loop newline counter re-counts newlines that
were already counted during recursive parsing of $() bodies.  This
happens because scan_dollar returns text containing newlines (from
multi-line command substitutions), and the catch-all counter at the
end of scan_dqstring counts all of them again.

Fix this by counting newlines inline as non-special characters are
consumed, and removing the post-loop catch-all.  Each newline is
now counted exactly once: literal newlines at the inline match,
line splices at the backslash handler, and $() newlines by
scan_token during the recursive parse.

This is a latent bug: any consumer that relies on token line
numbers rather than byte offsets would get incorrect results for
tokens following a multi-line $() inside a double-quoted string.
chainlint is not affected because it annotates the original body
text using byte offsets, not token line numbers.

Signed-off-by: Michael Montalbo <redacted>
---
 t/lib-shell-parser.pl | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/t/lib-shell-parser.pl b/t/lib-shell-parser.pl
index 5c435c5d05..17fbf461b1 100644
--- a/t/lib-shell-parser.pl
+++ b/t/lib-shell-parser.pl
@@ -93,8 +93,12 @@ sub scan_dqstring {
 	my $b = $self->{buff};
 	my $s = '"';
 	while (1) {
-		# slurp up non-special characters
-		$s .= $1 if $$b =~ /\G([^"\$\\]+)/gc;
+		# Slurp non-special characters; count newlines here because
+		# newlines inside $() are already counted by the recursive parse.
+		if ($$b =~ /\G([^"\$\\]+)/gc) {
+			$s .= $1;
+			$self->{lineno} += $1 =~ tr/\n//;
+		}
 		# handle special characters
 		last unless $$b =~ /\G(.)/sgc;
 		my $c = $1;
@@ -111,7 +115,6 @@ sub scan_dqstring {
 		}
 		die("internal error scanning dq-string '$c'\n");
 	}
-	$self->{lineno} += () = $s =~ /\n/sg;
 	return $s;
 }
 
-- 
gitgitgadget
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help