forked from mirrors/tar-split
archive/tar: remove dead code with USTAR path splitting
Convert splitUSTARPath to return a bool rather than an error since the caller never ever uses the error other than to check if it is nil. Thus, we can remove errNameTooLong as well. Also, fold the checking of the length <= fileNameSize and whether the string is ASCII into the split function itself. Lastly, remove logic to set the MAGIC since that's already done on L200. Thus, setting the magic is redundant. There is no overall logic change. Updates #12638 Change-Id: I26b6992578199abad723c2a2af7f4fc078af9c17 Reviewed-on: https://go-review.googlesource.com/14723 Reviewed-by: David Symonds <dsymonds@golang.org> Run-TryBot: David Symonds <dsymonds@golang.org>
This commit is contained in:
parent
d50e5c9283
commit
440ba9e519
2 changed files with 52 additions and 34 deletions
|
@ -23,7 +23,6 @@ var (
|
||||||
ErrWriteTooLong = errors.New("archive/tar: write too long")
|
ErrWriteTooLong = errors.New("archive/tar: write too long")
|
||||||
ErrFieldTooLong = errors.New("archive/tar: header field too long")
|
ErrFieldTooLong = errors.New("archive/tar: header field too long")
|
||||||
ErrWriteAfterClose = errors.New("archive/tar: write after close")
|
ErrWriteAfterClose = errors.New("archive/tar: write after close")
|
||||||
errNameTooLong = errors.New("archive/tar: name too long")
|
|
||||||
errInvalidHeader = errors.New("archive/tar: header field too long or contains invalid values")
|
errInvalidHeader = errors.New("archive/tar: header field too long or contains invalid values")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -215,26 +214,14 @@ func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error {
|
||||||
_, paxPathUsed := paxHeaders[paxPath]
|
_, paxPathUsed := paxHeaders[paxPath]
|
||||||
// try to use a ustar header when only the name is too long
|
// try to use a ustar header when only the name is too long
|
||||||
if !tw.preferPax && len(paxHeaders) == 1 && paxPathUsed {
|
if !tw.preferPax && len(paxHeaders) == 1 && paxPathUsed {
|
||||||
suffix := hdr.Name
|
prefix, suffix, ok := splitUSTARPath(hdr.Name)
|
||||||
prefix := ""
|
if ok {
|
||||||
if len(hdr.Name) > fileNameSize && isASCII(hdr.Name) {
|
// Since we can encode in USTAR format, disable PAX header.
|
||||||
var err error
|
delete(paxHeaders, paxPath)
|
||||||
prefix, suffix, err = tw.splitUSTARLongName(hdr.Name)
|
|
||||||
if err == nil {
|
|
||||||
// ok we can use a ustar long name instead of pax, now correct the fields
|
|
||||||
|
|
||||||
// remove the path field from the pax header. this will suppress the pax header
|
// Update the path fields
|
||||||
delete(paxHeaders, paxPath)
|
tw.cString(pathHeaderBytes, suffix, false, paxNone, nil)
|
||||||
|
tw.cString(prefixHeaderBytes, prefix, false, paxNone, nil)
|
||||||
// update the path fields
|
|
||||||
tw.cString(pathHeaderBytes, suffix, false, paxNone, nil)
|
|
||||||
tw.cString(prefixHeaderBytes, prefix, false, paxNone, nil)
|
|
||||||
|
|
||||||
// Use the ustar magic if we used ustar long names.
|
|
||||||
if len(prefix) > 0 && !tw.usedBinary {
|
|
||||||
copy(header[257:265], []byte("ustar\x00"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,28 +257,25 @@ func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error {
|
||||||
return tw.err
|
return tw.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeUSTARLongName splits a USTAR long name hdr.Name.
|
// splitUSTARPath splits a path according to USTAR prefix and suffix rules.
|
||||||
// name must be < 256 characters. errNameTooLong is returned
|
// If the path is not splittable, then it will return ("", "", false).
|
||||||
// if hdr.Name can't be split. The splitting heuristic
|
func splitUSTARPath(name string) (prefix, suffix string, ok bool) {
|
||||||
// is compatible with gnu tar.
|
|
||||||
func (tw *Writer) splitUSTARLongName(name string) (prefix, suffix string, err error) {
|
|
||||||
length := len(name)
|
length := len(name)
|
||||||
if length > fileNamePrefixSize+1 {
|
if length <= fileNameSize || !isASCII(name) {
|
||||||
|
return "", "", false
|
||||||
|
} else if length > fileNamePrefixSize+1 {
|
||||||
length = fileNamePrefixSize + 1
|
length = fileNamePrefixSize + 1
|
||||||
} else if name[length-1] == '/' {
|
} else if name[length-1] == '/' {
|
||||||
length--
|
length--
|
||||||
}
|
}
|
||||||
|
|
||||||
i := strings.LastIndex(name[:length], "/")
|
i := strings.LastIndex(name[:length], "/")
|
||||||
// nlen contains the resulting length in the name field.
|
nlen := len(name) - i - 1 // nlen is length of suffix
|
||||||
// plen contains the resulting length in the prefix field.
|
plen := i // plen is length of prefix
|
||||||
nlen := len(name) - i - 1
|
|
||||||
plen := i
|
|
||||||
if i <= 0 || nlen > fileNameSize || nlen == 0 || plen > fileNamePrefixSize {
|
if i <= 0 || nlen > fileNameSize || nlen == 0 || plen > fileNamePrefixSize {
|
||||||
err = errNameTooLong
|
return "", "", false
|
||||||
return
|
|
||||||
}
|
}
|
||||||
prefix, suffix = name[:i], name[i+1:]
|
return name[:i], name[i+1:], true
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// writePaxHeader writes an extended pax header to the
|
// writePaxHeader writes an extended pax header to the
|
||||||
|
|
|
@ -544,3 +544,37 @@ func TestWriteAfterClose(t *testing.T) {
|
||||||
t.Fatalf("Write: got %v; want ErrWriteAfterClose", err)
|
t.Fatalf("Write: got %v; want ErrWriteAfterClose", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSplitUSTARPath(t *testing.T) {
|
||||||
|
var sr = strings.Repeat
|
||||||
|
|
||||||
|
var vectors = []struct {
|
||||||
|
input string // Input path
|
||||||
|
prefix string // Expected output prefix
|
||||||
|
suffix string // Expected output suffix
|
||||||
|
ok bool // Split success?
|
||||||
|
}{
|
||||||
|
{"", "", "", false},
|
||||||
|
{"abc", "", "", false},
|
||||||
|
{"用戶名", "", "", false},
|
||||||
|
{sr("a", fileNameSize), "", "", false},
|
||||||
|
{sr("a", fileNameSize) + "/", "", "", false},
|
||||||
|
{sr("a", fileNameSize) + "/a", sr("a", fileNameSize), "a", true},
|
||||||
|
{sr("a", fileNamePrefixSize) + "/", "", "", false},
|
||||||
|
{sr("a", fileNamePrefixSize) + "/a", sr("a", fileNamePrefixSize), "a", true},
|
||||||
|
{sr("a", fileNameSize+1), "", "", false},
|
||||||
|
{sr("/", fileNameSize+1), sr("/", fileNameSize-1), "/", true},
|
||||||
|
{sr("a", fileNamePrefixSize) + "/" + sr("b", fileNameSize),
|
||||||
|
sr("a", fileNamePrefixSize), sr("b", fileNameSize), true},
|
||||||
|
{sr("a", fileNamePrefixSize) + "//" + sr("b", fileNameSize), "", "", false},
|
||||||
|
{sr("a/", fileNameSize), sr("a/", 77) + "a", sr("a/", 22), true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range vectors {
|
||||||
|
prefix, suffix, ok := splitUSTARPath(v.input)
|
||||||
|
if prefix != v.prefix || suffix != v.suffix || ok != v.ok {
|
||||||
|
t.Errorf("splitUSTARPath(%q):\ngot (%q, %q, %v)\nwant (%q, %q, %v)",
|
||||||
|
v.input, prefix, suffix, ok, v.prefix, v.suffix, v.ok)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue