Rev 3808: Change deserialise to properly handle when there is a '\r' in the key. in http://bazaar.launchpad.net/%7Ebzr/bzr/brisbane-core

John Arbash Meinel john at arbash-meinel.com
Wed Jan 7 22:16:33 GMT 2009


At http://bazaar.launchpad.net/%7Ebzr/bzr/brisbane-core

------------------------------------------------------------
revno: 3808
revision-id: john at arbash-meinel.com-20090107221557-363iqonfmy1avcl2
parent: john at arbash-meinel.com-20090107215828-ickxzzyp75fwfb6l
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: brisbane-core
timestamp: Wed 2009-01-07 16:15:57 -0600
message:
  Change deserialise to properly handle when there is a '\r' in the key.
  
  It turns out that bytes.splitlines() can split on a plain '\r', which breaks things.
  So instead, we use bytes.split('\n') which work correctly, though we have to remove
  the extra '' at the end.
-------------- next part --------------
=== modified file 'bzrlib/chk_map.py'
--- a/bzrlib/chk_map.py	2009-01-07 20:53:33 +0000
+++ b/bzrlib/chk_map.py	2009-01-07 22:15:57 +0000
@@ -524,7 +524,11 @@
         :param key: The key that the serialised node has.
         """
         result = LeafNode()
-        lines = bytes.splitlines()
+        # Splitlines can split on '\r' so don't use it, split('\n') adds an
+        # extra '' if the bytes ends in a final newline.
+        lines = bytes.split('\n')
+        assert lines[-1] == ''
+        lines.pop(-1)
         items = {}
         if lines[0] != 'chkleaf:':
             raise ValueError("not a serialised leaf node: %r" % bytes)
@@ -780,7 +784,12 @@
         :return: An InternalNode instance.
         """
         result = InternalNode()
-        lines = bytes.splitlines()
+        # Splitlines can split on '\r' so don't use it, remove the extra ''
+        # from the result of split('\n') because we should have a trailing
+        # newline
+        lines = bytes.split('\n')
+        assert lines[-1] == ''
+        lines.pop(-1)
         items = {}
         if lines[0] != 'chknode:':
             raise ValueError("not a serialised internal node: %r" % bytes)

=== modified file 'bzrlib/tests/test_chk_map.py'
--- a/bzrlib/tests/test_chk_map.py	2009-01-07 21:54:42 +0000
+++ b/bzrlib/tests/test_chk_map.py	2009-01-07 22:15:57 +0000
@@ -261,6 +261,37 @@
         self.assertCanonicalForm(chkmap)
         self.assertIsInstance(chkmap._root_node, InternalNode)
 
+    def test_with_linefeed_in_key(self):
+        store = self.get_chk_bytes()
+        chkmap = CHKMap(store, None)
+        # Should fit 1 key per LeafNode
+        chkmap._root_node.set_maximum_size(10)
+        chkmap.map(('a\ra',), 'val1')
+        chkmap.map(('a\rb',), 'val2')
+        chkmap.map(('ac',), 'val3')
+        self.assertCanonicalForm(chkmap)
+        self.assertEqualDiff("'' InternalNode\n"
+                             "  'a\\r' InternalNode\n"
+                             "    'a\\ra' LeafNode\n"
+                             "      ('a\\ra',) 'val1'\n"
+                             "    'a\\rb' LeafNode\n"
+                             "      ('a\\rb',) 'val2'\n"
+                             "  'ac' LeafNode\n"
+                             "      ('ac',) 'val3'\n",
+                             chkmap._dump_tree())
+        # We should also successfully serialise and deserialise these items
+        root_key = chkmap._save()
+        chkmap = CHKMap(store, root_key)
+        self.assertEqualDiff("'' InternalNode\n"
+                             "  'a\\r' InternalNode\n"
+                             "    'a\\ra' LeafNode\n"
+                             "      ('a\\ra',) 'val1'\n"
+                             "    'a\\rb' LeafNode\n"
+                             "      ('a\\rb',) 'val2'\n"
+                             "  'ac' LeafNode\n"
+                             "      ('ac',) 'val3'\n",
+                             chkmap._dump_tree())
+
     def test_deep_splitting(self):
         store = self.get_chk_bytes()
         chkmap = CHKMap(store, None)



More information about the bazaar-commits mailing list