Fix memory lifetime problem in a libsvn_wc error code path.
* subversion/libsvn_wc/wc_db_update_move.c (suitable_for_move): Calling svn_sqlite__column_text() with a NULL result pool twice means the result of the first call becomes invalid. Store the child_relpath variable in a pool. It is passed to path_for_error_message() later, after another call to svn_sqlite__column_text() with a NULL result pool has already occurred.
Crash observed on OpenBSD: #0 strlen () at /usr/src/lib/libc/arch/amd64/string/strlen.S:125 #1 0x00000c38d5de6db7 in svn_dirent_join ( base=0xc38dfe1ef00 "/home/stsp/svn/svn-1.12.0/subversion/tests/libsvn_wc/svn-test-work/working-copies/move_update_subtree", component=0xc390ca94fc8 '\337' <repeats 55 times>, <incomplete sequence \337><error: Cannot access memory at address 0xc390ca95000>, pool=0xc38eeceff00) at subversion/libsvn_subr/dirent_uri.c:1007 #2 0x00000c38f686a815 in path_for_error_message (wcroot=0xc387ee3d300, local_relpath=0xc390ca94fc8 '\337' <repeats 55 times>, <incomplete sequence \337><error: Cannot access memory at address 0xc390ca95000>, result_pool=0xc38eeceff00) at subversion/libsvn_wc/wc_db_update_move.c:167 #3 0x00000c38f686ad1f in suitable_for_move (wcroot=0xc387ee3d300, local_relpath=0xc387efe4ce0 "A/B", scratch_pool=0xc38eeceff00) at subversion/libsvn_wc/wc_db_update_move.c:2192
Record the move target path in a moved-away tree conflict skel.
Updates can modify the NODES table in ways which discard local move information about tree conflict victims. One example is:
echo foo >> epsilon/foo.txt svn mv epsilon alpha svn ci # create r2 svn up -r1 svn mv epsilon beta svn up -r2
When 'epsilon' is updated to r2, a tree conflict is raised and the move 'epsilon' -> 'beta' is deleted from the NODES table. 'beta' remains a copy.
$ svn status A + beta ! C epsilon > local dir moved away, incoming dir delete or move upon update $
The conflict skel for the tree conflict on 'epsilon' now contains: (tree () moved-away deleted epsilon)
This leaves the resolver with insufficient information about the local move 'epsilon' -> 'beta' which existed before the update. To resolve this conflict we must be able to identify the copy 'beta' as one potential move target. The fact that copyfrom on 'beta' points to 'epsilon' is insufficient because, in the general case, this copy could have occurred independently of the tree conflict.
As of this commit, the tree conflict skel also records a move destination path, 'beta' in our example: (tree () moved-away deleted epsilon beta)
Apart from recording the path in the skel, this commit introduces no other visible change in behaviour. In the future, the conflict resolver will be able to make use of this new information to correlate the copy 'beta' with the conflict victim 'epsilon' in the above example.
Note that old clients will simply ignore the new extra element at the end of the conflict skel.
* subversion/libsvn_wc/conflicts.c (svn_wc__conflict_skel_add_tree_conflict): Add move_dst_op_root_abspath parameter and append it to the skel if it is non-NULL. (svn_wc__conflict_read_tree_conflict): Return the move_dst_op_root_abspath if present in the conflict skel. (read_tree_conflict_desc, resolve_tree_conflict_on_node, svn_wc__conflict_tree_update_break_moved_away, svn_wc__conflict_tree_update_incoming_move, svn_wc__conflict_tree_update_local_add): Update callers.
* subversion/libsvn_wc/conflicts.h (svn_wc__conflict_skel_add_tree_conflict, svn_wc__conflict_read_tree_conflict): Update declaration and docstring.