Bladeren bron

Make sure none of the ancestor folders of a new refname is in packed-refs

KS Chan 6 jaren geleden
bovenliggende
commit
0b655db44e
2 gewijzigde bestanden met toevoegingen van 31 en 0 verwijderingen
  1. 10 0
      dulwich/refs.py
  2. 21 0
      dulwich/tests/test_refs.py

+ 10 - 0
dulwich/refs.py

@@ -687,6 +687,16 @@ class DiskRefsContainer(RefsContainer):
         except (KeyError, IndexError):
             realname = name
         filename = self.refpath(realname)
+
+        # make sure none of the ancestor folders is in packed refs
+        probe_ref = os.path.dirname(realname)
+        packed_refs = self.get_packed_refs()
+        while probe_ref:
+            if packed_refs.get(probe_ref, None) is not None:
+                raise OSError(errno.ENOTDIR,
+                              'Not a directory: {}'.format(filename))
+            probe_ref = os.path.dirname(probe_ref)
+
         ensure_dir_exists(os.path.dirname(filename))
         with GitFile(filename, 'wb') as f:
             if old_ref is not None:

+ 21 - 0
dulwich/tests/test_refs.py

@@ -340,6 +340,27 @@ class DiskRefsContainerTests(RefsContainerTests, TestCase):
                          f.read()[:40])
         f.close()
 
+        self.assertRaises(
+            OSError, self._refs.__setitem__,
+            b'refs/some/ref/sub', b'42d06bd4b77fed026b154d16493e5deab78f02ec')
+
+    def test_setitem_packed(self):
+        # It's allowed to set a new ref on a packed ref, the new ref will be placed outside on refs/
+        self._refs[b'refs/heads/packed'] = (
+            b'3ec9c43c84ff242e3ef4a9fc5bc111fd780a76a8'
+        )
+        f = open(os.path.join(self._refs.path, b'refs', b'heads', b'packed'),
+                 'rb')
+        self.assertEqual(b'3ec9c43c84ff242e3ef4a9fc5bc111fd780a76a8',
+                         f.read()[:40])
+        f.close()
+
+        self._refs._packed_refs[b'refs/some/packed'] = b'42d06bd4b77fed026b154d16493e5deab78f02ec'
+        self.assertRaises(
+            OSError, self._refs.__setitem__,
+            b'refs/some/packed/sub',
+            b'42d06bd4b77fed026b154d16493e5deab78f02ec')
+
     def test_setitem_symbolic(self):
         ones = b'1' * 40
         self._refs[b'HEAD'] = ones