From 56a24d518362e88339bbd34b9eb60d643de1b730 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 23 Apr 2026 20:12:14 +0200 Subject: [PATCH] fix container inspect output to not escape html chars The default std json behavior is to escape &, < and >. Because we print to the terminal we do not want escapes and rather the real chars. That is what PrintGenericJSON() does but because we have custom MarshalJSON() overwrite on the type which called json.Marshal() this option was not carried into that. The inner type must not escape it. This is not a problem in the other direction because the outer json.Marshal call will still escape the chars returned from the inner MarshalJSON() result if needed. Fixes: #28560 Signed-off-by: Paul Holzinger --- libpod/define/container_inspect.go | 11 +++++++++-- test/e2e/inspect_test.go | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go index ba2df4fab9..51ad4a0da7 100644 --- a/libpod/define/container_inspect.go +++ b/libpod/define/container_inspect.go @@ -1,6 +1,7 @@ package define import ( + "bytes" "encoding/json" "fmt" "strings" @@ -153,11 +154,16 @@ func (insp *InspectContainerConfig) UnmarshalJSON(data []byte) error { } func (insp *InspectContainerConfig) MarshalJSON() ([]byte, error) { + buf := bytes.Buffer{} + enc := json.NewEncoder(&buf) + enc.SetEscapeHTML(false) + // the alias is needed otherwise MarshalJSON will type Alias InspectContainerConfig conf := (*Alias)(insp) if !insp.V4PodmanCompatMarshal { - return json.Marshal(conf) + err := enc.Encode(conf) + return buf.Bytes(), err } type v4InspectContainerConfig struct { @@ -171,7 +177,8 @@ func (insp *InspectContainerConfig) MarshalJSON() ([]byte, error) { StopSignal: uint(stopSignal), Alias: conf, } - return json.Marshal(newConf) + err := enc.Encode(newConf) + return buf.Bytes(), err } // InspectRestartPolicy holds information about the container's restart policy. diff --git a/test/e2e/inspect_test.go b/test/e2e/inspect_test.go index d1e0b776a4..d15c8d301e 100644 --- a/test/e2e/inspect_test.go +++ b/test/e2e/inspect_test.go @@ -263,6 +263,15 @@ var _ = Describe("Podman inspect", func() { Expect(baseJSON[0]).To(HaveField("Name", ctrName)) }) + It("podman inspect should not escape special chars", func() { + ctrName := "testlabel" + podmanTest.PodmanExitCleanly("create", "--name", ctrName, "--label", "abc=&&**<>123", ALPINE, "sh") + + // see https://github.com/containers/podman/issues/28560 + inspect := podmanTest.PodmanExitCleanly("inspect", ctrName) + Expect(inspect.OutputToString()).To(ContainSubstring(`"abc=&&**<>123"`)) + }) + It("podman inspect - HostConfig.SecurityOpt ", func() { if !selinux.GetEnabled() { Skip("SELinux not enabled")