74 lines
2.5 KiB
Go
74 lines
2.5 KiB
Go
package tui
|
|
|
|
import (
|
|
"os/exec"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestShellQuoteArgsRoundTrip guards the updater's poll-script generation: cv fields
|
|
// (e.g. cert_dir_path) are operator-entered and get embedded into a shell script run
|
|
// inside the updater container. If shellQuote/shellQuoteArgs mis-escapes a value, that's
|
|
// a command-injection bug, not just a cosmetic one. This feeds tricky values through a
|
|
// real `sh` and checks they come back out exactly as they went in.
|
|
func TestShellQuoteArgsRoundTrip(t *testing.T) {
|
|
if _, err := exec.LookPath("sh"); err != nil {
|
|
t.Skip("sh not available")
|
|
}
|
|
|
|
cases := [][]string{
|
|
{"simple"},
|
|
{"has space"},
|
|
{"it's got a quote"},
|
|
{"$(echo injected)"},
|
|
{"a;b|c&d"},
|
|
{"back`tick`"},
|
|
{"multi", "arg space", "o'clock", "$HOME", "'"},
|
|
}
|
|
|
|
for _, args := range cases {
|
|
script := "printf '%s\\n' " + shellQuoteArgs(args)
|
|
out, err := exec.Command("sh", "-c", script).Output()
|
|
if err != nil {
|
|
t.Fatalf("sh failed for %v: %v", args, err)
|
|
}
|
|
got := strings.Split(strings.TrimRight(string(out), "\n"), "\n")
|
|
if !reflect.DeepEqual(got, args) {
|
|
t.Errorf("round trip mismatch for %v: got %v", args, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestBuildRecreateCmdUsesLivePort guards against the updater silently reverting a host
|
|
// port that was changed by hand after install: the recreate command must reference the
|
|
// live $PORT read at recreate time, not replay the port typed into the wizard.
|
|
func TestBuildRecreateCmdUsesLivePort(t *testing.T) {
|
|
if _, err := exec.LookPath("sh"); err != nil {
|
|
t.Skip("sh not available")
|
|
}
|
|
|
|
args := []string{"run", "-d", "-p", "9999:8080", "--name", "app-dono-cliente"}
|
|
cmd := buildRecreateCmd(args, "9999")
|
|
|
|
if strings.Contains(cmd, "9999:8080") {
|
|
t.Fatalf("recreate command still contains the wizard-time port literal: %s", cmd)
|
|
}
|
|
if !strings.Contains(cmd, `"$PORT:8080"`) {
|
|
t.Fatalf("recreate command missing live $PORT reference: %s", cmd)
|
|
}
|
|
|
|
// Swap the leading `docker` for `printf` so we can inspect the argv sh would have
|
|
// passed to docker, with PORT set as the poll script would set it live.
|
|
script := "PORT=8081\n" + strings.Replace(cmd, "docker ", "printf '%s\\n' ", 1)
|
|
out, err := exec.Command("sh", "-c", script).Output()
|
|
if err != nil {
|
|
t.Fatalf("sh failed: %v", err)
|
|
}
|
|
got := strings.Split(strings.TrimRight(string(out), "\n"), "\n")
|
|
want := []string{"run", "-d", "-p", "8081:8080", "--name", "app-dono-cliente"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("got %v, want %v", got, want)
|
|
}
|
|
}
|