← Back to team overview

dulwich-users team mailing list archive

[PATCH 2/5] Use correct path separators for named repo files.

 

From: Dave Borowitz <dborowitz@xxxxxxxxxx>

Change-Id: I79175078920ef177006bbd323c3d63232f3060b8
---
 NEWS                             |    2 ++
 dulwich/repo.py                  |    8 ++++++--
 dulwich/tests/test_repository.py |   19 ++++++++++++++++++-
 dulwich/web.py                   |   14 +++++++++++---
 4 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index 72cf790..4681e9f 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@
 
   * Fix memory leak in C implementation of sorted_tree_items. (Dave Borowitz)
 
+  * Use correct path separators for named repo files. (Dave Borowitz)
+
  FEATURES
 
   * Move named file initilization to BaseRepo. (Dave Borowitz)
diff --git a/dulwich/repo.py b/dulwich/repo.py
index ffda6d6..322d776 100644
--- a/dulwich/repo.py
+++ b/dulwich/repo.py
@@ -758,7 +758,7 @@ class BaseRepo(object):
                                         'filemode = true\n'
                                         'bare = false\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):
         """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.
         :contents: A string to write to the file.
         """
+        path = path.lstrip(os.path.sep)
         f = GitFile(os.path.join(self.controldir(), path), 'wb')
         try:
             f.write(contents)
@@ -1111,8 +1112,11 @@ class Repo(BaseRepo):
         :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.
         """
+        # TODO(dborowitz): sanitize filenames, since this is used directly by
+        # the dumb web serving code.
+        path = path.lstrip(os.path.sep)
         try:
-            return open(os.path.join(self.controldir(), path.lstrip('/')), 'rb')
+            return open(os.path.join(self.controldir(), path), 'rb')
         except (IOError, OSError), e:
             if e.errno == errno.ENOENT:
                 return None
diff --git a/dulwich/tests/test_repository.py b/dulwich/tests/test_repository.py
index ee7d861..423d3b1 100644
--- a/dulwich/tests/test_repository.py
+++ b/dulwich/tests/test_repository.py
@@ -50,11 +50,28 @@ missing_sha = 'b91fa4d900e17e99b433218e988c4eb4a3e9a097'
 
 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()
         try:
             repo = Repo.init_bare(tmp_dir)
             self.assertEquals(tmp_dir, repo._controldir)
+            self._check_repo_contents(repo)
         finally:
             shutil.rmtree(tmp_dir)
 
diff --git a/dulwich/web.py b/dulwich/web.py
index 380d507..a9776ca 100644
--- a/dulwich/web.py
+++ b/dulwich/web.py
@@ -19,6 +19,7 @@
 """HTTP server for dulwich that implements the git smart HTTP protocol."""
 
 from cStringIO import StringIO
+import os
 import re
 import time
 
@@ -98,9 +99,14 @@ def send_file(req, f, content_type):
         raise
 
 
+def _url_to_path(url):
+    return url.replace('/', os.path.sep)
+
+
 def get_text_file(req, backend, mat):
     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')
 
 
@@ -121,13 +127,15 @@ def get_loose_object(req, backend, mat):
 
 def get_pack_file(req, backend, mat):
     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')
 
 
 def get_idx_file(req, backend, mat):
     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')
 
 
-- 
1.7.0.4




References