From 716bfae0c925e70f1fbd1717ee7f06fd076e03ce Mon Sep 17 00:00:00 2001 From: Connor Taffe Date: Thu, 28 Aug 2025 14:12:14 -0500 Subject: [PATCH] Quote rc commands if necessary Surround an argument with quotes before assembling it into a command base on whether a command requires quoting to be parsed by rc as it was received through args. If the arg contains any of rc's special characters or whitespace as documented in rc(1), it is quoted and any ' characters are escaped to ''. The quoted command string is also appended to the dump command. Fixes #135 --- acme/Watch/main.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/acme/Watch/main.go b/acme/Watch/main.go index 3dab1606..2bff5f3d 100644 --- a/acme/Watch/main.go +++ b/acme/Watch/main.go @@ -47,6 +47,8 @@ import ( "9fans.net/go/acme" ) +const rcspecial = "#;&|^$=`'{}()<> \t\n" + var args []string var win *acme.Win var needrun = make(chan bool, 1) @@ -64,6 +66,8 @@ func main() { flag.Parse() args = flag.Args() + escaped := rcquote(args) + var err error win, err = acme.New() if err != nil { @@ -80,7 +84,7 @@ func main() { } win.Ctl(cmd) win.Fprintf("tag", "Get Kill Quit ") - win.Fprintf("body", "%% %s\n", strings.Join(args, " ")) + win.Fprintf("body", "%% %s\n", escaped) needrun <- true go events() @@ -329,3 +333,18 @@ func runBackground(id int, dir string) { // Continue loop with lock held } } + +func rcquote(args []string) string { + var b strings.Builder + for i, arg := range args { + if i != 0 { + b.WriteRune(' ') + } + if strings.ContainsAny(arg, rcspecial) { + fmt.Fprintf(&b, "'%s'", strings.ReplaceAll(arg, "'", "''")) + } else { + b.WriteString(arg) + } + } + return b.String() +}