Merge pull request #2037 from giuseppe/fix-decoding-xattr
chunked, composefs: fix decoding of xattrs
This commit is contained in:
commit
398fe57538
|
|
@ -4,6 +4,7 @@ package dump
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -22,12 +23,12 @@ const (
|
||||||
ESCAPE_LONE_DASH
|
ESCAPE_LONE_DASH
|
||||||
)
|
)
|
||||||
|
|
||||||
func escaped(val string, escape int) string {
|
func escaped(val []byte, escape int) string {
|
||||||
noescapeSpace := escape&NOESCAPE_SPACE != 0
|
noescapeSpace := escape&NOESCAPE_SPACE != 0
|
||||||
escapeEqual := escape&ESCAPE_EQUAL != 0
|
escapeEqual := escape&ESCAPE_EQUAL != 0
|
||||||
escapeLoneDash := escape&ESCAPE_LONE_DASH != 0
|
escapeLoneDash := escape&ESCAPE_LONE_DASH != 0
|
||||||
|
|
||||||
if escapeLoneDash && val == "-" {
|
if escapeLoneDash && len(val) == 1 && val[0] == '-' {
|
||||||
return fmt.Sprintf("\\x%.2x", val[0])
|
return fmt.Sprintf("\\x%.2x", val[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,8 +76,8 @@ func escaped(val string, escape int) string {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func escapedOptional(val string, escape int) string {
|
func escapedOptional(val []byte, escape int) string {
|
||||||
if val == "" {
|
if len(val) == 0 {
|
||||||
return "-"
|
return "-"
|
||||||
}
|
}
|
||||||
return escaped(val, escape)
|
return escaped(val, escape)
|
||||||
|
|
@ -136,7 +137,7 @@ func dumpNode(out io.Writer, added map[string]*internal.FileMetadata, links map[
|
||||||
}
|
}
|
||||||
added[path] = entry
|
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
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,14 +195,18 @@ func dumpNode(out io.Writer, added map[string]*internal.FileMetadata, links map[
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
digest := verityDigests[payload]
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range entry.Xattrs {
|
for k, vEncoded := range entry.Xattrs {
|
||||||
name := escaped(k, ESCAPE_EQUAL)
|
v, err := base64.StdEncoding.DecodeString(vEncoded)
|
||||||
value := escaped(v, ESCAPE_EQUAL)
|
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 {
|
if _, err := fmt.Fprintf(out, " %s=%s", name, value); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ package dump
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -37,7 +38,7 @@ func TestEscaped(t *testing.T) {
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.input, func(t *testing.T) {
|
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 {
|
if result != test.want {
|
||||||
t.Errorf("got %q, want %q", result, test.want)
|
t.Errorf("got %q, want %q", result, test.want)
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +61,7 @@ func TestDumpNode(t *testing.T) {
|
||||||
Linkname: "",
|
Linkname: "",
|
||||||
Digest: "sha256:abcdef1234567890",
|
Digest: "sha256:abcdef1234567890",
|
||||||
Xattrs: map[string]string{
|
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,
|
ModTime: &modTime,
|
||||||
Linkname: "",
|
Linkname: "",
|
||||||
Xattrs: map[string]string{
|
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)
|
t.Errorf("for %s, got %q, want %q", testCase.name, actual, testCase.expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue