From 8577be72e8ec7fa597c7196bca0705d2c66083e0 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Mon, 22 Feb 2021 15:08:40 +0100 Subject: podman cp: treat /dev/stdout correctly /dev/stdout should not be treated as "-" to remain compatible with Docker and to have a more consistent and idiomatic interface. Fixes: #9362 Signed-off-by: Valentin Rothberg --- cmd/podman/containers/cp.go | 19 ++++++++++++++++++- test/system/065-cp.bats | 4 ++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/cmd/podman/containers/cp.go b/cmd/podman/containers/cp.go index d3b904412..b29a95707 100644 --- a/cmd/podman/containers/cp.go +++ b/cmd/podman/containers/cp.go @@ -121,7 +121,9 @@ func copyFromContainer(container string, containerPath string, hostPath string) return err } + isStdout := false if hostPath == "-" { + isStdout = true hostPath = os.Stdout.Name() } @@ -152,10 +154,16 @@ func copyFromContainer(container string, containerPath string, hostPath string) hostBaseName = filepath.Base(hostInfo.LinkTarget) } + if !isStdout { + if err := validateFileInfo(hostInfo); err != nil { + return errors.Wrap(err, "invalid destination") + } + } + reader, writer := io.Pipe() hostCopy := func() error { defer reader.Close() - if hostInfo.LinkTarget == os.Stdout.Name() { + if isStdout { _, err := io.Copy(os.Stdout, reader) return err } @@ -363,3 +371,12 @@ func containerParentDir(container string, containerPath string) (string, error) workDir = filepath.Join(workDir, containerPath) return filepath.Dir(workDir), nil } + +// validateFileInfo returns an error if the specified FileInfo doesn't point to +// a directory or a regular file. +func validateFileInfo(info *copy.FileInfo) error { + if info.Mode.IsDir() || info.Mode.IsRegular() { + return nil + } + return errors.Errorf("%q must be a directory or a regular file", info.LinkTarget) +} diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats index 0fcc437d4..87a961160 100644 --- a/test/system/065-cp.bats +++ b/test/system/065-cp.bats @@ -508,6 +508,10 @@ load helpers run_podman exec cpcontainer sh -c "echo '$rand_content' > /tmp/file.txt" run_podman exec cpcontainer touch /tmp/empty.txt + # Make sure that only "-" gets special treatment. "/dev/stdout" + run_podman 125 cp cpcontainer:/tmp/file.txt /dev/stdout + is "$output" 'Error: invalid destination: "/dev/stdout" must be a directory or a regular file' + # Copying from stdout will always compress. So let's copy the previously # created file from the container via stdout, untar the archive and make # sure the file exists with the expected content. -- cgit v1.2.3-54-g00ecf