package main
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
)
func TestRunPipedConnectsStdoutToStdin(t *testing.T) {
err := runPiped(context.Background(),
[]string{"echo", "-n", "hello"},
[]string{"cat"},
)
if err != nil {
t.Fatalf("runPiped: %v", err)
}
}
// TestRunPipedNoShellInjection reproduces the real bug: the previous
// `sh -c "docker save '<tag>' | k3s ctr images import -"` pattern's
// quoting (shellQuote, a bare wrap in single quotes) didn't escape an
// embedded single quote, so a tag/version string containing one could
// break out and run arbitrary shell commands. runPiped never invokes a
// shell at all, so the same string is inert — it's just a literal
// argument to `cat`, not code.
func TestRunPipedNoShellInjection(t *testing.T) {
dir := t.TempDir()
proof := filepath.Join(dir, "proof")
malicious := "gitfed:1.2.10'; touch " + proof + "; echo '"
err := runPiped(context.Background(),
[]string{"echo", "-n", malicious},
[]string{"cat"},
)
if err != nil {
t.Fatalf("runPiped: %v", err)
}
if _, statErr := os.Stat(proof); statErr == nil {
t.Fatal("injection succeeded: a shell interpreted the piped argument")
}
}
func TestRunPipedFirstCommandFails(t *testing.T) {
err := runPiped(context.Background(),
[]string{"sh", "-c", "echo bad-times >&2; exit 3"},
[]string{"cat"},
)
if err == nil {
t.Fatal("expected an error when the first command exits non-zero")
}
if !strings.Contains(err.Error(), "bad-times") {
t.Errorf("expected the first command's stderr in the error, got: %v", err)
}
}
func TestRunPipedSecondCommandFails(t *testing.T) {
err := runPiped(context.Background(),
[]string{"echo", "hi"},
[]string{"sh", "-c", "echo nope >&2; exit 3"},
)
if err == nil {
t.Fatal("expected an error when the second command exits non-zero")
}
if !strings.Contains(err.Error(), "nope") {
t.Errorf("expected the second command's stderr in the error, got: %v", err)
}
}