Rev 3854: (jam) Part of bug #295161, prohibit characters that won't round trip. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Nov 25 20:35:37 GMT 2008


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3854
revision-id: pqm at pqm.ubuntu.com-20081125203528-0vccybk8fasrh3fn
parent: pqm at pqm.ubuntu.com-20081125191811-pwwzoldg0s0wkze8
parent: john at arbash-meinel.com-20081125195600-lwovdm2idircn2o5
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2008-11-25 20:35:28 +0000
message:
  (jam) Part of bug #295161, prohibit characters that won't round trip.
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
  bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
  bzrlib/tests/per_repository/test_revision.py testrevprops.py-20051013073044-92bc3c68302ce1bf
  bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
    ------------------------------------------------------------
    revno: 3831.1.6
    revision-id: john at arbash-meinel.com-20081125195600-lwovdm2idircn2o5
    parent: john at arbash-meinel.com-20081125185148-jsfkqnzfjjqsleds
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: revision_strictness
    timestamp: Tue 2008-11-25 13:56:00 -0600
    message:
      For the simple-log tests, avoid using '\r' in the test.
    modified:
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
    ------------------------------------------------------------
    revno: 3831.1.5
    revision-id: john at arbash-meinel.com-20081125185148-jsfkqnzfjjqsleds
    parent: john at arbash-meinel.com-20081125172714-184bkswbz4bc5ffe
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: revision_strictness
    timestamp: Tue 2008-11-25 12:51:48 -0600
    message:
      It seems we have some direct tests that don't use strings and expect a value error as well.
      
      They would be sanitized later on by Revision. We could use that code, but this test
      depends on the serializer, which Revision wouldn't know about.
    modified:
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/tests/per_repository/test_revision.py testrevprops.py-20051013073044-92bc3c68302ce1bf
    ------------------------------------------------------------
    revno: 3831.1.4
    revision-id: john at arbash-meinel.com-20081125172714-184bkswbz4bc5ffe
    parent: john at arbash-meinel.com-20081125170722-s9bl39idjxylrura
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: revision_strictness
    timestamp: Tue 2008-11-25 11:27:14 -0600
    message:
      Update the per-repository unicode commit test.
      
      We no longer allow '\r' to be passed in, and the test asserted that it was
      replaced with '\n' anyway.
    modified:
      bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
    ------------------------------------------------------------
    revno: 3831.1.3
    revision-id: john at arbash-meinel.com-20081125170722-s9bl39idjxylrura
    parent: john at arbash-meinel.com-20081113055624-ilm4on4r4s7svu6d
    parent: pqm at pqm.ubuntu.com-20081125152232-c22rycit2dfzm11f
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: revision_strictness
    timestamp: Tue 2008-11-25 11:07:22 -0600
    message:
      Merge bzr.dev, resolve NEWS
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
      bzrlib/_readdir_pyx.pyx        readdir.pyx-20060609152855-rm6v321vuaqyh9tu-1
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/btree_index.py          index.py-20080624222253-p0x5f92uyh5hw734-7
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
      bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
      bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/lockable_files.py       control_files.py-20051111201905-bb88546e799d669f
      bzrlib/option.py               option.py-20051014052914-661fb36e76e7362f
      bzrlib/plugin.py               plugin.py-20050622060424-829b654519533d69
      bzrlib/plugins/launchpad/account.py account.py-20071011033320-50y6vfftywf4yllw-1
      bzrlib/plugins/launchpad/lp_directory.py lp_indirect.py-20070126012204-de5rugwlt22c7u7e-1
      bzrlib/plugins/launchpad/test_account.py test_account.py-20071011033320-50y6vfftywf4yllw-2
      bzrlib/python-compat.h         pythoncompat.h-20080924041409-9kvi0fgtuuqp743j-1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/shelf_ui.py             shelver.py-20081005210102-33worgzwrtdw0yrm-1
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/branch_implementations/test_stacking.py test_stacking.py-20080214020755-msjlkb7urobwly0f-1
      bzrlib/tests/interrepository_implementations/test_fetch.py test_fetch.py-20080425213627-j60cjh782ufm83ry-1
      bzrlib/tests/per_repository/test_write_group.py test_write_group.py-20070716105516-89n34xtogq5frn0m-1
      bzrlib/tests/test_btree_index.py test_index.py-20080624222253-p0x5f92uyh5hw734-13
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_pack_repository.py test_pack_repository-20080801043947-eaw0e6h2gu75kwmy-1
      bzrlib/tests/test_permissions.py test_permissions.py-20051215004520-ccf475789c80e80c
      bzrlib/tests/test_plugins.py   plugins.py-20050622075746-32002b55e5e943e9
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
      bzrlib/tests/test_revision.py  testrevision.py-20050804210559-46f5e1eb67b01289
      bzrlib/tests/test_shelf_ui.py  test_shelf_ui.py-20081027155203-wtcuazg85wp9u4fv-1
      bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
      bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
    ------------------------------------------------------------
    revno: 3831.1.2
    revision-id: john at arbash-meinel.com-20081113055624-ilm4on4r4s7svu6d
    parent: john at arbash-meinel.com-20081112073857-fm1qchpnttxt6vav
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: revision_strictness
    timestamp: Wed 2008-11-12 23:56:24 -0600
    message:
      Reference bug #295161
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 3831.1.1
    revision-id: john at arbash-meinel.com-20081112073857-fm1qchpnttxt6vav
    parent: pqm at pqm.ubuntu.com-20081112012514-6y8u99lf11pk0rdm
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: revision_strictness
    timestamp: Wed 2008-11-12 01:38:57 -0600
    message:
      Before allowing commit to succeed, verify the texts will be 'safe'.
      
      This is done via CommitBuilder, so that repositories which could handle those
      texts can allow them. For now, all repos use XML serialization, and need to
      assert that we don't have characters that won't round-trip through XML.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
