1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
commit 598be9170c5e21ba408ba139a2b7bd7da6a04c70
Author: Jelmer Vernooij <jelmer@samba.org>
Date: Thu Jan 15 23:30:28 2015 +0100
By default refuse to create index entries with a path starting with .git/.
diff --git a/dulwich/index.py b/dulwich/index.py
index f32d70f..3c7488e 100644
--- a/dulwich/index.py
+++ b/dulwich/index.py
@@ -402,8 +402,14 @@ def index_entry_from_stat(stat_val, hex_sha, flags, mode=None):
stat_val.st_gid, stat_val.st_size, hex_sha, flags)
+def validate_path_default(path):
+ """Default path validator that just checks for .git/."""
+ return not path.startswith(".git/")
+
+
def build_index_from_tree(prefix, index_path, object_store, tree_id,
- honor_filemode=True):
+ honor_filemode=True,
+ validate_path=validate_path_default):
"""Generate and materialize index from a tree
:param tree_id: Tree to materialize
@@ -412,6 +418,8 @@ def build_index_from_tree(prefix, index_path, object_store, tree_id,
:param object_store: Non-empty object store holding tree contents
:param honor_filemode: An optional flag to honor core.filemode setting in
config file, default is core.filemode=True, change executable bit
+ :param validate_path: Function to validate paths to check out;
+ default just refuses filenames starting with .git/.
:note:: existing index is wiped and contents are not merged
in a working dir. Suiteable only for fresh clones.
@@ -420,6 +428,8 @@ def build_index_from_tree(prefix, index_path, object_store, tree_id,
index = Index(index_path)
for entry in object_store.iter_tree_contents(tree_id):
+ if not validate_path(entry.path):
+ continue
full_path = os.path.join(prefix, entry.path)
if not os.path.exists(os.path.dirname(full_path)):
diff --git a/dulwich/tests/test_index.py b/dulwich/tests/test_index.py
index 89b5d54..1852b9a 100644
--- a/dulwich/tests/test_index.py
+++ b/dulwich/tests/test_index.py
@@ -284,6 +284,43 @@ class BuildIndexTests(TestCase):
# Verify no files
self.assertEqual(['.git'], os.listdir(repo.path))
+ def test_git_dir(self):
+ if os.name != 'posix':
+ self.skipTest("test depends on POSIX shell")
+
+ repo_dir = tempfile.mkdtemp()
+ repo = Repo.init(repo_dir)
+ self.addCleanup(shutil.rmtree, repo_dir)
+
+ # Populate repo
+ filea = Blob.from_string('file a')
+ filee = Blob.from_string('d')
+
+ tree = Tree()
+ tree['.git/a'] = (stat.S_IFREG | 0o644, filea.id)
+ tree['c/e'] = (stat.S_IFREG | 0o644, filee.id)
+
+ repo.object_store.add_objects([(o, None)
+ for o in [filea, filee, tree]])
+
+ build_index_from_tree(repo.path, repo.index_path(),
+ repo.object_store, tree.id)
+
+ # Verify index entries
+ index = repo.open_index()
+ self.assertEqual(len(index), 1)
+
+ # filea
+ apath = os.path.join(repo.path, '.git', 'a')
+ self.assertFalse(os.path.exists(apath))
+
+ # filee
+ epath = os.path.join(repo.path, 'c', 'e')
+ self.assertTrue(os.path.exists(epath))
+ self.assertReasonableIndexEntry(index['c/e'],
+ stat.S_IFREG | 0o644, 1, filee.id)
+ self.assertFileContents(epath, 'd')
+
def test_nonempty(self):
if os.name != 'posix':
self.skipTest("test depends on POSIX shell")
|