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

Problem Writing Non-Ascii Files to Aci Writer #694

Open
@Toasterson

Description

@Toasterson

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")
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载