=== modified file 'NEWS'
--- a/NEWS	2008-11-25 17:31:02 +0000
+++ b/NEWS	2008-11-25 20:35:28 +0000
@@ -58,6 +58,11 @@
 
   API CHANGES:
 
+    * ``CommitBuilder`` now validates the strings it will be committing,
+      to ensure that they do not have characters that will not be properly
+      round-tripped. For now, it just checks for characters that are
+      invalid in the XML form. (John Arbash Meinel, #295161)
+
     * Constructor parameters for NewPack (internal to pack repositories)
       have changed incompatibly.
 

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2008-11-21 20:24:15 +0000
+++ b/bzrlib/repository.py	2008-11-25 18:51:48 +0000
@@ -103,6 +103,7 @@
 
         self._revprops = {}
         if revprops is not None:
+            self._validate_revprops(revprops)
             self._revprops.update(revprops)
 
         if timestamp is None:
@@ -118,11 +119,27 @@
         self._generate_revision_if_needed()
         self.__heads = graph.HeadsCache(repository.get_graph()).heads
 
+    def _validate_unicode_text(self, text, context):
+        """Verify things like commit messages don't have bogus characters."""
+        if '\r' in text:
+            raise ValueError('Invalid value for %s: %r' % (context, text))
+
+    def _validate_revprops(self, revprops):
+        for key, value in revprops.iteritems():
+            # We know that the XML serializers do not round trip '\r'
+            # correctly, so refuse to accept them
+            if not isinstance(value, basestring):
+                raise ValueError('revision property (%s) is not a valid'
+                                 ' (unicode) string: %r' % (key, value))
+            self._validate_unicode_text(value,
+                                        'revision property (%s)' % (key,))
+
     def commit(self, message):
         """Make the actual commit.
 
         :return: The revision id of the recorded revision.
         """
+        self._validate_unicode_text(message, 'commit message')
         rev = _mod_revision.Revision(
                        timestamp=self._timestamp,
                        timezone=self._timezone,

=== modified file 'bzrlib/tests/per_repository/test_commit_builder.py'
--- a/bzrlib/tests/per_repository/test_commit_builder.py	2008-09-22 05:15:20 +0000
+++ b/bzrlib/tests/per_repository/test_commit_builder.py	2008-11-12 07:38:57 +0000
@@ -585,3 +585,21 @@
 
     def test_last_modified_file_link(self):
         self._check_kind_change(self.make_file, self.make_link)
+
+    def test_get_commit_builder_with_invalid_revprops(self):
+        branch = self.make_branch('.')
+        branch.repository.lock_write()
+        self.addCleanup(branch.repository.unlock)
+        self.assertRaises(ValueError, branch.repository.get_commit_builder,
+            branch, [], branch.get_config(),
+            revprops={'invalid': u'property\rwith\r\ninvalid chars'})
+
+    def test_commit_builder_commit_with_invalid_message(self):
+        branch = self.make_branch('.')
+        branch.repository.lock_write()
+        self.addCleanup(branch.repository.unlock)
+        builder = branch.repository.get_commit_builder(branch, [],
+            branch.get_config())
+        self.addCleanup(branch.repository.abort_write_group)
+        self.assertRaises(ValueError, builder.commit,
+            u'Invalid\r\ncommit message\r\n')

=== modified file 'bzrlib/tests/per_repository/test_repository.py'
--- a/bzrlib/tests/per_repository/test_repository.py	2008-09-17 07:18:20 +0000
+++ b/bzrlib/tests/per_repository/test_repository.py	2008-11-25 17:27:14 +0000
@@ -440,7 +440,6 @@
             u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
             lambda match: match.group(0).encode('unicode_escape'),
             message)
-        escaped_message= re.sub('\r', '\n', escaped_message)
         self.assertEqual(rev.message, escaped_message)
         # insist the class is unicode no matter what came in for 
         # consistency.
@@ -452,8 +451,12 @@
 
     def test_commit_unicode_control_characters(self):
         # a unicode message with control characters should roundtrip too.
+        unichars = [unichr(x) for x in range(256)]
+        # '\r' is not directly allowed anymore, as it used to be translated
+        # into '\n' anyway
+        unichars[ord('\r')] = u'\n'
         self.assertMessageRoundtrips(
-            "All 8-bit chars: " +  ''.join([unichr(x) for x in range(256)]))
+            u"All 8-bit chars: " +  ''.join(unichars))
 
     def test_check_repository(self):
         """Check a fairly simple repository's history"""

