You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/08/26 17:58:22 UTC

svn commit: r989787 - /subversion/trunk/subversion/libsvn_client/diff.c

Author: stsp
Date: Thu Aug 26 15:58:22 2010
New Revision: 989787

URL: http://svn.apache.org/viewvc?rev=989787&view=rev
Log:
* subversion/libsvn_client/diff.c
  (diff_file_added): Remove code that attempted to check whether the
   copyfrom path was within scope of the diff operation. It could
   lead to out-of-bounds array writes:

      offset = strlen(repos_relpath) - strlen(path) 
                 + strlen(diff_cmd_baton->orig_path_2);
      ancestor_of_path[offset] = '\0';

  Here, path comes from the command line, so if svn diff is run from
  somewhere above the working copy, it could be longer than repos_relpath
  and diff_cmd_baton->orig_path2. Then offset ended up being negative.

  I'm not even sure if transforming copies into adds is a good thing to do.
  We might be able to figure out a way to always produce usable copyfrom
  information, by redefining how svn diff shows paths.
  For now, the copyfrom path will always be relative to the repository root.
  But this is far from ideal, because we can get git diff headers which
  git and hg won't be able to apply, e.g.:
    copy from src/foo.c
    copy to trunk/src/bar.c

Modified:
    subversion/trunk/subversion/libsvn_client/diff.c

Modified: subversion/trunk/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/diff.c?rev=989787&r1=989786&r2=989787&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/diff.c (original)
+++ subversion/trunk/subversion/libsvn_client/diff.c Thu Aug 26 15:58:22 2010
@@ -938,47 +938,12 @@ diff_file_added(const char *local_dir_ab
      user see that *something* happened. */
   diff_cmd_baton->force_empty = TRUE;
 
-  /* ### We still can't detect moves without extending the parameters of
-   * ### file_added(). The *right* thing to do is propably to extend
-   * ### svn_wc_diff_callbacks4_t with file_copied() and file_moved(). */
   if (tmpfile1 && copyfrom_path)
-    {
-      const char *repos_relpath;
-      char *ancestor_of_path;
-      const char *local_abspath;
-      int offset;
-      svn_diff_operation_kind_t op_kind = svn_diff_op_copied;
-
-      SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
-
-      SVN_ERR(svn_wc__node_get_repos_relpath(&repos_relpath, 
-                                             diff_cmd_baton->wc_ctx,
-                                             local_abspath, scratch_pool,
-                                             scratch_pool));
-
-      /* We need to determine if the copyfrom_path is within scope of the
-       * diff we're producing. If not we'll just mark it as an add.
-       * Determining scope involves checking two things; the dir we executed
-       * the command from (orig_path2) and the target of the command (path).
-       *
-       * ### We'll do the same thing for moves but then we'll have to
-       * ### consider the scope of both the delete-half and the add-half. */
-      ancestor_of_path = apr_pstrdup(scratch_pool, repos_relpath);
-
-      offset = strlen(repos_relpath) - strlen(path) 
-                 + strlen(diff_cmd_baton->orig_path_2);
-
-      ancestor_of_path[offset] = '\0';
-
-      if (strncmp(copyfrom_path, ancestor_of_path, strlen(ancestor_of_path)))
-        op_kind = svn_diff_op_added;
-                                             
-      SVN_ERR(diff_content_changed(path,
-                                   tmpfile1, tmpfile2, rev1, rev2,
-                                   mimetype1, mimetype2,
-                                   op_kind, copyfrom_path,
-                                   diff_baton));
-    }
+    SVN_ERR(diff_content_changed(path,
+                                 tmpfile1, tmpfile2, rev1, rev2,
+                                 mimetype1, mimetype2,
+                                 svn_diff_op_copied, copyfrom_path,
+                                 diff_baton));
   else if (tmpfile1)
     SVN_ERR(diff_content_changed(path,
                                  tmpfile1, tmpfile2, rev1, rev2,