Loading cmd/zip2zip/zip2zip.go +28 −2 Original line number Diff line number Diff line Loading @@ -148,8 +148,13 @@ func zip2zip(reader *zip.Reader, writer *zip.Writer, sortOutput, sortJava, setTi } else { if pathtools.IsGlob(input) { // If the input is a glob then the output is a directory. _, name := filepath.Split(file.Name) newName = filepath.Join(output, name) rel, err := filepath.Rel(constantPartOfPattern(input), file.Name) if err != nil { return err } else if strings.HasPrefix("../", rel) { return fmt.Errorf("globbed path %q was not in %q", file.Name, constantPartOfPattern(input)) } newName = filepath.Join(output, rel) } else { // Otherwise it is a file. newName = output Loading Loading @@ -277,3 +282,24 @@ func (m *multiFlag) Match(s string) (bool, error) { } return false, nil } func constantPartOfPattern(pattern string) string { ret := "" for pattern != "" { var first string first, pattern = splitFirst(pattern) if pathtools.IsGlob(first) { return ret } ret = filepath.Join(ret, first) } return ret } func splitFirst(path string) (string, string) { i := strings.IndexRune(path, filepath.Separator) if i < 0 { return path, "" } return path[:i], path[i+1:] } cmd/zip2zip/zip2zip_test.go +96 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,60 @@ var testCases = []struct { "a/b", }, }, { name: "recursive glob", inputFiles: []string{ "a/a/a", "a/a/b", }, args: []string{"a/**/*:b"}, outputFiles: []string{ "b/a/a", "b/a/b", }, }, { name: "glob", inputFiles: []string{ "a/a/a", "a/a/b", "a/b", "a/c", }, args: []string{"a/*:b"}, outputFiles: []string{ "b/b", "b/c", }, }, { name: "top level glob", inputFiles: []string{ "a", "b", }, args: []string{"*:b"}, outputFiles: []string{ "b/a", "b/b", }, }, { name: "multilple glob", inputFiles: []string{ "a/a/a", "a/a/b", }, args: []string{"a/*/*:b"}, outputFiles: []string{ "b/a/a", "b/a/b", }, }, } func errorString(e error) string { Loading Loading @@ -416,3 +470,45 @@ func TestZip2Zip(t *testing.T) { }) } } func TestConstantPartOfPattern(t *testing.T) { testCases := []struct{ in, out string }{ { in: "", out: "", }, { in: "a", out: "a", }, { in: "*", out: "", }, { in: "a/a", out: "a/a", }, { in: "a/*", out: "a", }, { in: "a/*/a", out: "a", }, { in: "a/**/*", out: "a", }, } for _, test := range testCases { t.Run(test.in, func(t *testing.T) { got := constantPartOfPattern(test.in) if got != test.out { t.Errorf("want %q, got %q", test.out, got) } }) } } Loading
cmd/zip2zip/zip2zip.go +28 −2 Original line number Diff line number Diff line Loading @@ -148,8 +148,13 @@ func zip2zip(reader *zip.Reader, writer *zip.Writer, sortOutput, sortJava, setTi } else { if pathtools.IsGlob(input) { // If the input is a glob then the output is a directory. _, name := filepath.Split(file.Name) newName = filepath.Join(output, name) rel, err := filepath.Rel(constantPartOfPattern(input), file.Name) if err != nil { return err } else if strings.HasPrefix("../", rel) { return fmt.Errorf("globbed path %q was not in %q", file.Name, constantPartOfPattern(input)) } newName = filepath.Join(output, rel) } else { // Otherwise it is a file. newName = output Loading Loading @@ -277,3 +282,24 @@ func (m *multiFlag) Match(s string) (bool, error) { } return false, nil } func constantPartOfPattern(pattern string) string { ret := "" for pattern != "" { var first string first, pattern = splitFirst(pattern) if pathtools.IsGlob(first) { return ret } ret = filepath.Join(ret, first) } return ret } func splitFirst(path string) (string, string) { i := strings.IndexRune(path, filepath.Separator) if i < 0 { return path, "" } return path[:i], path[i+1:] }
cmd/zip2zip/zip2zip_test.go +96 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,60 @@ var testCases = []struct { "a/b", }, }, { name: "recursive glob", inputFiles: []string{ "a/a/a", "a/a/b", }, args: []string{"a/**/*:b"}, outputFiles: []string{ "b/a/a", "b/a/b", }, }, { name: "glob", inputFiles: []string{ "a/a/a", "a/a/b", "a/b", "a/c", }, args: []string{"a/*:b"}, outputFiles: []string{ "b/b", "b/c", }, }, { name: "top level glob", inputFiles: []string{ "a", "b", }, args: []string{"*:b"}, outputFiles: []string{ "b/a", "b/b", }, }, { name: "multilple glob", inputFiles: []string{ "a/a/a", "a/a/b", }, args: []string{"a/*/*:b"}, outputFiles: []string{ "b/a/a", "b/a/b", }, }, } func errorString(e error) string { Loading Loading @@ -416,3 +470,45 @@ func TestZip2Zip(t *testing.T) { }) } } func TestConstantPartOfPattern(t *testing.T) { testCases := []struct{ in, out string }{ { in: "", out: "", }, { in: "a", out: "a", }, { in: "*", out: "", }, { in: "a/a", out: "a/a", }, { in: "a/*", out: "a", }, { in: "a/*/a", out: "a", }, { in: "a/**/*", out: "a", }, } for _, test := range testCases { t.Run(test.in, func(t *testing.T) { got := constantPartOfPattern(test.in) if got != test.out { t.Errorf("want %q, got %q", test.out, got) } }) } }