diff --git a/pkg/chunked/dump/dump.go b/pkg/chunked/dump/dump.go index 0cf8352d9e..d98cee09de 100644 --- a/pkg/chunked/dump/dump.go +++ b/pkg/chunked/dump/dump.go @@ -4,6 +4,7 @@ package dump import ( "bufio" + "encoding/base64" "fmt" "io" "path/filepath" @@ -22,12 +23,12 @@ const ( ESCAPE_LONE_DASH ) -func escaped(val string, escape int) string { +func escaped(val []byte, escape int) string { noescapeSpace := escape&NOESCAPE_SPACE != 0 escapeEqual := escape&ESCAPE_EQUAL != 0 escapeLoneDash := escape&ESCAPE_LONE_DASH != 0 - if escapeLoneDash && val == "-" { + if escapeLoneDash && len(val) == 1 && val[0] == '-' { return fmt.Sprintf("\\x%.2x", val[0]) } @@ -75,8 +76,8 @@ func escaped(val string, escape int) string { return result } -func escapedOptional(val string, escape int) string { - if val == "" { +func escapedOptional(val []byte, escape int) string { + if len(val) == 0 { return "-" } return escaped(val, escape) @@ -136,7 +137,7 @@ func dumpNode(out io.Writer, added map[string]*internal.FileMetadata, links map[ } added[path] = entry - if _, err := fmt.Fprint(out, escaped(path, ESCAPE_STANDARD)); err != nil { + if _, err := fmt.Fprint(out, escaped([]byte(path), ESCAPE_STANDARD)); err != nil { return err } @@ -180,7 +181,7 @@ func dumpNode(out io.Writer, added map[string]*internal.FileMetadata, links map[ } } - if _, err := fmt.Fprint(out, escapedOptional(payload, ESCAPE_LONE_DASH)); err != nil { + if _, err := fmt.Fprint(out, escapedOptional([]byte(payload), ESCAPE_LONE_DASH)); err != nil { return err } @@ -194,14 +195,18 @@ func dumpNode(out io.Writer, added map[string]*internal.FileMetadata, links map[ return err } digest := verityDigests[payload] - if _, err := fmt.Fprint(out, escapedOptional(digest, ESCAPE_LONE_DASH)); err != nil { + if _, err := fmt.Fprint(out, escapedOptional([]byte(digest), ESCAPE_LONE_DASH)); err != nil { return err } - for k, v := range entry.Xattrs { - name := escaped(k, ESCAPE_EQUAL) - value := escaped(v, ESCAPE_EQUAL) + for k, vEncoded := range entry.Xattrs { + v, err := base64.StdEncoding.DecodeString(vEncoded) + if err != nil { + return fmt.Errorf("decode xattr %q: %w", k, err) + } + name := escaped([]byte(k), ESCAPE_EQUAL) + value := escaped(v, ESCAPE_EQUAL) if _, err := fmt.Fprintf(out, " %s=%s", name, value); err != nil { return err } diff --git a/pkg/chunked/dump/dump_test.go b/pkg/chunked/dump/dump_test.go index 1e2b01ff3c..d99693baf8 100644 --- a/pkg/chunked/dump/dump_test.go +++ b/pkg/chunked/dump/dump_test.go @@ -4,6 +4,7 @@ package dump import ( "bytes" + "encoding/base64" "testing" "time" @@ -37,7 +38,7 @@ func TestEscaped(t *testing.T) { for _, test := range tests { t.Run(test.input, func(t *testing.T) { - result := escaped(test.input, test.escape) + result := escaped([]byte(test.input), test.escape) if result != test.want { t.Errorf("got %q, want %q", result, test.want) } @@ -60,7 +61,7 @@ func TestDumpNode(t *testing.T) { Linkname: "", Digest: "sha256:abcdef1234567890", Xattrs: map[string]string{ - "user.key1": "value1", + "user.key1": base64.StdEncoding.EncodeToString([]byte("value1")), }, } @@ -86,7 +87,7 @@ func TestDumpNode(t *testing.T) { ModTime: &modTime, Linkname: "", Xattrs: map[string]string{ - "user.key2": "value2", + "user.key2": base64.StdEncoding.EncodeToString([]byte("value2")), }, } @@ -226,6 +227,5 @@ func TestDumpNode(t *testing.T) { t.Errorf("for %s, got %q, want %q", testCase.name, actual, testCase.expected) } } - } }