You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2012/07/13 01:58:53 UTC

svn commit: r1361007 - /subversion/trunk/subversion/libsvn_wc/merge.c

Author: rhuijben
Date: Thu Jul 12 23:58:53 2012
New Revision: 1361007

URL: http://svn.apache.org/viewvc?rev=1361007&view=rev
Log:
Make sure 'svn merge' can't break the workqueue by copying files that are not
in the working copy, into the working copy temp dir before installing a
workqueue item that references it.

The merge code calls this function with files in the system temp directory.

* subversion/libsvn_wc/merge.c
  (merge_file_trivial): Add cancel_func arguments. Copy to be installed file
    to the workingcopy temp dir if necessary.
  (svn_wc__internal_merge): Update caller.

Modified:
    subversion/trunk/subversion/libsvn_wc/merge.c

Modified: subversion/trunk/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/merge.c?rev=1361007&r1=1361006&r2=1361007&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/merge.c (original)
+++ subversion/trunk/subversion/libsvn_wc/merge.c Thu Jul 12 23:58:53 2012
@@ -626,6 +626,8 @@ merge_file_trivial(svn_skel_t **work_ite
                    const char *detranslated_target_abspath,
                    svn_boolean_t dry_run,
                    svn_wc__db_t *db,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
 {
@@ -670,6 +672,40 @@ merge_file_trivial(svn_skel_t **work_ite
           *merge_outcome = svn_wc_merge_merged;
           if (!dry_run)
             {
+              const char *wcroot_abspath;
+              svn_boolean_t delete_src;
+              /* The right_abspath might be outside our working copy. In that
+                 case we should copy the file to a safe location before
+                 installing to avoid breaking the workqueue */
+
+              SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath,
+                                            db, target_abspath,
+                                            scratch_pool, scratch_pool));
+
+              if (!svn_dirent_is_child(wcroot_abspath, right_abspath, NULL))
+                {
+                  svn_stream_t *tmp_src;
+                  svn_stream_t *tmp_dst;
+
+                  SVN_ERR(svn_stream_open_readonly(&tmp_src, right_abspath,
+                                                   scratch_pool,
+                                                   scratch_pool));
+
+                  SVN_ERR(svn_wc__open_writable_base(&tmp_dst, &right_abspath,
+                                                     NULL, NULL,
+                                                     db, target_abspath,
+                                                     scratch_pool,
+                                                     scratch_pool));
+
+                  SVN_ERR(svn_stream_copy3(tmp_src, tmp_dst,
+                                           cancel_func, cancel_baton,
+                                           scratch_pool));
+
+                  /* no need to strdup right_abspath, as the wq_build_()
+                     call already does that for us */
+                  delete_src = TRUE;
+                }
+
               SVN_ERR(svn_wc__wq_build_file_install(
                         &work_item, db, target_abspath, right_abspath,
                         FALSE /* use_commit_times */,
@@ -677,6 +713,15 @@ merge_file_trivial(svn_skel_t **work_ite
                         result_pool, scratch_pool));
               *work_items = svn_wc__wq_merge(*work_items, work_item,
                                              result_pool);
+
+              if (delete_src)
+                {
+                  SVN_ERR(svn_wc__wq_build_file_remove(
+                                    &work_item, db, right_abspath,
+                                    result_pool, scratch_pool));
+                  *work_items = svn_wc__wq_merge(*work_items, work_item,
+                                                 result_pool);
+                }
             }
         }
 
@@ -1019,7 +1064,8 @@ svn_wc__internal_merge(svn_skel_t **work
   SVN_ERR(merge_file_trivial(work_items, merge_outcome,
                              left_abspath, right_abspath,
                              target_abspath, detranslated_target_abspath,
-                             dry_run, db, result_pool, scratch_pool));
+                             dry_run, db, cancel_func, cancel_baton,
+                             result_pool, scratch_pool));
   if (*merge_outcome == svn_wc_merge_no_merge)
     {
       if (is_binary)