From afd7fe2554d65040b27291d658af21af8f8ae521 Mon Sep 17 00:00:00 2001 From: Chris Northwood Date: Thu, 21 Mar 2019 17:01:07 +0000 Subject: [PATCH] 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 --- pkg/tarutil/tarutil.go | 6 ++++-- pkg/tarutil/tarutil_test.go | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/pkg/tarutil/tarutil.go b/pkg/tarutil/tarutil.go index 357f96da..bf47bcb6 100644 --- a/pkg/tarutil/tarutil.go +++ b/pkg/tarutil/tarutil.go @@ -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 } diff --git a/pkg/tarutil/tarutil_test.go b/pkg/tarutil/tarutil_test.go index 9db377ab..fd41cdc2 100644 --- a/pkg/tarutil/tarutil_test.go +++ b/pkg/tarutil/tarutil_test.go @@ -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))