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 2018/01/27 12:38:39 UTC

svn commit: r1822401 - /subversion/trunk/subversion/libsvn_client/conflicts.c

Author: stsp
Date: Sat Jan 27 12:38:39 2018
New Revision: 1822401

URL: http://svn.apache.org/viewvc?rev=1822401&view=rev
Log:
Fix a crash on strict alignment platforms in the conflict resolver.

* subversion/libsvn_client/conflicts.c
  (configure_option_incoming_move_file_merge,
   configure_option_incoming_dir_merge): The tree_conflict_incoming_details
    pointer does not necessarily point to a data structure of type struct
    conflict_tree_incoming_delete_details. E.g. in case of incoming edits
    it will point to an apr_array_header_t.
    Only cast this pointer to struct conflict_tree_incoming_delete_details
    if the incoming change is in fact a deletion. Otherwise, we can crash on
    strict alignment platforms trying to dereference a misaligned pointer.

Found by: svn-bb-openbsd buildbot

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

Modified: subversion/trunk/subversion/libsvn_client/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/conflicts.c?rev=1822401&r1=1822400&r2=1822401&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_client/conflicts.c Sat Jan 27 12:38:39 2018
@@ -9841,12 +9841,6 @@ configure_option_incoming_move_file_merg
   const char *incoming_new_repos_relpath;
   svn_revnum_t incoming_new_pegrev;
   svn_node_kind_t incoming_new_kind;
-  struct conflict_tree_incoming_delete_details *details;
-
-  details = conflict->tree_conflict_incoming_details;
-  if (details == NULL || details->moves == NULL)
-    return SVN_NO_ERROR;
-
   incoming_change = svn_client_conflict_get_incoming_change(conflict);
   victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
   SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
@@ -9863,8 +9857,13 @@ configure_option_incoming_move_file_merg
       incoming_new_kind == svn_node_none &&
       incoming_change == svn_wc_conflict_action_delete)
     {
+      struct conflict_tree_incoming_delete_details *details;
       const char *description;
 
+      details = conflict->tree_conflict_incoming_details;
+      if (details == NULL || details->moves == NULL)
+        return SVN_NO_ERROR;
+
       if (apr_hash_count(details->wc_move_targets) == 0)
         return SVN_NO_ERROR;
 
@@ -9899,11 +9898,6 @@ configure_option_incoming_dir_merge(svn_
   const char *incoming_new_repos_relpath;
   svn_revnum_t incoming_new_pegrev;
   svn_node_kind_t incoming_new_kind;
-  struct conflict_tree_incoming_delete_details *details;
-
-  details = conflict->tree_conflict_incoming_details;
-  if (details == NULL || details->moves == NULL)
-    return SVN_NO_ERROR;
 
   incoming_change = svn_client_conflict_get_incoming_change(conflict);
   victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
@@ -9921,8 +9915,13 @@ configure_option_incoming_dir_merge(svn_
       incoming_new_kind == svn_node_none &&
       incoming_change == svn_wc_conflict_action_delete)
     {
+      struct conflict_tree_incoming_delete_details *details;
       const char *description;
 
+      details = conflict->tree_conflict_incoming_details;
+      if (details == NULL || details->moves == NULL)
+        return SVN_NO_ERROR;
+
       if (apr_hash_count(details->wc_move_targets) == 0)
         return SVN_NO_ERROR;