Apply a patch from upstream which fixes an assertion failure during merge.

Noticed by and ok mpi@
This commit is contained in:
stsp 2011-10-14 10:13:05 +00:00
parent bbe2caba68
commit 15dd757d5c
2 changed files with 197 additions and 1 deletions

View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.98 2011/10/13 11:22:58 stsp Exp $
# $OpenBSD: Makefile,v 1.99 2011/10/14 10:13:05 stsp Exp $
COMMENT-main= subversion revision control system
COMMENT-perl= perl interface to subversion
@ -18,6 +18,8 @@ FULLPKGPATH-ruby= devel/subversion,-ruby
FULLPKGNAME-ap2= ap2-subversion-${VERSION}
FULLPKGPATH-ap2= devel/subversion,-ap2
REVISION-main= 0
SO_VERSION= 1.3
SVN_LIBS= svn_client-1 svn_delta-1 svn_diff-1 svn_fs-1 \
svn_fs_base-1 svn_fs_fs-1 svn_fs_util-1 svn_ra-1 svn_ra_neon-1 \

View File

@ -0,0 +1,194 @@
$OpenBSD: patch-subversion_libsvn_client_merge_c,v 1.1 2011/10/14 10:13:08 stsp Exp $
Fix a possible crash during merge; from upstream
--- subversion/libsvn_client/merge.c.orig Tue Sep 27 18:30:36 2011
+++ subversion/libsvn_client/merge.c Thu Oct 13 18:02:51 2011
@@ -2726,6 +2726,43 @@ notification_receiver(void *baton, const svn_wc_notify
(*notify_b->wrapped_func)(notify_b->wrapped_baton, notify, pool);
}
+/* Set *OUT_RANGELIST to the intersection of IN_RANGELIST with the simple
+ * (inheritable) revision range REV1:REV2, according to CONSIDER_INHERITANCE.
+ * If REV1 is equal to REV2, the result is an empty rangelist, otherwise
+ * REV1 must be less than REV2.
+ *
+ * Note: If CONSIDER_INHERITANCE is FALSE, the effect is to treat any non-
+ * inheritable input ranges as if they were inheritable. If it is TRUE, the
+ * effect is to discard any non-inheritable input ranges. Therefore the
+ * ranges in *OUT_RANGELIST will always be inheritable. */
+static svn_error_t *
+rangelist_intersect_range(apr_array_header_t **out_rangelist,
+ const apr_array_header_t *in_rangelist,
+ svn_revnum_t rev1,
+ svn_revnum_t rev2,
+ svn_boolean_t consider_inheritance,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR_ASSERT(rev1 <= rev2);
+
+ if (rev1 < rev2)
+ {
+ apr_array_header_t *simple_rangelist =
+ svn_rangelist__initialize(rev1, rev2, TRUE, scratch_pool);
+
+ SVN_ERR(svn_rangelist_intersect(out_rangelist,
+ simple_rangelist, in_rangelist,
+ consider_inheritance, result_pool));
+ }
+ else
+ {
+ *out_rangelist = apr_array_make(result_pool, 0,
+ sizeof(svn_merge_range_t *));
+ }
+ return SVN_NO_ERROR;
+}
+
/* Helper for fix_deleted_subtree_ranges(). Like fix_deleted_subtree_ranges()
this function should only be called when honoring mergeinfo.
@@ -2824,7 +2861,6 @@ adjust_deleted_subtree_ranges(svn_client__merge_path_t
svn_revnum_t younger_rev = is_rollback ? revision1 : revision2;
svn_revnum_t peg_rev = younger_rev;
svn_revnum_t older_rev = is_rollback ? revision2 : revision1;
- svn_revnum_t revision_primary_url_deleted = SVN_INVALID_REVNUM;
apr_array_header_t *segments;
const char *rel_source_path;
const char *session_url;
@@ -2879,20 +2915,20 @@ adjust_deleted_subtree_ranges(svn_client__merge_path_t
}
else
{
- apr_array_header_t *exists_rangelist, *deleted_rangelist;
+ apr_array_header_t *deleted_rangelist;
+ svn_revnum_t rev_primary_url_deleted;
/* PRIMARY_URL@older_rev exists, so it was deleted at some
revision prior to peg_rev, find that revision. */
SVN_ERR(svn_ra_get_deleted_rev(ra_session, rel_source_path,
older_rev, younger_rev,
- &revision_primary_url_deleted,
+ &rev_primary_url_deleted,
scratch_pool));
/* PRIMARY_URL@older_rev exists and PRIMARY_URL@peg_rev doesn't,
so svn_ra_get_deleted_rev() should always find the revision
PRIMARY_URL@older_rev was deleted. */
- SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(
- revision_primary_url_deleted));
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(rev_primary_url_deleted));
/* If this is a reverse merge reorder CHILD->REMAINING_RANGES and
PARENT->REMAINING_RANGES so both will work with the
@@ -2910,41 +2946,22 @@ adjust_deleted_subtree_ranges(svn_client__merge_path_t
/* Find the intersection of CHILD->REMAINING_RANGES with the
range over which PRIMARY_URL@older_rev exists (ending at
the youngest revision at which it still exists). */
- if (revision_primary_url_deleted - 1 > older_rev)
- {
- /* It was not deleted immediately after OLDER_REV, so
- it has some relevant changes. */
- exists_rangelist =
- svn_rangelist__initialize(older_rev,
- revision_primary_url_deleted - 1,
- TRUE, scratch_pool);
- SVN_ERR(svn_rangelist_intersect(&(child->remaining_ranges),
- exists_rangelist,
- child->remaining_ranges,
- FALSE, scratch_pool));
- }
- else
- {
- /* It was deleted immediately after the OLDER rev, so
- it has no relevant changes. */
- child->remaining_ranges
- = apr_array_make(scratch_pool, 0,
- sizeof(svn_merge_range_t *));
- }
+ SVN_ERR(rangelist_intersect_range(&child->remaining_ranges,
+ child->remaining_ranges,
+ older_rev,
+ rev_primary_url_deleted - 1,
+ FALSE,
+ scratch_pool, scratch_pool));
- /* Find the intersection of PARENT->REMAINING_RANGES with the
- range beginning when PRIMARY_URL@older_rev was deleted
- until younger_rev.
- Finally merge this rangelist with the rangelist above and
- store the result in CHILD->REMANING_RANGES. */
- deleted_rangelist =
- svn_rangelist__initialize(revision_primary_url_deleted - 1,
- peg_rev, TRUE, scratch_pool);
- SVN_ERR(svn_rangelist_intersect(&deleted_rangelist,
- deleted_rangelist,
- parent->remaining_ranges,
- FALSE, scratch_pool));
-
+ /* Merge into CHILD->REMANING_RANGES the intersection of
+ PARENT->REMAINING_RANGES with the range beginning when
+ PRIMARY_URL@older_rev was deleted until younger_rev. */
+ SVN_ERR(rangelist_intersect_range(&deleted_rangelist,
+ parent->remaining_ranges,
+ rev_primary_url_deleted - 1,
+ peg_rev,
+ FALSE,
+ scratch_pool, scratch_pool));
SVN_ERR(svn_rangelist_merge(&(child->remaining_ranges),
deleted_rangelist, scratch_pool));
@@ -2966,7 +2983,7 @@ adjust_deleted_subtree_ranges(svn_client__merge_path_t
}
else /* PRIMARY_URL@peg_rev exists. */
{
- apr_array_header_t *exists_rangelist, *non_existent_rangelist;
+ apr_array_header_t *non_existent_rangelist;
svn_location_segment_t *segment =
APR_ARRAY_IDX(segments, (segments->nelts - 1),
svn_location_segment_t *);
@@ -2993,32 +3010,22 @@ adjust_deleted_subtree_ranges(svn_client__merge_path_t
scratch_pool));
}
- /* Since segment doesn't span older_rev:peg_rev we know
+ /* Intersect CHILD->REMAINING_RANGES with the range where PRIMARY_URL
+ exists. Since segment doesn't span older_rev:peg_rev we know
PRIMARY_URL@peg_rev didn't come into existence until
- segment->range_start + 1. Create a rangelist describing
- range where PRIMARY_URL exists and find the intersection of that
- range and CHILD->REMAINING_RANGELIST. */
- exists_rangelist = svn_rangelist__initialize(segment->range_start,
- peg_rev, TRUE,
- scratch_pool);
- SVN_ERR(svn_rangelist_intersect(&(child->remaining_ranges),
- exists_rangelist,
- child->remaining_ranges,
- FALSE, scratch_pool));
+ segment->range_start + 1. */
+ SVN_ERR(rangelist_intersect_range(&child->remaining_ranges,
+ child->remaining_ranges,
+ segment->range_start, peg_rev,
+ FALSE, scratch_pool, scratch_pool));
- /* Create a second rangelist describing the range before
- PRIMARY_URL@peg_rev came into existence and find the intersection of
- that range and PARENT->REMAINING_RANGES. Then merge that rangelist
- with exists_rangelist and store the result in
- CHILD->REMANING_RANGES. */
- non_existent_rangelist = svn_rangelist__initialize(older_rev,
- segment->range_start,
- TRUE, scratch_pool);
- SVN_ERR(svn_rangelist_intersect(&non_existent_rangelist,
- non_existent_rangelist,
- parent->remaining_ranges,
- FALSE, scratch_pool));
-
+ /* Merge into CHILD->REMANING_RANGES the intersection of
+ PARENT->REMAINING_RANGES with the range before PRIMARY_URL@peg_rev
+ came into existence. */
+ SVN_ERR(rangelist_intersect_range(&non_existent_rangelist,
+ parent->remaining_ranges,
+ older_rev, segment->range_start,
+ FALSE, scratch_pool, scratch_pool));
SVN_ERR(svn_rangelist_merge(&(child->remaining_ranges),
non_existent_rangelist, scratch_pool));