Problem Writing Non-Ascii Files to Aci Writer
Opened this issue · 0 comments
Hello
Recently I tried to use the ACI image spec for my work with Illumos Zones. However I stumbled upon a quite nasty behaviour. Everytime I created an Archive it only the wrote part of the Image and aborted. Always when writing the same file '/etc/certs/CA/Certinomis_-Autorité_Racine.pem'. (On Linux the File is named Certinomis-_Autorit___Racine.pem) As suspected this behaviour is the same with other unicode file names. See test Code below:
This code fails consistently on close when flushing with missing bytes. However if using archive/tar directly it does not.
Assuming my code below is correct, I would assume the that the Problem lies with io.Copy. The Test Case in the golang archive/tar which this test is based on uses tarWriter.Write directly and works.
import (
"testing"
"strings"
"bytes"
"os"
"archive/tar"
"github.com/appc/spec/aci"
"github.com/appc/spec/schema"
)
func TestPaxNonAscii(t *testing.T) {
// Create an archive with non ascii. These should trigger a pax header
// because pax headers have a defined utf-8 encoding.
fileinfo, err := os.Stat("testdata/small.txt")
if err != nil {
t.Fatal(err)
}
hdr, err := tar.FileInfoHeader(fileinfo, "")
if err != nil {
t.Fatalf("os.Stat:1 %v", err)
}
hdr2, err := tar.FileInfoHeader(fileinfo, "")
if err != nil {
t.Fatalf("os.Stat:1 %v", err)
}
// some sample data
chineseFilename := "文件名"
chineseGroupname := "組"
chineseUsername := "用戶名"
hdr.Name = chineseFilename
hdr.Gname = chineseGroupname
hdr.Uname = chineseUsername
hdr2.Name = chineseFilename
hdr2.Gname = chineseGroupname
hdr2.Uname = chineseUsername
contents := strings.Repeat(" ", int(hdr.Size))
contentReader := bytes.NewBufferString(contents)
var buf bytes.Buffer
writer := tar.NewWriter(&buf)
manifest := schema.BlankImageManifest()
manifest.Name = "test"
aciW := aci.NewImageWriter(*manifest, writer)
aciW.AddFile(hdr, contentReader)
aciW.AddFile(hdr2, contentReader)
if err := aciW.Close(); err != nil {
t.Fatal(err)
}
// Simple test to make sure PAX extensions are in effect
if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.0")) {
t.Fatal("Expected at least one PAX header to be written.")
}
// Test that we can get a long name back out of the archive.
reader := tar.NewReader(&buf)
hdr, err = reader.Next()
if err != nil {
t.Fatal(err)
}
if hdr.Name != chineseFilename {
t.Fatal("Couldn't recover unicode name")
}
if hdr.Gname != chineseGroupname {
t.Fatal("Couldn't recover unicode group")
}
if hdr.Uname != chineseUsername {
t.Fatal("Couldn't recover unicode user")
}
hdr2, err = reader.Next()
if err != nil {
t.Fatal(err)
}
if hdr2.Name != chineseFilename {
t.Fatal("Couldn't recover unicode name")
}
if hdr2.Gname != chineseGroupname {
t.Fatal("Couldn't recover unicode group")
}
if hdr2.Uname != chineseUsername {
t.Fatal("Couldn't recover unicode user")
}
}