Ver código fonte

Stop magic protocol ref `capabilities^{}` from leaking out to users.

Fixes #254
Jelmer Vernooij 8 anos atrás
pai
commit
5678e842dc
5 arquivos alterados com 36 adições e 11 exclusões
  1. 3 0
      NEWS
  2. 3 0
      dulwich/client.py
  3. 4 0
      dulwich/protocol.py
  4. 9 10
      dulwich/server.py
  5. 17 1
      dulwich/tests/test_client.py

+ 3 - 0
NEWS

@@ -8,6 +8,9 @@
   * Support removing refs from porcelain.push.
     (Jelmer Vernooij, #437)
 
+  * Stop magic protocol ref `capabilities^{}` from leaking out
+    to clients. (Jelmer Vernooij, #254)
+
  IMPROVEMENTS
 
   * Add `dulwich.config.parse_submodules` function.

+ 3 - 0
dulwich/client.py

@@ -70,6 +70,7 @@ from dulwich.protocol import (
     CAPABILITY_REPORT_STATUS,
     CAPABILITY_SIDE_BAND_64K,
     CAPABILITY_THIN_PACK,
+    CAPABILITIES_REF,
     COMMAND_DONE,
     COMMAND_HAVE,
     COMMAND_WANT,
@@ -175,6 +176,8 @@ def read_pkt_refs(proto):
 
     if len(refs) == 0:
         return None, set([])
+    if refs == {CAPABILITIES_REF: ZERO_SHA}:
+        refs = {}
     return refs, set(server_capabilities)
 
 

+ 4 - 0
dulwich/protocol.py

@@ -60,6 +60,10 @@ CAPABILITY_SIDE_BAND_64K = b'side-band-64k'
 CAPABILITY_THIN_PACK = b'thin-pack'
 CAPABILITY_AGENT = b'agent'
 
+# Magic ref that is used to attach capabilities to when
+# there are no refs. Should always be ste to ZERO_SHA.
+CAPABILITIES_REF = b'capabilities^{}'
+
 
 def agent_string():
     return ('dulwich/%d.%d.%d' % dulwich.__version__).encode('ascii')

+ 9 - 10
dulwich/server.py

@@ -69,6 +69,7 @@ from dulwich.pack import (
 from dulwich.protocol import (
     BufferedPktLineWriter,
     capability_agent,
+    CAPABILITIES_REF,
     CAPABILITY_DELETE_REFS,
     CAPABILITY_INCLUDE_TAG,
     CAPABILITY_MULTI_ACK_DETAILED,
@@ -932,16 +933,14 @@ class ReceivePackHandler(PackHandler):
         if self.advertise_refs or not self.http_req:
             refs = sorted(self.repo.get_refs().items())
 
-            if refs:
-                self.proto.write_pkt_line(
-                  refs[0][1] + b' ' + refs[0][0] + b'\0' +
-                  self.capability_line() + b'\n')
-                for i in range(1, len(refs)):
-                    ref = refs[i]
-                    self.proto.write_pkt_line(ref[1] + b' ' + ref[0] + b'\n')
-            else:
-                self.proto.write_pkt_line(ZERO_SHA + b" capabilities^{}\0" +
-                    self.capability_line())
+            if not refs:
+                refs = [(CAPABILITIES_REF, ZERO_SHA)]
+            self.proto.write_pkt_line(
+              refs[0][1] + b' ' + refs[0][0] + b'\0' +
+              self.capability_line() + b'\n')
+            for i in range(1, len(refs)):
+                ref = refs[i]
+                self.proto.write_pkt_line(ref[1] + b' ' + ref[0] + b'\n')
 
             self.proto.write_pkt_line(None)
             if self.advertise_refs:

+ 17 - 1
dulwich/tests/test_client.py

@@ -107,7 +107,23 @@ class GitClientTests(TestCase):
     def test_fetch_empty(self):
         self.rin.write(b'0000')
         self.rin.seek(0)
-        self.client.fetch_pack(b'/', lambda heads: [], None, None)
+        def check_heads(heads):
+            self.assertIs(heads, None)
+            return []
+        self.client.fetch_pack(b'/', check_heads, None, None)
+
+    def test_fetch_pack_ignores_magic_ref(self):
+        self.rin.write(
+            b'00000000000000000000000000000000000000000000 capabilities^{}\x00 multi_ack '
+            b'thin-pack side-band side-band-64k ofs-delta shallow no-progress '
+            b'include-tag\n'
+            b'0000')
+        self.rin.seek(0)
+        def check_heads(heads):
+            self.assertEquals({}, heads)
+            return []
+        self.client.fetch_pack(b'bla', check_heads, None, None, None)
+        self.assertEqual(self.rout.getvalue(), b'0000')
 
     def test_fetch_pack_none(self):
         self.rin.write(