=== modified file 'bzrlib/tests/per_repository/test_revision.py'
--- a/bzrlib/tests/per_repository/test_revision.py	2008-09-04 20:32:04 +0000
+++ b/bzrlib/tests/per_repository/test_revision.py	2008-11-25 18:51:48 +0000
@@ -31,14 +31,14 @@
                      condiment='orange\n  mint\n\tcandy',
                      empty='',
                      non_ascii=u'\xb5')
-        wt.commit(message='initial null commit', 
+        wt.commit(message='initial null commit',
                  revprops=props,
                  allow_pointless=True,
                  rev_id='test at user-1')
         rev = b.repository.get_revision('test at user-1')
         self.assertTrue('flavor' in rev.properties)
         self.assertEquals(rev.properties['flavor'], 'choc-mint')
-        self.assertEquals([('branch-nick', 'Nicholas'), 
+        self.assertEquals([('branch-nick', 'Nicholas'),
                            ('condiment', 'orange\n  mint\n\tcandy'),
                            ('empty', ''),
                            ('flavor', 'choc-mint'),
@@ -50,11 +50,11 @@
         wt = self.make_branch_and_tree('.')
         b = wt.branch
         self.assertRaises(ValueError,
-                          wt.commit, 
+                          wt.commit,
                           message='invalid',
                           revprops={'what a silly property': 'fine'})
         self.assertRaises(ValueError,
-                          wt.commit, 
+                          wt.commit,
                           message='invalid',
                           revprops=dict(number=13))
 
@@ -63,7 +63,7 @@
     """Test that revision attributes are correct."""
 
     def test_revision_accessors(self):
-        """Make sure the values that come out of a revision are the 
+        """Make sure the values that come out of a revision are the
         same as the ones that go in.
         """
         tree1 = self.make_branch_and_tree("br1")
@@ -91,7 +91,7 @@
                      verbose=True)
         rev_b = tree2.branch.repository.get_revision(
                             tree2.branch.last_revision())
-        
+
         self.assertEqual(rev_a.message, rev_b.message)
         self.assertEqual(rev_a.timestamp, rev_b.timestamp)
         self.assertEqual(rev_a.timezone, rev_b.timezone)

=== modified file 'bzrlib/tests/test_log.py'
--- a/bzrlib/tests/test_log.py	2008-09-22 20:09:07 +0000
+++ b/bzrlib/tests/test_log.py	2008-11-25 19:56:00 +0000
@@ -146,7 +146,7 @@
         self.log('log entries:')
         for logentry in lf.logs:
             self.log('%4s %s' % (logentry.revno, logentry.rev.message))
-        
+
         # first one is most recent
         logentry = lf.logs[0]
         eq(logentry.revno, '2')
@@ -154,9 +154,10 @@
         d = logentry.delta
         self.log('log 2 delta: %r' % d)
         self.checkDelta(d, added=['hello'])
-        
+
         # commit a log message with control characters
-        msg = "All 8-bit chars: " +  ''.join([unichr(x) for x in range(256)])
+        msg = u"All 8-bit chars: " +  ''.join([unichr(x) for x in range(256)])
+        msg = msg.replace(u'\r', u'\n')
         self.log("original commit message: %r", msg)
         wt.commit(msg)
         lf = LogCatcher()




More information about the bazaar-commits mailing list