浏览代码

Use correct path separators for named repo files.

Change-Id: I79175078920ef177006bbd323c3d63232f3060b8
Dave Borowitz 15 年之前
父节点
当前提交
44e1d6154c
共有 4 个文件被更改,包括 37 次插入6 次删除
  1. 2 0
      NEWS
  2. 6 2
      dulwich/repo.py
  3. 18 1
      dulwich/tests/test_repository.py
  4. 11 3
      dulwich/web.py

+ 2 - 0
NEWS

@@ -4,6 +4,8 @@
 
 
   * Fix memory leak in C implementation of sorted_tree_items. (Dave Borowitz)
   * Fix memory leak in C implementation of sorted_tree_items. (Dave Borowitz)
 
 
+  * Use correct path separators for named repo files. (Dave Borowitz)
+
  FEATURES
  FEATURES
 
 
   * Move named file initilization to BaseRepo. (Dave Borowitz)
   * Move named file initilization to BaseRepo. (Dave Borowitz)

+ 6 - 2
dulwich/repo.py

@@ -758,7 +758,7 @@ class BaseRepo(object):
                                         'filemode = true\n'
                                         'filemode = true\n'
                                         'bare = false\n'
                                         'bare = false\n'
                                         'logallrefupdates = true\n'))
                                         'logallrefupdates = true\n'))
-        self._put_named_file('info/exclude', '')
+        self._put_named_file(os.path.join('info', 'exclude'), '')
 
 
     def get_named_file(self, path):
     def get_named_file(self, path):
         """Get a file from the control dir with a specific name.
         """Get a file from the control dir with a specific name.
@@ -1095,6 +1095,7 @@ class Repo(BaseRepo):
         :param path: The path to the file, relative to the control dir.
         :param path: The path to the file, relative to the control dir.
         :contents: A string to write to the file.
         :contents: A string to write to the file.
         """
         """
+        path = path.lstrip(os.path.sep)
         f = GitFile(os.path.join(self.controldir(), path), 'wb')
         f = GitFile(os.path.join(self.controldir(), path), 'wb')
         try:
         try:
             f.write(contents)
             f.write(contents)
@@ -1111,8 +1112,11 @@ class Repo(BaseRepo):
         :param path: The path to the file, relative to the control dir.
         :param path: The path to the file, relative to the control dir.
         :return: An open file object, or None if the file does not exist.
         :return: An open file object, or None if the file does not exist.
         """
         """
+        # TODO(dborowitz): sanitize filenames, since this is used directly by
+        # the dumb web serving code.
+        path = path.lstrip(os.path.sep)
         try:
         try:
-            return open(os.path.join(self.controldir(), path.lstrip('/')), 'rb')
+            return open(os.path.join(self.controldir(), path), 'rb')
         except (IOError, OSError), e:
         except (IOError, OSError), e:
             if e.errno == errno.ENOENT:
             if e.errno == errno.ENOENT:
                 return None
                 return None

+ 18 - 1
dulwich/tests/test_repository.py

@@ -50,11 +50,28 @@ missing_sha = 'b91fa4d900e17e99b433218e988c4eb4a3e9a097'
 
 
 class CreateRepositoryTests(unittest.TestCase):
 class CreateRepositoryTests(unittest.TestCase):
 
 
-    def test_create(self):
+    def assertFileContentsEqual(self, expected, repo, path):
+        f = repo.get_named_file(path)
+        if not f:
+            self.assertEqual(expected, None)
+        else:
+            try:
+                self.assertEqual(expected, f.read())
+            finally:
+                f.close()
+
+    def _check_repo_contents(self, repo):
+        self.assertTrue(repo.bare)
+        self.assertFileContentsEqual('Unnamed repository', repo, 'description')
+        self.assertFileContentsEqual('', repo, os.path.join('info', 'exclude'))
+        self.assertFileContentsEqual(None, repo, 'nonexistent file')
+
+    def test_create_disk(self):
         tmp_dir = tempfile.mkdtemp()
         tmp_dir = tempfile.mkdtemp()
         try:
         try:
             repo = Repo.init_bare(tmp_dir)
             repo = Repo.init_bare(tmp_dir)
             self.assertEquals(tmp_dir, repo._controldir)
             self.assertEquals(tmp_dir, repo._controldir)
+            self._check_repo_contents(repo)
         finally:
         finally:
             shutil.rmtree(tmp_dir)
             shutil.rmtree(tmp_dir)
 
 

+ 11 - 3
dulwich/web.py

@@ -19,6 +19,7 @@
 """HTTP server for dulwich that implements the git smart HTTP protocol."""
 """HTTP server for dulwich that implements the git smart HTTP protocol."""
 
 
 from cStringIO import StringIO
 from cStringIO import StringIO
+import os
 import re
 import re
 import time
 import time
 
 
@@ -98,9 +99,14 @@ def send_file(req, f, content_type):
         raise
         raise
 
 
 
 
+def _url_to_path(url):
+    return url.replace('/', os.path.sep)
+
+
 def get_text_file(req, backend, mat):
 def get_text_file(req, backend, mat):
     req.nocache()
     req.nocache()
-    return send_file(req, get_repo(backend, mat).get_named_file(mat.group()),
+    path = _url_to_path(mat.group())
+    return send_file(req, get_repo(backend, mat).get_named_file(path),
                      'text/plain')
                      'text/plain')
 
 
 
 
@@ -121,13 +127,15 @@ def get_loose_object(req, backend, mat):
 
 
 def get_pack_file(req, backend, mat):
 def get_pack_file(req, backend, mat):
     req.cache_forever()
     req.cache_forever()
-    return send_file(req, get_repo(backend, mat).get_named_file(mat.group()),
+    path = _url_to_path(mat.group())
+    return send_file(req, get_repo(backend, mat).get_named_file(path),
                      'application/x-git-packed-objects')
                      'application/x-git-packed-objects')
 
 
 
 
 def get_idx_file(req, backend, mat):
 def get_idx_file(req, backend, mat):
     req.cache_forever()
     req.cache_forever()
-    return send_file(req, get_repo(backend, mat).get_named_file(mat.group()),
+    path = _url_to_path(mat.group())
+    return send_file(req, get_repo(backend, mat).get_named_file(path),
                      'application/x-git-packed-objects-toc')
                      'application/x-git-packed-objects-toc')