tarutil: allow file names to be specified by regexp

Some features do not exist in set locations, but can be anywhere in the layer.
This allows those featurefmt to specify the filenames to be scanned by
regexp, as opposed to purely by path prefix.
If any current users of this express paths which use regexp special characters
this could be a breaking change for them (with the exception of . which will
continue to work as it matches against the literal character .), however
none of the code in this repo does that.

fixes #456
This commit is contained in:
Chris Northwood 2019-03-21 17:01:07 +00:00
parent 2c7838eac7
commit afd7fe2554
2 changed files with 24 additions and 2 deletions

View File

@ -25,6 +25,7 @@ import (
"io"
"io/ioutil"
"os/exec"
"regexp"
"strings"
)
@ -50,7 +51,8 @@ var (
type FilesMap map[string][]byte
// ExtractFiles decompresses and extracts only the specified files from an
// io.Reader representing an archive.
// io.Reader representing an archive. The files to be extracted are specified
// by regexp
func ExtractFiles(r io.Reader, filenames []string) (FilesMap, error) {
data := make(map[string][]byte)
@ -78,7 +80,7 @@ func ExtractFiles(r io.Reader, filenames []string) (FilesMap, error) {
// Determine if we should extract the element
toBeExtracted := false
for _, s := range filenames {
if strings.HasPrefix(filename, s) {
if match, err := regexp.MatchString("^"+s, filename); err == nil && match {
toBeExtracted = true
break
}

View File

@ -57,6 +57,26 @@ func TestExtract(t *testing.T) {
}
}
func TestExtractGlob(t *testing.T) {
for _, filename := range testTarballs {
f, err := os.Open(testfilepath(filename))
assert.Nil(t, err)
defer f.Close()
data, err := ExtractFiles(f, []string{`.+\.txt`})
assert.Nil(t, err)
if c, n := data["test/test.txt"]; !n {
assert.Fail(t, "test/test.txt should have been extracted")
} else {
assert.NotEqual(t, 0, len(c) > 0, "test/test.txt file is empty")
}
if _, n := data["test.txt"]; !n {
assert.Fail(t, "test.txt should also have been extracted")
}
}
}
func TestExtractUncompressedData(t *testing.T) {
for _, filename := range testTarballs {
f, err := os.Open(testfilepath(filename))