While investigating yet another Python testsuite failure, I came upon
something which looks like a bug in Subversion itself.
Consider the following scenario. A user creates a diff editor by using
svn_wc_get_diff_editor4, and passes it a set of callbacks and a callback
baton. We'll call those real_callbacks and real_baton.
svn_wc_get_diff_editor4 is a compatibility function, so it encapsulates
our callbacks and baton in an instance of callbacks2_wrapper_baton, and
uses callbacks2_wrapper as the new set of callbacks. Then it passes this
stuff to svn_wc_get_diff_editor5. But that's a compatibility function too,
and the cycle repeats with callbacks3_wrapper[_baton]. Then the new
parameters are passed to svn_wc_get_diff_editor6, which is the real
Now the editor's real parameters are:
callbacks = &callbacks3_wrapper (4)
baton = callback3_wrapper_baton:
callbacks = &callbacks2_wrapper (3)
baton = callbacks2_wrapper_baton:
callbacks = real_callbacks (2)
Parenthesized numbers indicate the "generation" of the callback structure.
So let's see what happens when we want to call a callback function,
callbacks->dir_props_changed. callbacks3_wrapper.dir_props_changed =
&dir_props_changed2, so dir_props_changed2 is called with a
(callback3_wrapper_baton *) as the argument. But dir_props_changed2 is
actually a (3) to (2) wrapper, and casts the baton to
(callback2_wrapper_baton *)... From there, it just goes downhill (note
that the structures are not compatible).
It looks like callback3_wrapper->dir_props_changed isn't the only member
affected in this way, but I'm yet to determine all the possibilities.
Received on 2009-06-26 20:06:14 CEST