diff options
-rw-r--r-- | config/config.go | 12 | ||||
-rw-r--r-- | config/modules.go | 20 | ||||
-rw-r--r-- | config/modules_test.go | 26 | ||||
-rw-r--r-- | plumbing/format/idxfile/decoder.go | 8 | ||||
-rw-r--r-- | plumbing/transport/test/receive_pack.go | 1 | ||||
-rw-r--r-- | storage/filesystem/config.go | 2 | ||||
-rw-r--r-- | storage/filesystem/config_test.go | 2 | ||||
-rw-r--r-- | storage/filesystem/dotgit/dotgit.go (renamed from storage/filesystem/internal/dotgit/dotgit.go) | 0 | ||||
-rw-r--r-- | storage/filesystem/dotgit/dotgit_rewrite_packed_refs_nix.go (renamed from storage/filesystem/internal/dotgit/dotgit_rewrite_packed_refs_nix.go) | 0 | ||||
-rw-r--r-- | storage/filesystem/dotgit/dotgit_rewrite_packed_refs_norwfs.go (renamed from storage/filesystem/internal/dotgit/dotgit_rewrite_packed_refs_norwfs.go) | 0 | ||||
-rw-r--r-- | storage/filesystem/dotgit/dotgit_rewrite_packed_refs_windows.go (renamed from storage/filesystem/internal/dotgit/dotgit_rewrite_packed_refs_windows.go) | 0 | ||||
-rw-r--r-- | storage/filesystem/dotgit/dotgit_setref.go (renamed from storage/filesystem/internal/dotgit/dotgit_setref.go) | 0 | ||||
-rw-r--r-- | storage/filesystem/dotgit/dotgit_setref_norwfs.go (renamed from storage/filesystem/internal/dotgit/dotgit_setref_norwfs.go) | 0 | ||||
-rw-r--r-- | storage/filesystem/dotgit/dotgit_test.go (renamed from storage/filesystem/internal/dotgit/dotgit_test.go) | 0 | ||||
-rw-r--r-- | storage/filesystem/dotgit/writers.go (renamed from storage/filesystem/internal/dotgit/writers.go) | 0 | ||||
-rw-r--r-- | storage/filesystem/dotgit/writers_test.go (renamed from storage/filesystem/internal/dotgit/writers_test.go) | 0 | ||||
-rw-r--r-- | storage/filesystem/index.go | 2 | ||||
-rw-r--r-- | storage/filesystem/module.go | 2 | ||||
-rw-r--r-- | storage/filesystem/object.go | 2 | ||||
-rw-r--r-- | storage/filesystem/object_test.go | 2 | ||||
-rw-r--r-- | storage/filesystem/reference.go | 2 | ||||
-rw-r--r-- | storage/filesystem/shallow.go | 2 | ||||
-rw-r--r-- | storage/filesystem/storage.go | 2 | ||||
-rw-r--r-- | submodule_test.go | 15 | ||||
-rw-r--r-- | worktree.go | 12 |
25 files changed, 86 insertions, 26 deletions
diff --git a/config/config.go b/config/config.go index c730015..ce6506d 100644 --- a/config/config.go +++ b/config/config.go @@ -135,7 +135,7 @@ func (c *Config) Unmarshal(b []byte) error { if err := c.unmarshalPack(); err != nil { return err } - c.unmarshalSubmodules() + unmarshalSubmodules(c.Raw, c.Submodules) if err := c.unmarshalBranches(); err != nil { return err @@ -182,13 +182,17 @@ func (c *Config) unmarshalRemotes() error { return nil } -func (c *Config) unmarshalSubmodules() { - s := c.Raw.Section(submoduleSection) +func unmarshalSubmodules(fc *format.Config, submodules map[string]*Submodule) { + s := fc.Section(submoduleSection) for _, sub := range s.Subsections { m := &Submodule{} m.unmarshal(sub) - c.Submodules[m.Name] = m + if m.Validate() == ErrModuleBadPath { + continue + } + + submodules[m.Name] = m } } diff --git a/config/modules.go b/config/modules.go index b208984..90758d9 100644 --- a/config/modules.go +++ b/config/modules.go @@ -3,6 +3,7 @@ package config import ( "bytes" "errors" + "regexp" format "gopkg.in/src-d/go-git.v4/plumbing/format/config" ) @@ -10,6 +11,12 @@ import ( var ( ErrModuleEmptyURL = errors.New("module config: empty URL") ErrModuleEmptyPath = errors.New("module config: empty path") + ErrModuleBadPath = errors.New("submodule has an invalid path") +) + +var ( + // Matches module paths with dotdot ".." components. + dotdotPath = regexp.MustCompile(`(^|[/\\])\.\.([/\\]|$)`) ) // Modules defines the submodules properties, represents a .gitmodules file @@ -44,14 +51,7 @@ func (m *Modules) Unmarshal(b []byte) error { return err } - s := m.raw.Section(submoduleSection) - for _, sub := range s.Subsections { - mod := &Submodule{} - mod.unmarshal(sub) - - m.Submodules[mod.Path] = mod - } - + unmarshalSubmodules(m.raw, m.Submodules) return nil } @@ -102,6 +102,10 @@ func (m *Submodule) Validate() error { return ErrModuleEmptyURL } + if dotdotPath.MatchString(m.Path) { + return ErrModuleBadPath + } + return nil } diff --git a/config/modules_test.go b/config/modules_test.go index 36cd93f..8e10d70 100644 --- a/config/modules_test.go +++ b/config/modules_test.go @@ -11,6 +11,29 @@ func (s *ModulesSuite) TestValidateMissingURL(c *C) { c.Assert(m.Validate(), Equals, ErrModuleEmptyURL) } +func (s *ModulesSuite) TestValidateBadPath(c *C) { + input := []string{ + `..`, + `../`, + `../bar`, + + `/..`, + `/../bar`, + + `foo/..`, + `foo/../`, + `foo/../bar`, + } + + for _, p := range input { + m := &Submodule{ + Path: p, + URL: "https://example.com/", + } + c.Assert(m.Validate(), Equals, ErrModuleBadPath) + } +} + func (s *ModulesSuite) TestValidateMissingName(c *C) { m := &Submodule{URL: "bar"} c.Assert(m.Validate(), Equals, ErrModuleEmptyPath) @@ -39,6 +62,9 @@ func (s *ModulesSuite) TestUnmarshall(c *C) { path = foo/bar url = https://github.com/foo/bar.git branch = dev +[submodule "suspicious"] + path = ../../foo/bar + url = https://github.com/foo/bar.git `) cfg := NewModules() diff --git a/plumbing/format/idxfile/decoder.go b/plumbing/format/idxfile/decoder.go index f361213..45afb1e 100644 --- a/plumbing/format/idxfile/decoder.go +++ b/plumbing/format/idxfile/decoder.go @@ -6,7 +6,6 @@ import ( "errors" "io" - "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/utils/binary" ) @@ -98,13 +97,14 @@ func readFanout(idx *Idxfile, r io.Reader) error { func readObjectNames(idx *Idxfile, r io.Reader) error { c := int(idx.ObjectCount) + new := make([]Entry, c) for i := 0; i < c; i++ { - var ref plumbing.Hash - if _, err := io.ReadFull(r, ref[:]); err != nil { + e := &new[i] + if _, err := io.ReadFull(r, e.Hash[:]); err != nil { return err } - idx.Entries = append(idx.Entries, &Entry{Hash: ref}) + idx.Entries = append(idx.Entries, e) } return nil diff --git a/plumbing/transport/test/receive_pack.go b/plumbing/transport/test/receive_pack.go index 6179850..57f602d 100644 --- a/plumbing/transport/test/receive_pack.go +++ b/plumbing/transport/test/receive_pack.go @@ -231,7 +231,6 @@ func (s *ReceivePackSuite) receivePackNoCheck(c *C, ep *transport.Endpoint, // fixtures are generated with read only permissions, this casuses // errors deleting or modifying files. rootPath := ep.Path - println("STAT", rootPath) stat, err := os.Stat(ep.Path) if rootPath != "" && err == nil && stat.IsDir() { diff --git a/storage/filesystem/config.go b/storage/filesystem/config.go index 85feaf0..be812e4 100644 --- a/storage/filesystem/config.go +++ b/storage/filesystem/config.go @@ -5,7 +5,7 @@ import ( "os" "gopkg.in/src-d/go-git.v4/config" - "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" + "gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit" "gopkg.in/src-d/go-git.v4/utils/ioutil" ) diff --git a/storage/filesystem/config_test.go b/storage/filesystem/config_test.go index cc03119..71c947d 100644 --- a/storage/filesystem/config_test.go +++ b/storage/filesystem/config_test.go @@ -5,7 +5,7 @@ import ( "os" "gopkg.in/src-d/go-git.v4/config" - "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" + "gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit" . "gopkg.in/check.v1" "gopkg.in/src-d/go-billy.v4/osfs" diff --git a/storage/filesystem/internal/dotgit/dotgit.go b/storage/filesystem/dotgit/dotgit.go index 52b621c..52b621c 100644 --- a/storage/filesystem/internal/dotgit/dotgit.go +++ b/storage/filesystem/dotgit/dotgit.go diff --git a/storage/filesystem/internal/dotgit/dotgit_rewrite_packed_refs_nix.go b/storage/filesystem/dotgit/dotgit_rewrite_packed_refs_nix.go index c760793..c760793 100644 --- a/storage/filesystem/internal/dotgit/dotgit_rewrite_packed_refs_nix.go +++ b/storage/filesystem/dotgit/dotgit_rewrite_packed_refs_nix.go diff --git a/storage/filesystem/internal/dotgit/dotgit_rewrite_packed_refs_norwfs.go b/storage/filesystem/dotgit/dotgit_rewrite_packed_refs_norwfs.go index 6e43b42..6e43b42 100644 --- a/storage/filesystem/internal/dotgit/dotgit_rewrite_packed_refs_norwfs.go +++ b/storage/filesystem/dotgit/dotgit_rewrite_packed_refs_norwfs.go diff --git a/storage/filesystem/internal/dotgit/dotgit_rewrite_packed_refs_windows.go b/storage/filesystem/dotgit/dotgit_rewrite_packed_refs_windows.go index 897d2c9..897d2c9 100644 --- a/storage/filesystem/internal/dotgit/dotgit_rewrite_packed_refs_windows.go +++ b/storage/filesystem/dotgit/dotgit_rewrite_packed_refs_windows.go diff --git a/storage/filesystem/internal/dotgit/dotgit_setref.go b/storage/filesystem/dotgit/dotgit_setref.go index d27c1a3..d27c1a3 100644 --- a/storage/filesystem/internal/dotgit/dotgit_setref.go +++ b/storage/filesystem/dotgit/dotgit_setref.go diff --git a/storage/filesystem/internal/dotgit/dotgit_setref_norwfs.go b/storage/filesystem/dotgit/dotgit_setref_norwfs.go index 5695bd3..5695bd3 100644 --- a/storage/filesystem/internal/dotgit/dotgit_setref_norwfs.go +++ b/storage/filesystem/dotgit/dotgit_setref_norwfs.go diff --git a/storage/filesystem/internal/dotgit/dotgit_test.go b/storage/filesystem/dotgit/dotgit_test.go index 7733eef..7733eef 100644 --- a/storage/filesystem/internal/dotgit/dotgit_test.go +++ b/storage/filesystem/dotgit/dotgit_test.go diff --git a/storage/filesystem/internal/dotgit/writers.go b/storage/filesystem/dotgit/writers.go index c2b420f..c2b420f 100644 --- a/storage/filesystem/internal/dotgit/writers.go +++ b/storage/filesystem/dotgit/writers.go diff --git a/storage/filesystem/internal/dotgit/writers_test.go b/storage/filesystem/dotgit/writers_test.go index bf00762..bf00762 100644 --- a/storage/filesystem/internal/dotgit/writers_test.go +++ b/storage/filesystem/dotgit/writers_test.go diff --git a/storage/filesystem/index.go b/storage/filesystem/index.go index 092edec..2ebf57e 100644 --- a/storage/filesystem/index.go +++ b/storage/filesystem/index.go @@ -4,7 +4,7 @@ import ( "os" "gopkg.in/src-d/go-git.v4/plumbing/format/index" - "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" + "gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit" "gopkg.in/src-d/go-git.v4/utils/ioutil" ) diff --git a/storage/filesystem/module.go b/storage/filesystem/module.go index 6f3de3f..7c8c8d8 100644 --- a/storage/filesystem/module.go +++ b/storage/filesystem/module.go @@ -2,7 +2,7 @@ package filesystem import ( "gopkg.in/src-d/go-git.v4/storage" - "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" + "gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit" ) type ModuleStorage struct { diff --git a/storage/filesystem/object.go b/storage/filesystem/object.go index 26190fd..54f268a 100644 --- a/storage/filesystem/object.go +++ b/storage/filesystem/object.go @@ -11,7 +11,7 @@ import ( "gopkg.in/src-d/go-git.v4/plumbing/format/objfile" "gopkg.in/src-d/go-git.v4/plumbing/format/packfile" "gopkg.in/src-d/go-git.v4/plumbing/storer" - "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" + "gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit" "gopkg.in/src-d/go-git.v4/storage/memory" "gopkg.in/src-d/go-git.v4/utils/ioutil" diff --git a/storage/filesystem/object_test.go b/storage/filesystem/object_test.go index de8f2b2..4b57a67 100644 --- a/storage/filesystem/object_test.go +++ b/storage/filesystem/object_test.go @@ -2,7 +2,7 @@ package filesystem import ( "gopkg.in/src-d/go-git.v4/plumbing" - "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" + "gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit" . "gopkg.in/check.v1" "gopkg.in/src-d/go-git-fixtures.v3" diff --git a/storage/filesystem/reference.go b/storage/filesystem/reference.go index 7313f05..a891b83 100644 --- a/storage/filesystem/reference.go +++ b/storage/filesystem/reference.go @@ -3,7 +3,7 @@ package filesystem import ( "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/storer" - "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" + "gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit" ) type ReferenceStorage struct { diff --git a/storage/filesystem/shallow.go b/storage/filesystem/shallow.go index 173767c..502d406 100644 --- a/storage/filesystem/shallow.go +++ b/storage/filesystem/shallow.go @@ -5,7 +5,7 @@ import ( "fmt" "gopkg.in/src-d/go-git.v4/plumbing" - "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" + "gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit" "gopkg.in/src-d/go-git.v4/utils/ioutil" ) diff --git a/storage/filesystem/storage.go b/storage/filesystem/storage.go index 82b137c..d7aa18b 100644 --- a/storage/filesystem/storage.go +++ b/storage/filesystem/storage.go @@ -2,7 +2,7 @@ package filesystem import ( - "gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit" + "gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit" "gopkg.in/src-d/go-billy.v4" ) diff --git a/submodule_test.go b/submodule_test.go index 7c97179..2c0a2ed 100644 --- a/submodule_test.go +++ b/submodule_test.go @@ -196,6 +196,21 @@ func (s *SubmoduleSuite) TestSubmodulesInit(c *C) { } } +func (s *SubmoduleSuite) TestGitSubmodulesSymlink(c *C) { + f, err := s.Worktree.Filesystem.Create("badfile") + c.Assert(err, IsNil) + defer f.Close() + + err = s.Worktree.Filesystem.Remove(gitmodulesFile) + c.Assert(err, IsNil) + + err = s.Worktree.Filesystem.Symlink("badfile", gitmodulesFile) + c.Assert(err, IsNil) + + _, err = s.Worktree.Submodules() + c.Assert(err, Equals, ErrGitModulesSymlink) +} + func (s *SubmoduleSuite) TestSubmodulesStatus(c *C) { sm, err := s.Worktree.Submodules() c.Assert(err, IsNil) diff --git a/worktree.go b/worktree.go index ddf6fff..99b2cd1 100644 --- a/worktree.go +++ b/worktree.go @@ -28,6 +28,7 @@ var ( ErrWorktreeNotClean = errors.New("worktree is not clean") ErrSubmoduleNotFound = errors.New("submodule not found") ErrUnstagedChanges = errors.New("worktree contains unstaged changes") + ErrGitModulesSymlink = errors.New(gitmodulesFile + " is a symlink") ) // Worktree represents a git worktree. @@ -680,7 +681,18 @@ func (w *Worktree) newSubmodule(fromModules, fromConfig *config.Submodule) *Subm return m } +func (w *Worktree) isSymlink(path string) bool { + if s, err := w.Filesystem.Lstat(path); err == nil { + return s.Mode()&os.ModeSymlink != 0 + } + return false +} + func (w *Worktree) readGitmodulesFile() (*config.Modules, error) { + if w.isSymlink(gitmodulesFile) { + return nil, ErrGitModulesSymlink + } + f, err := w.Filesystem.Open(gitmodulesFile) if err != nil { if os.IsNotExist(err) { |