Merge lp:~weyrick/bzr/720853-max-recursion-depth into lp:bzr

Proposed by Shannon Weyrick
Status: Merged
Approved by: Martin Pool
Approved revision: no longer in the source branch.
Merged at revision: 6256
Proposed branch: lp:~weyrick/bzr/720853-max-recursion-depth
Merge into: lp:bzr
Diff against target: 48 lines (+17/-0)
3 files modified
bzrlib/btree_index.py (+6/-0)
bzrlib/tests/test_btree_index.py (+8/-0)
doc/en/release-notes/bzr-2.5.txt (+3/-0)
To merge this branch: bzr merge lp:~weyrick/bzr/720853-max-recursion-depth
Reviewer Review Type Date Requested Status
Martin Pool Approve
John A Meinel Needs Fixing
Robert Collins Pending
Review via email: mp+81297@code.launchpad.net

Commit message

raise BadIndexKey rather than crashing if the key is unreasonably long

Description of the change

Fix recursion problem by explicitly checking for a key that is too big to fit in a page.

To post a comment you must log in.
Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 11/04/2011 05:41 PM, Shannon Weyrick wrote:
> Shannon Weyrick has proposed merging
> lp:~weyrick/bzr/720853-max-recursion-depth into lp:bzr.
>
> Requested reviews: Robert Collins (lifeless) Related bugs: Bug
> #720853 in Bazaar: "bzr crashed with RuntimeError in normpath():
> maximum recursion depth exceeded while calling a Python object"
> https://bugs.launchpad.net/bzr/+bug/720853
>
> For more details, see:
> https://code.launchpad.net/~weyrick/bzr/720853-max-recursion-depth/+merge/81297
>
> Fix recursion problem by explicitly checking for a key that is too
> big to fit in a page. In that case, the key is skipped.

Silently discarding user data is not a good way to go. I can see
teaching something like bzr-search handling an error that indicates it
can ignore the request, but we really don't want to silently skip data
that cannot be recorded.

 review: needsfixing

John
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk60SBQACgkQJdeBCYSNAAPz9gCfd4Hom4IBhhiNrw25Gw+SF02e
K5sAn3rstL/S7m+9yJXK7688K58VIM5s
=XxxO
-----END PGP SIGNATURE-----

review: Needs Fixing
Revision history for this message
Martin Packman (gz) wrote :

Thanks for working on this!

Do you need any help working out how to write a test that hits this code?

Revision history for this message
Shannon Weyrick (weyrick) wrote :

I've added a test, please review.

Revision history for this message
Martin Pool (mbp) wrote :

that seems to make sense to me.

i would kind of like a second review from john or robert.

review: Approve
Revision history for this message
Martin Pool (mbp) wrote :

the other question is, what will happen to bzr-search when it gets BadIndexKey from this? Does the program abort, but with a cleaner message, or does it cope, and if so how?

Revision history for this message
Shannon Weyrick (weyrick) wrote :

Yes so this patch is just the bzrlib side. bzr-search would ideally handle this raised exception better. Currently, yes, it aborts with a cleaner message, not to mention much faster than without this patch.

Revision history for this message
Martin Pool (mbp) wrote :

robert agreed on irc

Revision history for this message
Martin Pool (mbp) wrote :

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/btree_index.py'
2--- bzrlib/btree_index.py 2011-08-19 22:34:02 +0000
3+++ bzrlib/btree_index.py 2011-11-11 01:10:29 +0000
4@@ -320,6 +320,12 @@
5 optimize_for_size=self._optimize_for_size)
6 rows[-1].writer.write(_LEAF_FLAG)
7 if rows[-1].writer.write(line):
8+ # if we failed to write, despite having an empty page to write to,
9+ # then line is too big. len is 2 here because we've already written
10+ # some header. raising the error avoids infinite recursion searching
11+ # for a suitably large page that will not be found.
12+ if rows[-1].writer.bytes_out_len <= 2:
13+ raise errors.BadIndexKey(string_key)
14 # this key did not fit in the node:
15 rows[-1].finish_node()
16 key_line = string_key + "\n"
17
18=== modified file 'bzrlib/tests/test_btree_index.py'
19--- bzrlib/tests/test_btree_index.py 2011-08-19 22:34:02 +0000
20+++ bzrlib/tests/test_btree_index.py 2011-11-11 01:10:29 +0000
21@@ -831,6 +831,14 @@
22 btree_index.BTreeGraphIndex(t1, 'index', 10) !=
23 btree_index.BTreeGraphIndex(t1, 'index', 20))
24
25+ def test_key_too_big(self):
26+ # the size that matters here is the _compressed_ size of the key, so we can't
27+ # do a simple character repeat.
28+ bigKey = ''.join(map(repr, xrange(btree_index._PAGE_SIZE)))
29+ self.assertRaises(errors.BadIndexKey,
30+ self.make_index,
31+ nodes=[((bigKey,), 'value', ())])
32+
33 def test_iter_all_only_root_no_size(self):
34 self.make_index(nodes=[(('key',), 'value', ())])
35 t = transport.get_transport_from_url('trace+' + self.get_url(''))
36
37=== modified file 'doc/en/release-notes/bzr-2.5.txt'
38--- doc/en/release-notes/bzr-2.5.txt 2011-11-10 13:56:18 +0000
39+++ doc/en/release-notes/bzr-2.5.txt 2011-11-11 01:10:29 +0000
40@@ -511,6 +511,9 @@
41 operations that use it, like merge, can now create trees without a root.
42 (Aaron Bentley)
43
44+* Raise BadIndexKey exception in btree_index when a key is too large, fixing
45+ an infinite recursion issue. (Shannon Weyrick, #720853)
46+
47 Documentation
48 *************
49