Author: pburba
Date: Thu Jun 2 17:49:36 2011
New Revision: 1130688
URL: http://svn.apache.org/viewvc?rev=1130688&view=rev
Log:
A partial fix for issue #3896 'mergeinfo syntax errors should be treated
gracefully': Tolerate invalid mergeinfo in the repository.
This allows 'svn mergeinfo' to function in the presence of of invalid
mergeinfo in the repository. It also allows 'svn merge' to function if
invalid mergeinfo is inherited by a merge target and the repository must
be contacted to find this inherited mergeinfo.
* subversion/libsvn_fs_base/tree.c
(txn_body_get_mergeinfo_data_and_entries,
txn_body_get_mergeinfo_for_path): If invalid mergeinfo is present on a
node or inherited from a parent node, then ignore it rather than
raising a parse error.
* subversion/libsvn_fs_fs/tree.c
(crawl_directory_dag_for_mergeinfo,
get_mergeinfo_for_path): Same as above.
Modified:
subversion/trunk/subversion/libsvn_fs_base/tree.c
subversion/trunk/subversion/libsvn_fs_fs/tree.c
Modified: subversion/trunk/subversion/libsvn_fs_base/tree.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_base/tree.c?rev=1130688&r1=1130687&r2=1130688&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_base/tree.c Thu Jun 2 17:49:36 2011
@@ -5144,6 +5144,7 @@ txn_body_get_mergeinfo_data_and_entries(
apr_hash_t *plist;
svn_mergeinfo_t child_mergeinfo;
svn_string_t *pval;
+ svn_error_t *err;
SVN_ERR(svn_fs_base__dag_get_proplist(&plist, child_node,
trail, iterpool));
@@ -5157,13 +5158,26 @@ txn_body_get_mergeinfo_data_and_entries(
"mergeinfo but doesn't"),
id_str->data);
}
- SVN_ERR(svn_mergeinfo_parse(&child_mergeinfo, pval->data,
- result_pool));
- apr_hash_set(args->result_catalog,
- svn_fspath__join(args->node_path, dirent->name,
- result_pool),
- APR_HASH_KEY_STRING,
- child_mergeinfo);
+ /* Issue #3896: If syntactically invalid mergeinfo is present on
+ CHILD_NODE then treat it as if no mergeinfo is present rather
+ than raising a parse error. */
+ err = svn_mergeinfo_parse(&child_mergeinfo, pval->data,
+ result_pool);
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
+ svn_error_clear(err);
+ else
+ svn_error_return(err);
+ }
+ else
+ {
+ apr_hash_set(args->result_catalog,
+ svn_fspath__join(args->node_path, dirent->name,
+ result_pool),
+ APR_HASH_KEY_STRING,
+ child_mergeinfo);
+ }
}
/* If the child has descendants with mergeinfo -- that is, if
@@ -5352,28 +5366,63 @@ txn_body_get_mergeinfo_for_path(void *ba
/* If our nearest ancestor is the very path we inquired about, we
can return the mergeinfo results directly. Otherwise, we're
inheriting the mergeinfo, so we need to a) remove non-inheritable
- ranges and b) telescope the merged-from paths. */
+ ranges and b) telescope the merged-from paths.
+
+ /* Issue #3896: If a node has syntactically invalid mergeinfo, then
+ treat it as if no mergeinfo is present rather than raising a parse
+ error. */
if (nearest_ancestor == parent_path)
{
- SVN_ERR(svn_mergeinfo_parse(args->mergeinfo,
- mergeinfo_string->data, args->pool));
+ svn_error_t *err = svn_mergeinfo_parse(args->mergeinfo,
+ mergeinfo_string->data,
+ args->pool);
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
+ {
+ svn_error_clear(err);
+ err = NULL;
+ args->mergeinfo = NULL;
+ }
+ }
+ return svn_error_return(err);
}
else
{
svn_mergeinfo_t tmp_mergeinfo;
- SVN_ERR(svn_mergeinfo_parse(&tmp_mergeinfo,
- mergeinfo_string->data, trail->pool));
- SVN_ERR(svn_mergeinfo_inheritable(&tmp_mergeinfo,
- tmp_mergeinfo,
- NULL, SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM, trail->pool));
- SVN_ERR(append_to_merged_froms(args->mergeinfo,
- tmp_mergeinfo,
- parent_path_relpath(parent_path,
- nearest_ancestor,
- trail->pool),
- args->pool));
- *(args->inherited) = TRUE;
+ svn_error_t *err = svn_mergeinfo_parse(&tmp_mergeinfo,
+ mergeinfo_string->data,
+ trail->pool);
+
+ /* Issue #3896: If a node inherits syntactically invalid mergeinfo,
+ then treat it as if no mergeinfo is inherited rather than raising
+ a parse error. */
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
+ {
+ svn_error_clear(err);
+ args->mergeinfo = NULL;
+ }
+ else
+ {
+ return svn_error_return(err);
+ }
+ }
+ else
+ {
+ SVN_ERR(svn_mergeinfo_inheritable(&tmp_mergeinfo,
+ tmp_mergeinfo,
+ NULL, SVN_INVALID_REVNUM,
+ SVN_INVALID_REVNUM, trail->pool));
+ SVN_ERR(append_to_merged_froms(args->mergeinfo,
+ tmp_mergeinfo,
+ parent_path_relpath(parent_path,
+ nearest_ancestor,
+ trail->pool),
+ args->pool));
+ *(args->inherited) = TRUE;
+ }
}
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/libsvn_fs_fs/tree.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/tree.c?rev=1130688&r1=1130687&r2=1130688&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/tree.c Thu Jun 2 17:49:36 2011
@@ -3518,10 +3518,11 @@ crawl_directory_dag_for_mergeinfo(svn_fs
if (has_mergeinfo)
{
- /* Save this partisular node's mergeinfo. */
+ /* Save this particular node's mergeinfo. */
apr_hash_t *proplist;
svn_mergeinfo_t kid_mergeinfo;
svn_string_t *mergeinfo_string;
+ svn_error_t *err;
SVN_ERR(svn_fs_fs__dag_get_proplist(&proplist, kid_dag, iterpool));
mergeinfo_string = apr_hash_get(proplist, SVN_PROP_MERGEINFO,
@@ -3535,14 +3536,26 @@ crawl_directory_dag_for_mergeinfo(svn_fs
idstr->data);
}
- SVN_ERR(svn_mergeinfo_parse(&kid_mergeinfo,
- mergeinfo_string->data,
- result_pool));
-
- apr_hash_set(result_catalog,
- apr_pstrdup(result_pool, kid_path),
- APR_HASH_KEY_STRING,
- kid_mergeinfo);
+ /* Issue #3896: If a node has syntactically invalid mergeinfo, then
+ treat it as if no mergeinfo is present rather than raising a parse
+ error. */
+ err = svn_mergeinfo_parse(&kid_mergeinfo,
+ mergeinfo_string->data,
+ result_pool);
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
+ svn_error_clear(err);
+ else
+ svn_error_return(err);
+ }
+ else
+ {
+ apr_hash_set(result_catalog,
+ apr_pstrdup(result_pool, kid_path),
+ APR_HASH_KEY_STRING,
+ kid_mergeinfo);
+ }
}
if (go_down)
@@ -3661,40 +3674,76 @@ get_mergeinfo_for_path(svn_mergeinfo_t *
if (nearest_ancestor == parent_path)
{
+ svn_error_t *err;
+
/* We can return this directly. */
svn_pool_destroy(iterpool);
- return svn_mergeinfo_parse(mergeinfo,
- mergeinfo_string->data,
- result_pool);
+
+ /* Issue #3896: If a node has syntactically invalid mergeinfo, then
+ treat it as if no mergeinfo is present rather than raising a parse
+ error. */
+ err = svn_mergeinfo_parse(mergeinfo,
+ mergeinfo_string->data,
+ result_pool);
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
+ {
+ svn_error_clear(err);
+ err = NULL;
+ *mergeinfo = NULL;
+ }
+ }
+ return svn_error_return(err);
}
else
{
svn_mergeinfo_t temp_mergeinfo;
+ svn_error_t *err;
/* We're inheriting this, so we need to (a) remove
non-inheritable ranges and (b) add the rest of the path to
the merged-from paths.
*/
- SVN_ERR(svn_mergeinfo_parse(&temp_mergeinfo,
- mergeinfo_string->data,
- scratch_pool));
- SVN_ERR(svn_mergeinfo_inheritable(&temp_mergeinfo,
- temp_mergeinfo,
- NULL, SVN_INVALID_REVNUM,
- SVN_INVALID_REVNUM, scratch_pool));
-
- SVN_ERR(append_to_merged_froms(mergeinfo,
- temp_mergeinfo,
- parent_path_relpath(parent_path,
- nearest_ancestor,
- scratch_pool),
- result_pool));
-
- if (validate_inherited_mergeinfo)
- SVN_ERR(svn_fs_fs__validate_mergeinfo(mergeinfo, rev_root->fs,
- *mergeinfo, result_pool,
- iterpool));
+ /* Issue #3896: If a node inherits syntactically invalid mergeinfo,
+ then treat it as if no mergeinfo is inherited rather than raising
+ a parse error. */
+ err = svn_mergeinfo_parse(&temp_mergeinfo,
+ mergeinfo_string->data,
+ scratch_pool);
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
+ {
+ svn_error_clear(err);
+ *mergeinfo = NULL;
+ }
+ else
+ {
+ return svn_error_return(err);
+ }
+ }
+ else
+ {
+ SVN_ERR(svn_mergeinfo_inheritable(&temp_mergeinfo,
+ temp_mergeinfo,
+ NULL, SVN_INVALID_REVNUM,
+ SVN_INVALID_REVNUM,
+ scratch_pool));
+
+ SVN_ERR(append_to_merged_froms(mergeinfo,
+ temp_mergeinfo,
+ parent_path_relpath(parent_path,
+ nearest_ancestor,
+ scratch_pool),
+ result_pool));
+
+ if (validate_inherited_mergeinfo)
+ SVN_ERR(svn_fs_fs__validate_mergeinfo(mergeinfo, rev_root->fs,
+ *mergeinfo, result_pool,
+ iterpool));
+ }
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
@@ -3749,14 +3798,29 @@ get_mergeinfos_for_paths(svn_fs_root_t *
for (i = 0; i < paths->nelts; i++)
{
+ svn_error_t *err;
svn_mergeinfo_t path_mergeinfo;
const char *path = APR_ARRAY_IDX(paths, i, const char *);
svn_pool_clear(iterpool);
- SVN_ERR(get_mergeinfo_for_path(&path_mergeinfo, root, path,
- inherit, validate_inherited_mergeinfo,
- pool, iterpool));
+ err = get_mergeinfo_for_path(&path_mergeinfo, root, path,
+ inherit, validate_inherited_mergeinfo,
+ pool, iterpool);
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
+ {
+ svn_error_clear(err);
+ err = NULL;
+ path_mergeinfo = NULL;
+ }
+ else
+ {
+ svn_error_return(err);
+ }
+ }
+
if (path_mergeinfo)
apr_hash_set(result_catalog, path, APR_HASH_KEY_STRING,
path_mergeinfo);