Commit 258c278e authored by Russ Cox's avatar Russ Cox

cmd/pack: fix match

Match used len(ar.files) == 0 to mean "match everything"
but it also deleted matched things from the list, so once you
had matched everything you asked for, match returned true
for whatever was left in the archive too.

Concretely, if you have an archive containing f1, f2, then
        pack t foo.a f1
would match f1 and then, because len(ar.files) == 0 after
deleting f1 from the match list, also match f2.

Avoid the problem by recording explicitly whether match
matches everything.

LGTM=r, dsymonds
R=r, dsymonds
CC=golang-codereviews
https://golang.org/cl/65630046
parent 574e0f9a
...@@ -132,9 +132,10 @@ const ( ...@@ -132,9 +132,10 @@ const (
// An Archive represents an open archive file. It is always scanned sequentially // An Archive represents an open archive file. It is always scanned sequentially
// from start to end, without backing up. // from start to end, without backing up.
type Archive struct { type Archive struct {
fd *os.File // Open file descriptor. fd *os.File // Open file descriptor.
files []string // Explicit list of files to be processed. files []string // Explicit list of files to be processed.
pad int // Padding bytes required at end of current archive file pad int // Padding bytes required at end of current archive file
matchAll bool // match all files in archive
} }
// archive opens (or if necessary creates) the named archive. // archive opens (or if necessary creates) the named archive.
...@@ -148,8 +149,9 @@ func archive(name string, mode int, files []string) *Archive { ...@@ -148,8 +149,9 @@ func archive(name string, mode int, files []string) *Archive {
} }
mustBeArchive(fd) mustBeArchive(fd)
return &Archive{ return &Archive{
fd: fd, fd: fd,
files: files, files: files,
matchAll: len(files) == 0,
} }
} }
...@@ -282,7 +284,7 @@ func (ar *Archive) skip(entry *Entry) { ...@@ -282,7 +284,7 @@ func (ar *Archive) skip(entry *Entry) {
// match reports whether the entry matches the argument list. // match reports whether the entry matches the argument list.
// If it does, it also drops the file from the to-be-processed list. // If it does, it also drops the file from the to-be-processed list.
func (ar *Archive) match(entry *Entry) bool { func (ar *Archive) match(entry *Entry) bool {
if len(ar.files) == 0 { if ar.matchAll {
return true return true
} }
for i, name := range ar.files { for i, name := range ar.files {
......
...@@ -90,10 +90,12 @@ func TestTableOfContents(t *testing.T) { ...@@ -90,10 +90,12 @@ func TestTableOfContents(t *testing.T) {
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
name := filepath.Join(dir, "pack.a") name := filepath.Join(dir, "pack.a")
ar := archive(name, os.O_RDWR, nil) ar := archive(name, os.O_RDWR, nil)
// Add some entries by hand. // Add some entries by hand.
ar.addFile(helloFile.Reset()) ar.addFile(helloFile.Reset())
ar.addFile(goodbyeFile.Reset()) ar.addFile(goodbyeFile.Reset())
ar.fd.Close() ar.fd.Close()
// Now print it. // Now print it.
ar = archive(name, os.O_RDONLY, nil) ar = archive(name, os.O_RDONLY, nil)
var buf bytes.Buffer var buf bytes.Buffer
...@@ -111,6 +113,7 @@ func TestTableOfContents(t *testing.T) { ...@@ -111,6 +113,7 @@ func TestTableOfContents(t *testing.T) {
if result != expect { if result != expect {
t.Fatalf("expected %q got %q", expect, result) t.Fatalf("expected %q got %q", expect, result)
} }
// Do it again without verbose. // Do it again without verbose.
verbose = false verbose = false
buf.Reset() buf.Reset()
...@@ -123,6 +126,19 @@ func TestTableOfContents(t *testing.T) { ...@@ -123,6 +126,19 @@ func TestTableOfContents(t *testing.T) {
if result != expect { if result != expect {
t.Fatalf("expected %q got %q", expect, result) t.Fatalf("expected %q got %q", expect, result)
} }
// Do it again with file list arguments.
verbose = false
buf.Reset()
ar = archive(name, os.O_RDONLY, []string{helloFile.name})
ar.scan(ar.tableOfContents)
ar.fd.Close()
result = buf.String()
// Expect only helloFile.
expect = fmt.Sprintf("%s\n", helloFile.name)
if result != expect {
t.Fatalf("expected %q got %q", expect, result)
}
} }
// Test that we can create an archive, put some files in it, and get back a file. // Test that we can create an archive, put some files in it, and get back a file.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment