From e96a5ef42667de0bb4aeca94064f8d9f066ce2aa Mon Sep 17 00:00:00 2001 From: Ethan Reesor Date: Wed, 8 Jul 2020 02:44:49 -0500 Subject: [PATCH] GetArchive: make exclude relative to path --- .../get-archive-exclude-relative.yml | 5 +++++ internal/service/repository/archive.go | 3 ++- internal/service/repository/archive_test.go | 19 ++++++++++++++++++ proto/go/gitalypb/repository-service.pb.go | 20 ++++++++++--------- proto/repository-service.proto | 2 ++ 5 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 changelogs/unreleased/get-archive-exclude-relative.yml diff --git a/changelogs/unreleased/get-archive-exclude-relative.yml b/changelogs/unreleased/get-archive-exclude-relative.yml new file mode 100644 index 00000000000..d4d8a94f8b1 --- /dev/null +++ b/changelogs/unreleased/get-archive-exclude-relative.yml @@ -0,0 +1,5 @@ +--- +title: 'GetArchive: make exclude relative to path' +merge_request: 2363 +author: Ethan Reesor (@firelizzard) +type: changed diff --git a/internal/service/repository/archive.go b/internal/service/repository/archive.go index 35465312666..daff70da474 100644 --- a/internal/service/repository/archive.go +++ b/internal/service/repository/archive.go @@ -4,6 +4,7 @@ import ( "context" "io" "os/exec" + "path/filepath" "gitlab.com/gitlab-org/gitaly/internal/command" "gitlab.com/gitlab-org/gitaly/internal/git" @@ -31,7 +32,7 @@ func (s *server) GetArchive(in *gitalypb.GetArchiveRequest, stream gitalypb.Repo exclude := make([]string, len(in.GetExclude())) for i, ex := range in.GetExclude() { - exclude[i], err = storage.ValidateRelativePath(repoRoot, string(ex)) + exclude[i], err = storage.ValidateRelativePath(repoRoot, filepath.Join(string(in.GetPath()), string(ex))) if err != nil { return helper.ErrInvalidArgument(err) } diff --git a/internal/service/repository/archive_test.go b/internal/service/repository/archive_test.go index 87436d4a5d1..a91c5963191 100644 --- a/internal/service/repository/archive_test.go +++ b/internal/service/repository/archive_test.go @@ -89,6 +89,15 @@ func TestGetArchiveSuccess(t *testing.T) { contents: []string{"/.gitignore", "/LICENSE", "/README.md"}, excluded: []string{"/files/whitespace", "/files/html/500.html"}, }, + { + desc: "with path and exclusion", + commitID: "1e292f8fedd741b75372e19097c76d327140c312", + prefix: "", + path: []byte("files/"), + exclude: [][]byte{[]byte("html/")}, + contents: []string{"/files/whitespace"}, + excluded: []string{"/files/html/500.html"}, + }, } for _, tc := range testCases { @@ -215,6 +224,16 @@ func TestGetArchiveFailure(t *testing.T) { exclude: [][]byte{[]byte("files/")}, code: codes.FailedPrecondition, }, + { + desc: "Rooted exclude when path is specified", + repo: testRepo, + prefix: "", + commitID: "1e292f8fedd741b75372e19097c76d327140c312", + format: gitalypb.GetArchiveRequest_ZIP, + path: []byte("files/"), + exclude: [][]byte{[]byte("files/html")}, + code: codes.FailedPrecondition, + }, { desc: "path contains directory traversal outside repository root", repo: testRepo, diff --git a/proto/go/gitalypb/repository-service.pb.go b/proto/go/gitalypb/repository-service.pb.go index 0af7c9ef8ad..632cb32f25e 100644 --- a/proto/go/gitalypb/repository-service.pb.go +++ b/proto/go/gitalypb/repository-service.pb.go @@ -901,15 +901,17 @@ func (m *CreateRepositoryResponse) XXX_DiscardUnknown() { var xxx_messageInfo_CreateRepositoryResponse proto.InternalMessageInfo type GetArchiveRequest struct { - Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` - Prefix string `protobuf:"bytes,3,opt,name=prefix,proto3" json:"prefix,omitempty"` - Format GetArchiveRequest_Format `protobuf:"varint,4,opt,name=format,proto3,enum=gitaly.GetArchiveRequest_Format" json:"format,omitempty"` - Path []byte `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` - Exclude [][]byte `protobuf:"bytes,6,rep,name=exclude,proto3" json:"exclude,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"` + Prefix string `protobuf:"bytes,3,opt,name=prefix,proto3" json:"prefix,omitempty"` + Format GetArchiveRequest_Format `protobuf:"varint,4,opt,name=format,proto3,enum=gitaly.GetArchiveRequest_Format" json:"format,omitempty"` + Path []byte `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` + // Excluded paths must be relative to the base path. For example, to exclude + // 'a/b' when `path` is 'a/', `exclude` must be ['b/']. + Exclude [][]byte `protobuf:"bytes,6,rep,name=exclude,proto3" json:"exclude,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *GetArchiveRequest) Reset() { *m = GetArchiveRequest{} } diff --git a/proto/repository-service.proto b/proto/repository-service.proto index 5138dfe6cbb..b56b4078d65 100644 --- a/proto/repository-service.proto +++ b/proto/repository-service.proto @@ -311,6 +311,8 @@ message GetArchiveRequest { string prefix = 3; Format format = 4; bytes path = 5; + // Excluded paths must be relative to the base path. For example, to exclude + // 'a/b' when `path` is 'a/', `exclude` must be ['b/']. repeated bytes exclude = 6; } -- GitLab