shithub: trueawk

Download patch

ref: ddfd88a55337d1380fc38126326b2cc8d1dfa4cd
parent: 92aee59e6d4a1f052f2bede3f0c8b8e7440512a3
parent: 4236e5a9f45da97c0565cf0bc2a265d4c1d62af5
author: ozan yigit <ozan.yigit@gmail.com>
date: Thu Sep 7 20:21:09 EDT 2023

Merge branch 'mpinjr-fix-re-clobbering' into staging

--- a/awkgram.y
+++ b/awkgram.y
@@ -204,7 +204,7 @@
 		{ $$ = op2(BOR, notnull($1), notnull($3)); }
 	| ppattern and ppattern %prec AND
 		{ $$ = op2(AND, notnull($1), notnull($3)); }
-	| ppattern MATCHOP reg_expr	{ $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); }
+	| ppattern MATCHOP reg_expr	{ $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); free($3); }
 	| ppattern MATCHOP ppattern
 		{ if (constnode($3)) {
 			$$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0));
@@ -232,7 +232,7 @@
 	| pattern LE pattern		{ $$ = op2($2, $1, $3); }
 	| pattern LT pattern		{ $$ = op2($2, $1, $3); }
 	| pattern NE pattern		{ $$ = op2($2, $1, $3); }
-	| pattern MATCHOP reg_expr	{ $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); }
+	| pattern MATCHOP reg_expr	{ $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); free($3); }
 	| pattern MATCHOP pattern
 		{ if (constnode($3)) {
 			$$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0));
@@ -282,7 +282,7 @@
 
 re:
 	   reg_expr
-		{ $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); }
+		{ $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); free($1); }
 	| NOT re	{ $$ = op1(NOT, notnull($2)); }
 	;
 
@@ -388,7 +388,7 @@
 		  $$ = op2(INDEX, $3, (Node*)$5); }
 	| '(' pattern ')'		{ $$ = $2; }
 	| MATCHFCN '(' pattern comma reg_expr ')'
-		{ $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa($5, 1)); }
+		{ $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa($5, 1)); free($5); }
 	| MATCHFCN '(' pattern comma pattern ')'
 		{ if (constnode($5)) {
 			$$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa(strnode($5), 1));
@@ -399,13 +399,13 @@
 	| SPLIT '(' pattern comma varname comma pattern ')'     /* string */
 		{ $$ = op4(SPLIT, $3, makearr($5), $7, (Node*)STRING); }
 	| SPLIT '(' pattern comma varname comma reg_expr ')'    /* const /regexp/ */
-		{ $$ = op4(SPLIT, $3, makearr($5), (Node*)makedfa($7, 1), (Node *)REGEXPR); }
+		{ $$ = op4(SPLIT, $3, makearr($5), (Node*)makedfa($7, 1), (Node *)REGEXPR); free($7); }
 	| SPLIT '(' pattern comma varname ')'
 		{ $$ = op4(SPLIT, $3, makearr($5), NIL, (Node*)STRING); }  /* default */
 	| SPRINTF '(' patlist ')'	{ $$ = op1($1, $3); }
 	| string	 		{ $$ = celltonode($1, CCON); }
 	| subop '(' reg_expr comma pattern ')'
-		{ $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, rectonode()); }
+		{ $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, rectonode()); free($3); }
 	| subop '(' pattern comma pattern ')'
 		{ if (constnode($3)) {
 			$$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, rectonode());
@@ -413,7 +413,7 @@
 		  } else
 			$$ = op4($1, (Node *)1, $3, $5, rectonode()); }
 	| subop '(' reg_expr comma pattern comma var ')'
-		{ $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, $7); }
+		{ $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, $7); free($3); }
 	| subop '(' pattern comma pattern comma var ')'
 		{ if (constnode($3)) {
 			$$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, $7);
--- a/lex.c
+++ b/lex.c
@@ -554,7 +554,7 @@
 	*bp = 0;
 	if (c == 0)
 		SYNTAX("non-terminated regular expression %.10s...", buf);
-	yylval.s = buf;
+	yylval.s = tostring(buf);
 	unput('/');
 	RET(REGEXPR);
 }
--- a/testdir/T.misc
+++ b/testdir/T.misc
@@ -504,3 +504,9 @@
 echo 'E 2' >foo1
 (trap '' PIPE; "$awk" 'BEGIN { print "hi"; }' 2>/dev/null; echo "E $?" >foo2) | :
 cmp -s foo1 foo2 || echo 'BAD: T.misc exit status on I/O error'
+
+# Check for clobbering of the lexer's regular expression buffer.
+# If the output is "a1" instead of "1b", /b/ clobbered /a/.
+echo 1b >foo1
+echo ab | $awk '{ sub(/a/, "b" ~ /b/); print }' >foo2
+cmp -s foo1 foo2 || echo 'BAD: T.misc lexer regex buffer clobbered'
--