Skip to content
This repository has been archived by the owner on Aug 14, 2020. It is now read-only.

Problem Writing Non-Ascii Files to Aci Writer #694

Open
Toasterson opened this issue Oct 5, 2017 · 0 comments
Open

Problem Writing Non-Ascii Files to Aci Writer #694

Toasterson opened this issue Oct 5, 2017 · 0 comments

Comments

@Toasterson
Copy link

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")
	}
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant