onetrueawk / awk

One true awk
Other
1.98k stars 159 forks source link

Fix assignment operand handling to preserve ARGV #143

Closed mpinjr closed 2 years ago

mpinjr commented 2 years ago

After initialization, ARGV is supposed to be under the control of the application (the awk script). However, when fulfilling the assignment specified by a "name=value" operand, the implementation modifies the operand's ARGV entry behind the application's back, truncating it.

This commit undoes the munge before returning control to the application.

$ echo | ./master 'BEGIN { print ARGV[1] } { print ARGV[1] }' name=value name=value name

$ echo | ./a.out 'BEGIN { print ARGV[1] } { print ARGV[1] }' name=value name=value name=value

History: setclvar had been modifying its string argument without ill-effect from the beginning (7th Edition UNIX, 1979) [1], when, in 1989, SVR4 switched the source of the argument from argv to ARGV [2]. The former cannot be accessed by the application, the latter can. Thus, a private implementation detail unintentionally became a public defect.

[1] https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/awk/lib.c [2] https://github.com/danfuzz/one-true-awk/blob/master/versions/1989-10-11/lib.c