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 2014/12/14 12:44:04 UTC
svn commit: r1645439 [4/8] - in /subversion/branches/1.7.x-issue4340-repos:
./ build/ac-macros/ build/generator/ build/generator/templates/
contrib/hook-scripts/ subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/ja...
Propchange: subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_subr/svn_temp_serializer.c
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sun Dec 14 11:44:03 2014
@@ -1,4 +1,6 @@
+/subversion/branches/1.7.x/subversion/libsvn_subr/svn_temp_serializer.c:1480943-1645438
/subversion/branches/1.7.x-issue4087/subversion/libsvn_subr/svn_temp_serializer.c:1243707-1336073
+/subversion/branches/1.7.x-issue4153/subversion/libsvn_subr/svn_temp_serializer.c:1309894-1539233
/subversion/branches/1.7.x-issue4169/subversion/libsvn_subr/svn_temp_serializer.c:1330537-1336116
/subversion/branches/1.7.x-r1210147/subversion/libsvn_subr/svn_temp_serializer.c:1213310-1293110
/subversion/branches/1.7.x-r1423646/subversion/libsvn_subr/svn_temp_serializer.c:1423647-1424282
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/adm_ops.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/adm_ops.c Sun Dec 14 11:44:03 2014
@@ -1405,12 +1405,17 @@ revert_restore_handle_copied_dirs(svn_bo
/* Make the working tree under LOCAL_ABSPATH to depth DEPTH match the
versioned tree. This function is called after svn_wc__db_op_revert
has done the database revert and created the revert list. Notifies
- for all paths equal to or below LOCAL_ABSPATH that are reverted. */
+ for all paths equal to or below LOCAL_ABSPATH that are reverted.
+
+ REVERT_ROOT is true for explicit revert targets and FALSE for targets
+ reached via recursion.
+ */
static svn_error_t *
revert_restore(svn_wc__db_t *db,
const char *local_abspath,
svn_depth_t depth,
svn_boolean_t use_commit_times,
+ svn_boolean_t revert_root,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
@@ -1434,10 +1439,31 @@ revert_restore(svn_wc__db_t *db,
#endif
svn_boolean_t copied_here;
svn_wc__db_kind_t reverted_kind;
+ svn_boolean_t is_wcroot;
if (cancel_func)
SVN_ERR(cancel_func(cancel_baton));
+ SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath, scratch_pool));
+ if (is_wcroot && !revert_root)
+ {
+ /* Issue #4162: Obstructing working copy. We can't access the working
+ copy data from the parent working copy for this node by just using
+ local_abspath */
+
+ if (notify_func)
+ {
+ svn_wc_notify_t *notify = svn_wc_create_notify(
+ local_abspath,
+ svn_wc_notify_update_skip_obstruction,
+ scratch_pool);
+
+ notify_func(notify_baton, notify, scratch_pool);
+ }
+
+ return SVN_NO_ERROR; /* We don't revert obstructing working copies */
+ }
+
SVN_ERR(svn_wc__db_revert_list_read(¬ify_required,
&conflict_old, &conflict_new,
&conflict_working, &prop_reject,
@@ -1743,7 +1769,7 @@ revert_restore(svn_wc__db_t *db,
iterpool);
SVN_ERR(revert_restore(db, child_abspath, depth,
- use_commit_times,
+ use_commit_times, FALSE /* revert root */,
cancel_func, cancel_baton,
notify_func, notify_baton,
iterpool));
@@ -1795,7 +1821,7 @@ new_revert_internal(svn_wc__db_t *db,
if (!err)
err = revert_restore(db, local_abspath, depth,
- use_commit_times,
+ use_commit_times, TRUE /* revert root */,
cancel_func, cancel_baton,
notify_func, notify_baton,
scratch_pool);
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/diff_editor.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/diff_editor.c Sun Dec 14 11:44:03 2014
@@ -1281,11 +1281,10 @@ add_directory(const char *path,
dir_pool);
*child_baton = db;
- /* Add this path to the parent directory's list of elements that
- have been compared. */
- apr_hash_set(pb->compared, apr_pstrdup(pb->pool, db->path),
- APR_HASH_KEY_STRING, "");
-
+ /* Issue #3797: Don't add this filename to the parent directory's list of
+ elements that have been compared, to show local additions via the local
+ diff. The repository node is unrelated from the working copy version
+ (similar to not-present in the working copy) */
return SVN_NO_ERROR;
}
@@ -1430,10 +1429,10 @@ add_file(const char *path,
fb = make_file_baton(path, TRUE, pb, file_pool);
*file_baton = fb;
- /* Add this filename to the parent directory's list of elements that
- have been compared. */
- apr_hash_set(pb->compared, apr_pstrdup(pb->pool, path),
- APR_HASH_KEY_STRING, "");
+ /* Issue #3797: Don't add this filename to the parent directory's list of
+ elements that have been compared, to show local additions via the local
+ diff. The repository node is unrelated from the working copy version
+ (similar to not-present in the working copy) */
return SVN_NO_ERROR;
}
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/diff_local.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/diff_local.c Sun Dec 14 11:44:03 2014
@@ -204,11 +204,10 @@ file_diff(struct diff_baton *eb,
the latter two have corresponding pristine info to diff against. */
if (status == svn_wc__db_status_added)
SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL,
- &original_repos_relpath, NULL, NULL,
+ NULL, NULL, NULL,
NULL, db, local_abspath,
scratch_pool, scratch_pool));
-
SVN_ERR(get_empty_file(eb, &empty_file, scratch_pool));
/* When we show a delete, we show a diff of the original pristine against
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/old-and-busted.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/old-and-busted.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/old-and-busted.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/old-and-busted.c Sun Dec 14 11:44:03 2014
@@ -810,11 +810,15 @@ atts_to_entry(svn_wc_entry_t **new_entry
### not used by loggy; no need to set MODIFY_FLAGS */
entry->url = extract_string(atts, ENTRIES_ATTR_URL, pool);
+ if (entry->url)
+ entry->url = svn_uri_canonicalize(entry->url, pool);
/* Set up repository root. Make sure it is a prefix of url.
### not used by loggy; no need to set MODIFY_FLAGS */
entry->repos = extract_string(atts, ENTRIES_ATTR_REPOS, pool);
+ if (entry->repos)
+ entry->repos = svn_uri_canonicalize(entry->repos, pool);
if (entry->url && entry->repos
&& !svn_uri__is_ancestor(entry->repos, entry->url))
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/update_editor.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/update_editor.c Sun Dec 14 11:44:03 2014
@@ -1579,16 +1579,29 @@ check_tree_conflict(svn_wc_conflict_desc
if (reason == svn_wc_conflict_reason_edited
|| reason == svn_wc_conflict_reason_deleted
|| reason == svn_wc_conflict_reason_replaced)
- /* When the node existed before (it was locally deleted, replaced or
- * edited), then 'update' cannot add it "again". So it can only send
- * _action_edit, _delete or _replace. */
- SVN_ERR_ASSERT(action == svn_wc_conflict_action_edit
- || action == svn_wc_conflict_action_delete
- || action == svn_wc_conflict_action_replace);
+ {
+ /* When the node existed before (it was locally deleted, replaced or
+ * edited), then 'update' cannot add it "again". So it can only send
+ * _action_edit, _delete or _replace. */
+ if (action != svn_wc_conflict_action_edit
+ && action != svn_wc_conflict_action_delete
+ && action != svn_wc_conflict_action_replace)
+ return svn_error_createf(SVN_ERR_WC_FOUND_CONFLICT, NULL,
+ _("Unexpected attempt to add a node at path '%s'"),
+ svn_dirent_local_style(local_abspath, scratch_pool));
+ }
else if (reason == svn_wc_conflict_reason_added)
- /* When the node did not exist before (it was locally added), then 'update'
- * cannot want to modify it in any way. It can only send _action_add. */
- SVN_ERR_ASSERT(action == svn_wc_conflict_action_add);
+ {
+ /* When the node did not exist before (it was locally added),
+ * then 'update' cannot want to modify it in any way.
+ * It can only send _action_add. */
+ if (action != svn_wc_conflict_action_add)
+ return svn_error_createf(SVN_ERR_WC_FOUND_CONFLICT, NULL,
+ _("Unexpected attempt to edit, delete, or replace "
+ "a node at path '%s'"),
+ svn_dirent_local_style(local_abspath, scratch_pool));
+
+ }
/* A conflict was detected. Append log commands to the log accumulator
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/wc_db.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/libsvn_wc/wc_db.c Sun Dec 14 11:44:03 2014
@@ -3308,8 +3308,9 @@ get_info_for_copy(apr_int64_t *copyfrom_
svn_wc__db_kind_t *kind,
svn_boolean_t *op_root,
svn_boolean_t *have_work,
- svn_wc__db_wcroot_t *wcroot,
+ svn_wc__db_wcroot_t *src_wcroot,
const char *local_relpath,
+ svn_wc__db_wcroot_t *dst_wcroot,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -3322,7 +3323,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
NULL /* have_base */,
NULL /* have_more_work */,
have_work,
- wcroot, local_relpath, result_pool, scratch_pool));
+ src_wcroot, local_relpath, result_pool, scratch_pool));
if (*status == svn_wc__db_status_excluded)
{
@@ -3339,7 +3340,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
&parent_status,
&parent_kind,
NULL, &parent_have_work,
- wcroot, parent_relpath,
+ src_wcroot, parent_relpath, dst_wcroot,
scratch_pool, scratch_pool));
if (*copyfrom_relpath)
*copyfrom_relpath = svn_relpath_join(*copyfrom_relpath, base_name,
@@ -3352,7 +3353,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
SVN_ERR(scan_addition(NULL, &op_root_relpath,
NULL, NULL, /* repos_* */
copyfrom_relpath, copyfrom_id, copyfrom_rev,
- wcroot, local_relpath,
+ src_wcroot, local_relpath,
scratch_pool, scratch_pool));
if (*copyfrom_relpath)
{
@@ -3368,7 +3369,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
const char *base_del_relpath, *work_del_relpath;
SVN_ERR(scan_deletion(&base_del_relpath, NULL, &work_del_relpath,
- wcroot, local_relpath, scratch_pool,
+ src_wcroot, local_relpath, scratch_pool,
scratch_pool));
if (work_del_relpath)
{
@@ -3381,7 +3382,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
SVN_ERR(scan_addition(NULL, &op_root_relpath,
NULL, NULL, /* repos_* */
copyfrom_relpath, copyfrom_id, copyfrom_rev,
- wcroot, parent_del_relpath,
+ src_wcroot, parent_del_relpath,
scratch_pool, scratch_pool));
*copyfrom_relpath
= svn_relpath_join(*copyfrom_relpath,
@@ -3395,7 +3396,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
copyfrom_id,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
- wcroot, local_relpath,
+ src_wcroot, local_relpath,
result_pool, scratch_pool));
}
else
@@ -3407,6 +3408,24 @@ get_info_for_copy(apr_int64_t *copyfrom_
*copyfrom_rev = revision;
}
+ if (src_wcroot != dst_wcroot && *copyfrom_relpath)
+ {
+ const char *repos_root_url;
+ const char *repos_uuid;
+
+ /* Pass the right repos-id for the destination db. We can't just use
+ the id of the source database, as this value can change after
+ relocation (and perhaps also when we start storing multiple
+ working copies in a single db)! */
+
+ SVN_ERR(fetch_repos_info(&repos_root_url, &repos_uuid,
+ src_wcroot->sdb, *copyfrom_id,
+ scratch_pool));
+
+ SVN_ERR(create_repos_id(copyfrom_id, repos_root_url, repos_uuid,
+ dst_wcroot->sdb, scratch_pool));
+ }
+
return SVN_NO_ERROR;
}
@@ -3455,7 +3474,8 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
SVN_ERR(get_info_for_copy(©from_id, ©from_relpath, ©from_rev,
&status, &kind, &op_root, &have_work, src_wcroot,
- src_relpath, scratch_pool, scratch_pool));
+ src_relpath, dst_wcroot,
+ scratch_pool, scratch_pool));
SVN_ERR(op_depth_for_copy(&dst_op_depth, &dst_np_op_depth, copyfrom_id,
copyfrom_relpath, copyfrom_rev,
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/dav_svn.h?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/dav_svn.h Sun Dec 14 11:44:03 2014
@@ -841,6 +841,12 @@ dav_svn__simple_parse_uri(dav_svn__uri_i
const char *uri,
apr_pool_t *pool);
+/* Test the request R to determine if we should return the list of
+ * repositories at the parent path. Only true if SVNListParentPath directive
+ * is 'on' and the request is for our configured root path. */
+svn_boolean_t
+dav_svn__is_parentpath_list(request_rec *r);
+
int dav_svn__find_ns(const apr_array_header_t *namespaces, const char *uri);
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/mod_dav_svn.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/mod_dav_svn.c Sun Dec 14 11:44:03 2014
@@ -924,7 +924,95 @@ static int dav_svn__handler(request_rec
return DECLINED;
}
+#define NO_MAP_TO_STORAGE_NOTE "dav_svn-no-map-to-storage"
+/* Fill the filename on the request with a bogus path since we aren't serving
+ * a file off the disk. This means that <Directory> blocks will not match and
+ * that %f in logging formats will show as "svn:/path/to/repo/path/in/repo". */
+static int dav_svn__translate_name(request_rec *r)
+{
+ const char *fs_path, *repos_basename, *repos_path, *slash;
+ const char *ignore_cleaned_uri, *ignore_relative_path;
+ int ignore_had_slash;
+ dir_conf_t *conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
+
+ /* module is not configured, bail out early */
+ if (!conf->fs_path && !conf->fs_parent_path)
+ return DECLINED;
+
+ if (dav_svn__is_parentpath_list(r))
+ {
+ /* SVNListParentPath is on and the request is for the conf->root_dir,
+ * so just set the repos_basename to an empty string and the repos_path
+ * to NULL so we end up just reporting our parent path as the bogus
+ * path. */
+ repos_basename = "";
+ repos_path = NULL;
+ }
+ else
+ {
+ /* Retrieve path to repo and within repo for the request */
+ dav_error *err = dav_svn_split_uri(r, r->uri, conf->root_dir,
+ &ignore_cleaned_uri,
+ &ignore_had_slash, &repos_basename,
+ &ignore_relative_path, &repos_path);
+ if (err)
+ {
+ dav_svn__log_err(r, err, APLOG_ERR);
+ return err->status;
+ }
+ }
+
+ if (conf->fs_parent_path)
+ {
+ fs_path = svn_dirent_join(conf->fs_parent_path, repos_basename,
+ r->pool);
+ }
+ else
+ {
+ fs_path = conf->fs_path;
+ }
+
+ /* Avoid a trailing slash on the bogus path when repos_path is just "/" and
+ * ensure that there is always a slash between fs_path and repos_path as
+ * long as the repos_path is not an empty path. */
+ slash = "";
+ if (repos_path)
+ {
+ if ('/' == repos_path[0] && '\0' == repos_path[1])
+ repos_path = NULL;
+ else if ('/' != repos_path[0] && '\0' != repos_path[0])
+ slash = "/";
+ }
+
+ /* Combine 'svn:', fs_path and repos_path to produce the bogus path we're
+ * placing in r->filename. We can't use our standard join helpers such
+ * as svn_dirent_join. fs_path is a dirent and repos_path is a fspath
+ * (that can be trivially converted to a relpath by skipping the leading
+ * slash). In general it is safe to join these, but when a path in a
+ * repository is 'trunk/c:hi' this results in a non canonical dirent on
+ * Windows. Instead we just cat them together. */
+ r->filename = apr_pstrcat(r->pool,
+ "svn:", fs_path, slash, repos_path, NULL);
+
+ /* Leave a note to ourselves so that we know not to decline in the
+ * map_to_storage hook. */
+ apr_table_setn(r->notes, NO_MAP_TO_STORAGE_NOTE, (const char*)1);
+ return OK;
+}
+
+/* Prevent core_map_to_storage from running if we prevented the r->filename
+ * from being set since core_map_to_storage doesn't like r->filename being
+ * bogus. */
+static int dav_svn__map_to_storage(request_rec *r)
+{
+ /* Check a note we left in translate_name since map_to_storage doesn't
+ * have access to our configuration. */
+ if (apr_table_get(r->notes, NO_MAP_TO_STORAGE_NOTE))
+ return OK;
+
+ return DECLINED;
+}
@@ -1071,6 +1159,12 @@ register_hooks(apr_pool_t *pconf)
ap_register_input_filter("IncomingRewrite", dav_svn__location_in_filter,
NULL, AP_FTYPE_CONTENT_SET);
ap_hook_fixups(dav_svn__proxy_request_fixup, NULL, NULL, APR_HOOK_MIDDLE);
+ /* translate_name hook is LAST so that it doesn't interfere with modules
+ * like mod_alias that are MIDDLE. */
+ ap_hook_translate_name(dav_svn__translate_name, NULL, NULL, APR_HOOK_LAST);
+ /* map_to_storage hook is LAST to avoid interferring with mod_http's
+ * handling of OPTIONS and TRACE. */
+ ap_hook_map_to_storage(dav_svn__map_to_storage, NULL, NULL, APR_HOOK_LAST);
}
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/deleted-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/deleted-rev.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/deleted-rev.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/deleted-rev.c Sun Dec 14 11:44:03 2014
@@ -56,6 +56,9 @@ dav_svn__get_deleted_rev_report(const da
dav_error *derr = NULL;
/* Sanity check. */
+ if (!resource->info->repos_path)
+ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+ "The request does not specify a repository path");
ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
if (ns == -1)
return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0,
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/file-revs.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/file-revs.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/file-revs.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/file-revs.c Sun Dec 14 11:44:03 2014
@@ -251,6 +251,9 @@ dav_svn__file_revs_report(const dav_reso
arb.repos = resource->info->repos;
/* Sanity check. */
+ if (!resource->info->repos_path)
+ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+ "The request does not specify a repository path");
ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
/* ### This is done on other places, but the document element is
in this namespace, so is this necessary at all? */
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/get-location-segments.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/get-location-segments.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/get-location-segments.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/get-location-segments.c Sun Dec 14 11:44:03 2014
@@ -123,6 +123,9 @@ dav_svn__get_location_segments_report(co
struct location_segment_baton location_segment_baton;
/* Sanity check. */
+ if (!resource->info->repos_path)
+ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+ "The request does not specify a repository path");
ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
if (ns == -1)
{
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/get-locations.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/get-locations.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/get-locations.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/get-locations.c Sun Dec 14 11:44:03 2014
@@ -106,6 +106,9 @@ dav_svn__get_locations_report(const dav_
sizeof(svn_revnum_t));
/* Sanity check. */
+ if (!resource->info->repos_path)
+ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+ "The request does not specify a repository path");
ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
if (ns == -1)
{
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/log.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/log.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/log.c Sun Dec 14 11:44:03 2014
@@ -307,6 +307,9 @@ dav_svn__log_report(const dav_resource *
= apr_array_make(resource->pool, 1, sizeof(const char *));
/* Sanity check. */
+ if (!resource->info->repos_path)
+ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+ "The request does not specify a repository path");
ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
if (ns == -1)
{
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/mergeinfo.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/mergeinfo.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/reports/mergeinfo.c Sun Dec 14 11:44:03 2014
@@ -67,6 +67,9 @@ dav_svn__get_mergeinfo_report(const dav_
= apr_array_make(resource->pool, 0, sizeof(const char *));
/* Sanity check. */
+ if (!resource->info->repos_path)
+ return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+ "The request does not specify a repository path");
ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
if (ns == -1)
{
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/repos.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/repos.c Sun Dec 14 11:44:03 2014
@@ -506,6 +506,9 @@ parse_vtxnstub_uri(dav_resource_combined
if (parse_txnstub_uri(comb, path, label, use_checked_in))
return TRUE;
+ if (!comb->priv.root.txn_name)
+ return TRUE;
+
comb->priv.root.vtxn_name = comb->priv.root.txn_name;
comb->priv.root.txn_name = dav_svn__get_txn(comb->priv.repos,
comb->priv.root.vtxn_name);
@@ -574,6 +577,9 @@ parse_vtxnroot_uri(dav_resource_combined
if (parse_txnroot_uri(comb, path, label, use_checked_in))
return TRUE;
+ if (!comb->priv.root.txn_name)
+ return TRUE;
+
comb->priv.root.vtxn_name = comb->priv.root.txn_name;
comb->priv.root.txn_name = dav_svn__get_txn(comb->priv.repos,
comb->priv.root.vtxn_name);
@@ -919,6 +925,10 @@ prep_working(dav_resource_combined *comb
point. */
if (txn_name == NULL)
{
+ if (!comb->priv.root.activity_id)
+ return dav_svn__new_error(comb->res.pool, HTTP_BAD_REQUEST, 0,
+ "The request did not specify an activity ID");
+
txn_name = dav_svn__get_txn(comb->priv.repos,
comb->priv.root.activity_id);
if (txn_name == NULL)
@@ -1029,8 +1039,13 @@ prep_working(dav_resource_combined *comb
static dav_error *
prep_activity(dav_resource_combined *comb)
{
- const char *txn_name = dav_svn__get_txn(comb->priv.repos,
- comb->priv.root.activity_id);
+ const char *txn_name;
+
+ if (!comb->priv.root.activity_id)
+ return dav_svn__new_error(comb->res.pool, HTTP_BAD_REQUEST, 0,
+ "The request did not specify an activity ID");
+
+ txn_name = dav_svn__get_txn(comb->priv.repos, comb->priv.root.activity_id);
comb->priv.root.txn_name = txn_name;
comb->res.exists = txn_name != NULL;
@@ -1788,14 +1803,106 @@ do_out_of_date_check(dav_resource_combin
"Could not get created rev of "
"resource", r->pool);
- if (comb->priv.version_name < created_rev)
+ if (SVN_IS_VALID_REVNUM(created_rev))
+ {
+ if (comb->priv.version_name < created_rev)
+ {
+ serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
+ comb->res.collection
+ ? "Directory '%s' is out of date"
+ : (comb->res.exists
+ ? "File '%s' is out of date"
+ : "'%s' is out of date"),
+ comb->priv.repos_path);
+ return dav_svn__convert_err(serr, HTTP_CONFLICT,
+ "Attempting to modify out-of-date resource.",
+ r->pool);
+ }
+ }
+ else if (SVN_IS_VALID_REVNUM(comb->priv.version_name)
+ && comb->res.collection)
{
- serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
- "Item '%s' is out of date",
- comb->priv.repos_path);
- return dav_svn__convert_err(serr, HTTP_CONFLICT,
- "Attempting to modify out-of-date resource.",
- r->pool);
+ /* Issue #4480: With HTTPv2 we can receive the first change for a
+ directory after it has been made mutable, because one of its
+ descendants was changed before changing the directory.
+
+ We have to check if whatever the node is in HEAD is equivalent
+ to what it was in the provided BASE revision.
+
+ If the node was copied, we would process it before its decendants
+ and we already performed quite a few checks when making it mutable
+ via its descendant, so what we should really check here is if the
+ properties changed since the BASE version.
+
+ ### I think svn_fs_node_relation() checks for more changes than we
+ should check for here. Needs further review. But it looks like\
+ this check matches the checks in the libsvn_fs commit editor.
+
+ For now I would say reporting out of date in a few too many
+ cases is safer than not reporting out of date when we should.
+ */
+ svn_revnum_t youngest;
+ svn_fs_root_t *youngest_root;
+ svn_fs_root_t *rev_root;
+ const svn_fs_id_t *youngest_id;
+ const svn_fs_id_t *rev_id;
+
+ serr = svn_fs_youngest_rev(&youngest, comb->res.info->repos->fs,
+ r->pool);
+ if (serr != NULL)
+ {
+ return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+ "Could not determine the youngest "
+ "revision for verification against "
+ "the baseline being checked out",
+ r->pool);
+ }
+
+ if (comb->priv.version_name == youngest)
+ return NULL; /* Easy out: we commit against HEAD */
+
+ serr = svn_fs_revision_root(&youngest_root, comb->res.info->repos->fs,
+ youngest, r->pool);
+
+ if (!serr)
+ serr = svn_fs_node_id(&youngest_id, youngest_root,
+ comb->priv.repos_path, r->pool);
+
+ if (serr != NULL)
+ {
+ return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+ "Could not open youngest revision root "
+ "for verification against the base "
+ "revision", r->pool);
+ }
+
+ serr = svn_fs_revision_root(&rev_root, comb->res.info->repos->fs,
+ comb->priv.version_name, r->pool);
+
+ if (!serr)
+ serr = svn_fs_node_id(&rev_id, rev_root,
+ comb->priv.repos_path, r->pool);
+
+ if (serr != NULL)
+ {
+ return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+ "Could not open the base revision"
+ "for verification against the youngest "
+ "revision", r->pool);
+ }
+
+ svn_fs_close_root(rev_root);
+ svn_fs_close_root(youngest_root);
+
+ if (0 != svn_fs_compare_ids(youngest_id, rev_id))
+ {
+ serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
+ "Directory '%s' is out of date",
+ comb->priv.repos_path);
+ return dav_svn__convert_err(serr, HTTP_CONFLICT,
+ "Attempting to modify out-of-date resource.",
+ r->pool);
+ }
}
return NULL;
@@ -1957,26 +2064,31 @@ get_resource(request_rec *r,
/* Special case: detect and build the SVNParentPath as a unique type
of private resource, iff the SVNListParentPath directive is 'on'. */
- if (fs_parent_path && dav_svn__get_list_parentpath_flag(r))
+ if (dav_svn__is_parentpath_list(r))
{
- char *uri = apr_pstrdup(r->pool, r->uri);
- char *parentpath = apr_pstrdup(r->pool, root_path);
- apr_size_t uri_len = strlen(uri);
- apr_size_t parentpath_len = strlen(parentpath);
-
- if (uri[uri_len-1] == '/')
- uri[uri_len-1] = '\0';
+ /* Only allow GET and HEAD on the parentpath resource
+ * httpd uses the same method_number for HEAD as GET */
+ if (r->method_number != M_GET)
+ {
+ int status;
- if (parentpath[parentpath_len-1] == '/')
- parentpath[parentpath_len-1] = '\0';
+ /* Marshall the error back to the client by generating by
+ * way of the dav_svn__error_response_tag trick. */
+ err = dav_svn__new_error(r->pool, HTTP_METHOD_NOT_ALLOWED,
+ SVN_ERR_APMOD_MALFORMED_URI,
+ "The URI does not contain the name "
+ "of a repository.");
+ /* can't use r->allowed since the default handler isn't called */
+ apr_table_setn(r->headers_out, "Allow", "GET,HEAD");
+ status = dav_svn__error_response_tag(r, err);
- if (strcmp(parentpath, uri) == 0)
- {
- err = get_parentpath_resource(r, resource);
- if (err)
- return err;
- return NULL;
+ return dav_push_error(r->pool, status, err->error_id, NULL, err);
}
+
+ err = get_parentpath_resource(r, resource);
+ if (err)
+ return err;
+ return NULL;
}
/* This does all the work of interpreting/splitting the request uri. */
@@ -2390,21 +2502,12 @@ get_parent_path(const char *path,
svn_boolean_t is_urlpath,
apr_pool_t *pool)
{
- apr_size_t len;
- char *tmp = apr_pstrdup(pool, path);
-
- len = strlen(tmp);
-
- if (len > 0)
+ if (*path != '\0') /* not an empty string */
{
- /* Remove any trailing slash; else svn_path_dirname() asserts. */
- if (tmp[len-1] == '/')
- tmp[len-1] = '\0';
-
if (is_urlpath)
- return svn_urlpath__dirname(tmp, pool);
+ return svn_urlpath__dirname(path, pool);
else
- return svn_fspath__dirname(tmp, pool);
+ return svn_fspath__dirname(path, pool);
}
return path;
@@ -2440,13 +2543,18 @@ get_parent_resource(const dav_resource *
parent->versioned = 1;
parent->hooks = resource->hooks;
parent->pool = resource->pool;
- parent->uri = get_parent_path(resource->uri, TRUE, resource->pool);
+ parent->uri = get_parent_path(svn_urlpath__canonicalize(resource->uri,
+ resource->pool),
+ TRUE, resource->pool);
parent->info = parentinfo;
parentinfo->uri_path =
- svn_stringbuf_create(get_parent_path(resource->info->uri_path->data,
- TRUE, resource->pool),
- resource->pool);
+ svn_stringbuf_create(
+ get_parent_path(
+ svn_urlpath__canonicalize(resource->info->uri_path->data,
+ resource->pool),
+ TRUE, resource->pool),
+ resource->pool);
parentinfo->repos = resource->info->repos;
parentinfo->root = resource->info->root;
parentinfo->r = resource->info->r;
@@ -4085,7 +4193,9 @@ typedef struct walker_ctx_t {
static dav_error *
-do_walk(walker_ctx_t *ctx, int depth)
+do_walk(walker_ctx_t *ctx,
+ int depth,
+ apr_pool_t *scratch_pool)
{
const dav_walk_params *params = ctx->params;
int isdir = ctx->res.collection;
@@ -4158,19 +4268,19 @@ do_walk(walker_ctx_t *ctx, int depth)
svn_log__get_dir(ctx->info.repos_path,
ctx->info.root.rev,
TRUE, FALSE, SVN_DIRENT_ALL,
- params->pool));
+ scratch_pool));
/* fetch this collection's children */
serr = svn_fs_dir_entries(&children, ctx->info.root.root,
- ctx->info.repos_path, params->pool);
+ ctx->info.repos_path, scratch_pool);
if (serr != NULL)
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"could not fetch collection members",
params->pool);
/* iterate over the children in this collection */
- iterpool = svn_pool_create(params->pool);
- for (hi = apr_hash_first(params->pool, children); hi; hi = apr_hash_next(hi))
+ iterpool = svn_pool_create(scratch_pool);
+ for (hi = apr_hash_first(scratch_pool, children); hi; hi = apr_hash_next(hi))
{
const void *key;
apr_ssize_t klen;
@@ -4223,7 +4333,7 @@ do_walk(walker_ctx_t *ctx, int depth)
ctx->res.uri = ctx->uri->data;
/* recurse on this collection */
- err = do_walk(ctx, depth - 1);
+ err = do_walk(ctx, depth - 1, iterpool);
if (err != NULL)
return err;
@@ -4305,7 +4415,7 @@ walk(const dav_walk_params *params, int
/* ### is the root already/always open? need to verify */
/* always return the error, and any/all multistatus responses */
- err = do_walk(&ctx, depth);
+ err = do_walk(&ctx, depth, params->pool);
*response = ctx.wres.response;
return err;
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/util.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/util.c Sun Dec 14 11:44:03 2014
@@ -412,6 +412,32 @@ dav_svn__simple_parse_uri(dav_svn__uri_i
"Unsupported URI form");
}
+svn_boolean_t
+dav_svn__is_parentpath_list(request_rec *r)
+{
+ const char *fs_parent_path = dav_svn__get_fs_parent_path(r);
+
+ if (fs_parent_path && dav_svn__get_list_parentpath_flag(r))
+ {
+ const char *root_path = dav_svn__get_root_dir(r);
+ char *uri = apr_pstrdup(r->pool, r->uri);
+ char *parentpath = apr_pstrdup(r->pool, root_path);
+ apr_size_t uri_len = strlen(uri);
+ apr_size_t parentpath_len = strlen(parentpath);
+
+ if (uri[uri_len-1] == '/')
+ uri[uri_len-1] = '\0';
+
+ if (parentpath[parentpath_len-1] == '/')
+ parentpath[parentpath_len-1] = '\0';
+
+ if (strcmp(parentpath, uri) == 0)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
/* ### move this into apr_xml */
int
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/version.c?rev=1645439&r1=1645438&r2=1645439&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/mod_dav_svn/version.c Sun Dec 14 11:44:03 2014
@@ -953,8 +953,11 @@ dav_svn__checkin(dav_resource *resource,
if (serr)
{
+ int status;
+
if (serr->apr_err == SVN_ERR_FS_CONFLICT)
{
+ status = HTTP_CONFLICT;
msg = apr_psprintf(resource->pool,
"A conflict occurred during the CHECKIN "
"processing. The problem occurred with "
@@ -962,10 +965,12 @@ dav_svn__checkin(dav_resource *resource,
conflict_msg);
}
else
- msg = "An error occurred while committing the transaction.";
+ {
+ status = HTTP_INTERNAL_SERVER_ERROR;
+ msg = "An error occurred while committing the transaction.";
+ }
- return dav_svn__convert_err(serr, HTTP_CONFLICT, msg,
- resource->pool);
+ return dav_svn__convert_err(serr, status, msg, resource->pool);
}
else
{
@@ -1455,8 +1460,11 @@ merge(dav_resource *target,
if (serr)
{
const char *msg;
+ int status;
+
if (serr->apr_err == SVN_ERR_FS_CONFLICT)
{
+ status = HTTP_CONFLICT;
/* ### we need to convert the conflict path into a URI */
msg = apr_psprintf(pool,
"A conflict occurred during the MERGE "
@@ -1465,9 +1473,12 @@ merge(dav_resource *target,
conflict);
}
else
- msg = "An error occurred while committing the transaction.";
+ {
+ status = HTTP_INTERNAL_SERVER_ERROR;
+ msg = "An error occurred while committing the transaction.";
+ }
- return dav_svn__convert_err(serr, HTTP_CONFLICT, msg, pool);
+ return dav_svn__convert_err(serr, status, msg, pool);
}
else
{