Re: valgrind UMRs in "svn merge --record-only"
Paul Burba <[email protected]> Mon, 30 Nov 2009 18:18:30 -0500
| Newsgroups | gmane.comp.version-control.subversion.devel,gmane.comp.version-control.subversion.rapidsvn.devel |
|---|---|
| Message-ID | <[email protected]> |
On Mon, Nov 30, 2009 at 9:42 AM, Philip Martin <[email protected]> wrote: > I'm seeing an unitialised memory read during "svn merge --record-only" > in places like blame_tests.py 10. This happens when > libsvn_client/repos_diff.c:add_directory calls > libsvn_client/merge.c:merge_dir_added which does: > > /* Easy out: We are only applying mergeinfo changes to existing paths. */ > if (merge_b->record_only) > { > svn_pool_destroy(subpool); > return SVN_NO_ERROR; > } > > without setting *state so when add_directory then goes on the check > state it triggers the UMR. One fix would be soemthing like: > > Index: subversion/libsvn_client/merge.c > =================================================================== > --- subversion/libsvn_client/merge.c (revision 885260) > +++ subversion/libsvn_client/merge.c (working copy) > @@ -2003,6 +2003,8 @@ > /* Easy out: We are only applying mergeinfo changes to existing paths. */ > if (merge_b->record_only) > { > + if (*state) > + *state = svn_wc_notify_state_unknown; > svn_pool_destroy(subpool); > return SVN_NO_ERROR; > } > > > but I'm not sure that svn_wc_notify_state_unknown is correct. Does > the comment about only applying to existing paths mean that because > this is an add the directory does not exist in the working copy? Does > that mean that svn_wc_notify_state_missing would be better than > svn_wc_notify_state_unknown? > > The same code occurs in other places such as merge_dir_deleted, > merge_file_added and while these don't trigger UMRs I suspect that is > down to limited test coverage. Take merge_dir_deleted for example: it > doesn't set either *state or *tree_conflicted. It's even less clear > what the comment about only applying to existing paths means here. Hi (and welcome back!) Philip, Those 'if (merge_b->record_only)' early exits were added in r880264 which implemented the change that allows --record-only merges to apply only svn:mergeinfo diffs, see http://svn.haxx.se/dev/archive-2009-09/0520.shtml. You are correct about the the comment 'We are only applying mergeinfo changes to existing paths', as regards merge_dir_added (and merge_file_added); since we are applying only mergeinfo diffs we do not want to actually add any files/dirs. Unfortunately I used the same comment for merge_file_changed, merge_file_deleted, and merge_dir_deleted, which is quite wrong. The comment should universally be changed to: /* Easy out: We are only applying mergeinfo differences. */ Is that any clearer? Re what svn_wc_notify_state_t to return, I think that svn_wc_notify_state_unchanged makes the most sense for merge_file_changed, merge_file_deleted, merge_dir_deleted. I'm a bit less certain about merge_file_added and merge_dir_added, but svn_wc_notify_state_unchanged still seems to fit, since we haven't added anything. I'm fairly certain that svn_wc_notify_state_missing is wrong because how can we say a path was missing when we are asking to add it? The attached patch has the comment fix and sets any uninitialized output parameters to svn_wc_notify_state_unchanged, I'm running the tests right now to see if anything falls out... [[[ Follow-up to r880264, be sure to set state and tree conflict output parameters during --record-only merges. Found by: philip * subversion/libsvn_client/merge.c (merge_file_changed, merge_file_added, merge_file_deleted, merge_dir_added, merge_dir_deleted): Improve comments regarding early return during --record-only merges. Set any svn_wc_notify_state_t * arguments to svn_wc_notify_state_unchanged and any tree conflicted output argument to false, if any of these are not already set. ]]] Paul ------------------------------------------------------ http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=2425700 Please start new threads on the <[email protected]> mailing list. To subscribe to the new list, send an empty e-mail to <[email protected]>.
dont.forget.output.parms.1.diff.txt
(text/plain, 2.5 KB)
Index: subversion/libsvn_client/merge.c
===================================================================
--- subversion/libsvn_client/merge.c (revision 885596)
+++ subversion/libsvn_client/merge.c (working copy)
@@ -1426,10 +1426,12 @@
if (prop_state)
*prop_state = svn_wc_notify_state_unchanged;
- /* Easy out: We are only applying mergeinfo changes to existing paths. */
+ /* Easy out: We are only applying mergeinfo differences. */
if (merge_b->record_only)
{
svn_pool_destroy(subpool);
+ if (content_state);
+ *content_state = svn_wc_notify_state_unchanged;
return SVN_NO_ERROR;
}
@@ -1556,10 +1558,16 @@
apr_hash_t *new_props;
const char *mine_abspath;
- /* Easy out: We are only applying mergeinfo changes to existing paths. */
+ /* Easy out: We are only applying mergeinfo differences. */
if (merge_b->record_only)
{
svn_pool_destroy(subpool);
+ if (content_state)
+ *content_state = svn_wc_notify_state_unchanged;
+ if (prop_state)
+ *prop_state = svn_wc_notify_state_unchanged;
+ if (tree_conflicted)
+ *tree_conflicted = FALSE;
return SVN_NO_ERROR;
}
@@ -1859,10 +1867,14 @@
svn_node_kind_t kind;
const char *mine_abspath;
- /* Easy out: We are only applying mergeinfo changes to existing paths. */
+ /* Easy out: We are only applying mergeinfo differences. */
if (merge_b->record_only)
{
svn_pool_destroy(subpool);
+ if (state)
+ *state = svn_wc_notify_state_unchanged;
+ if (tree_conflicted)
+ *tree_conflicted = FALSE;
return SVN_NO_ERROR;
}
@@ -2000,10 +2012,14 @@
svn_boolean_t is_deleted;
svn_error_t *err;
- /* Easy out: We are only applying mergeinfo changes to existing paths. */
+ /* Easy out: We are only applying mergeinfo differences. */
if (merge_b->record_only)
{
svn_pool_destroy(subpool);
+ if (state)
+ *state = svn_wc_notify_state_unchanged;
+ if (tree_conflicted)
+ *tree_conflicted = FALSE;
return SVN_NO_ERROR;
}
@@ -2213,10 +2229,14 @@
svn_boolean_t is_versioned;
svn_boolean_t is_deleted;
- /* Easy out: We are only applying mergeinfo changes to existing paths. */
+ /* Easy out: We are only applying mergeinfo differences. */
if (merge_b->record_only)
{
svn_pool_destroy(subpool);
+ if (state)
+ *state = svn_wc_notify_state_unchanged;
+ if (tree_conflicted)
+ *tree_conflicted = FALSE;
return SVN_NO_ERROR;
}