You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2015/07/28 13:18:39 UTC
svn commit: r1693068 [2/2] - in /subversion/branches/1.7.x-issue4340-repos:
./ build/ build/ac-macros/ build/generator/ build/generator/templates/
subversion/bindings/swig/include/ subversion/include/
subversion/libsvn_client/ subversion/libsvn_fs_fs/ ...
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/svnrdump/load_editor.c?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/svnrdump/load_editor.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/svnrdump/load_editor.c Tue Jul 28 11:18:37 2015
@@ -41,6 +41,8 @@
#define SVNRDUMP_PROP_LOCK SVN_PROP_PREFIX "rdump-lock"
+#define ARE_VALID_COPY_ARGS(p,r) ((p) && SVN_IS_VALID_REVNUM(r))
+
#if 0
#define LDR_DBG(x) SVN_DBG(x)
#else
@@ -102,6 +104,15 @@ struct directory_baton
void *baton;
const char *relpath;
int depth;
+
+ /* The copy-from source of this directory, no matter whether it is
+ copied explicitly (the root node of a copy) or implicitly (being an
+ existing child of a copied directory). For a node that is newly
+ added (without history), even inside a copied parent, these are
+ NULL and SVN_INVALID_REVNUM. */
+ const char *copyfrom_path;
+ svn_revnum_t copyfrom_rev;
+
struct directory_baton *parent;
};
@@ -115,12 +126,20 @@ struct node_baton
svn_node_kind_t kind;
enum svn_node_action action;
+ /* Is this directory explicitly added? If not, then it already existed
+ or is a child of a copy. */
+ svn_boolean_t is_added;
+
svn_revnum_t copyfrom_rev;
const char *copyfrom_path;
+ const char *copyfrom_url;
void *file_baton;
const char *base_checksum;
+ /* (const char *name) -> (svn_prop_t *) */
+ apr_hash_t *prop_changes;
+
struct revision_baton *rb;
};
@@ -436,6 +455,7 @@ new_revision_record(void **revision_bato
pb = parse_baton;
rb->pool = svn_pool_create(pool);
rb->pb = pb;
+ rb->db = NULL;
for (hi = apr_hash_first(pool, headers); hi; hi = apr_hash_next(hi))
{
@@ -479,6 +499,47 @@ uuid_record(const char *uuid,
return SVN_NO_ERROR;
}
+/* Push information about another directory onto the linked list RB->db.
+ *
+ * CHILD_BATON is the baton returned by the commit editor. RELPATH is the
+ * repository-relative path of this directory. IS_ADDED is true iff this
+ * directory is being added (with or without history). If added with
+ * history then COPYFROM_PATH/COPYFROM_REV are the copyfrom source, else
+ * are NULL/SVN_INVALID_REVNUM.
+ */
+static void
+push_directory(struct revision_baton *rb,
+ void *child_baton,
+ const char *relpath,
+ svn_boolean_t is_added,
+ const char *copyfrom_path,
+ svn_revnum_t copyfrom_rev)
+{
+ struct directory_baton *child_db = apr_pcalloc(rb->pool, sizeof (*child_db));
+
+ SVN_ERR_ASSERT_NO_RETURN(
+ is_added || (copyfrom_path == NULL && copyfrom_rev == SVN_INVALID_REVNUM));
+
+ /* If this node is an existing (not newly added) child of a copied node,
+ calculate where it was copied from. */
+ if (!is_added
+ && ARE_VALID_COPY_ARGS(rb->db->copyfrom_path, rb->db->copyfrom_rev))
+ {
+ const char *name = svn_relpath_basename(relpath, NULL);
+
+ copyfrom_path = svn_relpath_join(rb->db->copyfrom_path, name,
+ rb->pool);
+ copyfrom_rev = rb->db->copyfrom_rev;
+ }
+
+ child_db->baton = child_baton;
+ child_db->relpath = relpath;
+ child_db->copyfrom_path = copyfrom_path;
+ child_db->copyfrom_rev = copyfrom_rev;
+ child_db->parent = rb->db;
+ rb->db = child_db;
+}
+
static svn_error_t *
new_node_record(void **node_baton,
apr_hash_t *headers,
@@ -489,17 +550,17 @@ new_node_record(void **node_baton,
const struct svn_delta_editor_t *commit_editor = rb->pb->commit_editor;
void *commit_edit_baton = rb->pb->commit_edit_baton;
struct node_baton *nb;
- struct directory_baton *child_db;
apr_hash_index_t *hi;
void *child_baton;
- char *relpath_compose;
const char *nb_dirname;
nb = apr_pcalloc(rb->pool, sizeof(*nb));
nb->rb = rb;
-
+ nb->is_added = FALSE;
nb->copyfrom_path = NULL;
+ nb->copyfrom_url = NULL;
nb->copyfrom_rev = SVN_INVALID_REVNUM;
+ nb->prop_changes = apr_hash_make(rb->pool);
/* If the creation of commit_editor is pending, create it now and
open_root on it; also create a top-level directory baton. */
@@ -532,13 +593,9 @@ new_node_record(void **node_baton,
LDR_DBG(("Opened root %p\n", child_baton));
- /* child_db corresponds to the root directory baton here */
- child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
- child_db->baton = child_baton;
- child_db->depth = 0;
- child_db->relpath = "";
- child_db->parent = NULL;
- rb->db = child_db;
+ /* child_baton corresponds to the root directory baton here */
+ push_directory(rb, child_baton, "", TRUE /*is_added*/,
+ NULL, SVN_INVALID_REVNUM);
}
for (hi = apr_hash_first(rb->pool, headers); hi; hi = apr_hash_next(hi))
@@ -607,7 +664,7 @@ new_node_record(void **node_baton,
for (i = 0; i < residual_open_path->nelts; i ++)
{
- relpath_compose =
+ char *relpath_compose =
svn_relpath_join(rb->db->relpath,
APR_ARRAY_IDX(residual_open_path, i, const char *),
rb->pool);
@@ -616,12 +673,8 @@ new_node_record(void **node_baton,
rb->rev - rb->rev_offset - 1,
rb->pool, &child_baton));
LDR_DBG(("Opened dir %p\n", child_baton));
- child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
- child_db->baton = child_baton;
- child_db->depth = rb->db->depth + 1;
- child_db->relpath = relpath_compose;
- child_db->parent = rb->db;
- rb->db = child_db;
+ push_directory(rb, child_baton, relpath_compose, TRUE /*is_added*/,
+ NULL, SVN_INVALID_REVNUM);
}
}
@@ -649,7 +702,7 @@ new_node_record(void **node_baton,
if (rb->pb->parent_dir)
nb->copyfrom_path = svn_relpath_join(rb->pb->parent_dir,
nb->copyfrom_path, rb->pool);
- nb->copyfrom_path = svn_path_url_add_component2(rb->pb->root_url,
+ nb->copyfrom_url = svn_path_url_add_component2(rb->pb->root_url,
nb->copyfrom_path,
rb->pool);
}
@@ -667,11 +720,12 @@ new_node_record(void **node_baton,
else
/* FALL THROUGH */;
case svn_node_action_add:
+ nb->is_added = TRUE;
switch (nb->kind)
{
case svn_node_file:
SVN_ERR(commit_editor->add_file(nb->path, rb->db->baton,
- nb->copyfrom_path,
+ nb->copyfrom_url,
nb->copyfrom_rev,
rb->pool, &(nb->file_baton)));
LDR_DBG(("Added file %s to dir %p as %p\n",
@@ -679,17 +733,13 @@ new_node_record(void **node_baton,
break;
case svn_node_dir:
SVN_ERR(commit_editor->add_directory(nb->path, rb->db->baton,
- nb->copyfrom_path,
+ nb->copyfrom_url,
nb->copyfrom_rev,
rb->pool, &child_baton));
LDR_DBG(("Added dir %s to dir %p as %p\n",
nb->path, rb->db->baton, child_baton));
- child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
- child_db->baton = child_baton;
- child_db->depth = rb->db->depth + 1;
- child_db->relpath = apr_pstrdup(rb->pool, nb->path);
- child_db->parent = rb->db;
- rb->db = child_db;
+ push_directory(rb, child_baton, nb->path, TRUE /*is_added*/,
+ nb->copyfrom_path, nb->copyfrom_rev);
break;
default:
break;
@@ -707,12 +757,8 @@ new_node_record(void **node_baton,
SVN_ERR(commit_editor->open_directory(nb->path, rb->db->baton,
rb->rev - rb->rev_offset - 1,
rb->pool, &child_baton));
- child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
- child_db->baton = child_baton;
- child_db->depth = rb->db->depth + 1;
- child_db->relpath = apr_pstrdup(rb->pool, nb->path);
- child_db->parent = rb->db;
- rb->db = child_db;
+ push_directory(rb, child_baton, nb->path, FALSE /*is_added*/,
+ NULL, SVN_INVALID_REVNUM);
break;
}
break;
@@ -763,8 +809,8 @@ set_node_property(void *baton,
const svn_string_t *value)
{
struct node_baton *nb = baton;
- const struct svn_delta_editor_t *commit_editor = nb->rb->pb->commit_editor;
apr_pool_t *pool = nb->rb->pool;
+ svn_prop_t *prop;
if (value && strcmp(name, SVN_PROP_MERGEINFO) == 0)
{
@@ -814,21 +860,11 @@ set_node_property(void *baton,
SVN_ERR(svn_repos__validate_prop(name, value, pool));
- switch (nb->kind)
- {
- case svn_node_file:
- LDR_DBG(("Applying properties on %p\n", nb->file_baton));
- SVN_ERR(commit_editor->change_file_prop(nb->file_baton, name,
- value, pool));
- break;
- case svn_node_dir:
- LDR_DBG(("Applying properties on %p\n", nb->rb->db->baton));
- SVN_ERR(commit_editor->change_dir_prop(nb->rb->db->baton, name,
- value, pool));
- break;
- default:
- break;
- }
+ prop = apr_palloc(nb->rb->pool, sizeof (*prop));
+ prop->name = apr_pstrdup(pool, name);
+ prop->value = value ? svn_string_dup(value, pool) : NULL;
+ apr_hash_set(nb->prop_changes, prop->name, APR_HASH_KEY_STRING, prop);
+
return SVN_NO_ERROR;
}
@@ -837,44 +873,84 @@ delete_node_property(void *baton,
const char *name)
{
struct node_baton *nb = baton;
- const struct svn_delta_editor_t *commit_editor = nb->rb->pb->commit_editor;
apr_pool_t *pool = nb->rb->pool;
+ svn_prop_t *prop;
SVN_ERR(svn_repos__validate_prop(name, NULL, pool));
- if (nb->kind == svn_node_file)
- SVN_ERR(commit_editor->change_file_prop(nb->file_baton, name,
- NULL, pool));
- else
- SVN_ERR(commit_editor->change_dir_prop(nb->rb->db->baton, name,
- NULL, pool));
+ prop = apr_palloc(pool, sizeof (*prop));
+ prop->name = apr_pstrdup(pool, name);
+ prop->value = NULL;
+ apr_hash_set(nb->prop_changes, prop->name, APR_HASH_KEY_STRING, prop);
return SVN_NO_ERROR;
}
+/* Delete all the properties of the node, if any.
+ *
+ * The commit editor doesn't have a method to delete a node's properties
+ * without knowing what they are, so we have to first find out what
+ * properties the node would have had. If it's copied (explicitly or
+ * implicitly), we look at the copy source. If it's only being changed,
+ * we look at the node's current path in the head revision.
+ */
static svn_error_t *
remove_node_props(void *baton)
{
struct node_baton *nb = baton;
+ struct revision_baton *rb = nb->rb;
apr_pool_t *pool = nb->rb->pool;
apr_hash_index_t *hi;
apr_hash_t *props;
+ const char *orig_path;
+ svn_revnum_t orig_rev;
+
+ /* Find the path and revision that has the node's original properties */
+ if (ARE_VALID_COPY_ARGS(nb->copyfrom_path, nb->copyfrom_rev))
+ {
+ LDR_DBG(("using nb->copyfrom %s@%ld", nb->copyfrom_path, nb->copyfrom_rev));
+ orig_path = nb->copyfrom_path;
+ orig_rev = nb->copyfrom_rev;
+ }
+ else if (!nb->is_added
+ && ARE_VALID_COPY_ARGS(rb->db->copyfrom_path, rb->db->copyfrom_rev))
+ {
+ /* If this is a dir, then it's described by rb->db;
+ if this is a file, then it's a child of the dir in rb->db. */
+ LDR_DBG(("using rb->db->copyfrom (k=%d) %s@%ld",
+ nb->kind, rb->db->copyfrom_path, rb->db->copyfrom_rev));
+ orig_path = (nb->kind == svn_node_dir)
+ ? rb->db->copyfrom_path
+ : svn_relpath_join(rb->db->copyfrom_path,
+ svn_relpath_basename(nb->path, NULL),
+ rb->pool);
+ orig_rev = rb->db->copyfrom_rev;
+ }
+ else
+ {
+ LDR_DBG(("using self.path@head %s@%ld", nb->path, SVN_INVALID_REVNUM));
+ /* ### Should we query at a known, fixed, "head" revision number
+ instead of passing SVN_INVALID_REVNUM and getting a moving target? */
+ orig_path = nb->path;
+ orig_rev = SVN_INVALID_REVNUM;
+ }
+ LDR_DBG(("Trying %s@%ld", orig_path, orig_rev));
if ((nb->action == svn_node_action_add
|| nb->action == svn_node_action_replace)
- && ! SVN_IS_VALID_REVNUM(nb->copyfrom_rev))
+ && ! ARE_VALID_COPY_ARGS(orig_path, orig_rev))
/* Add-without-history; no "old" properties to worry about. */
return SVN_NO_ERROR;
if (nb->kind == svn_node_file)
{
- SVN_ERR(svn_ra_get_file(nb->rb->pb->aux_session, nb->path,
- SVN_INVALID_REVNUM, NULL, NULL, &props, pool));
+ SVN_ERR(svn_ra_get_file(nb->rb->pb->aux_session,
+ orig_path, orig_rev, NULL, NULL, &props, pool));
}
else /* nb->kind == svn_node_dir */
{
SVN_ERR(svn_ra_get_dir2(nb->rb->pb->aux_session, NULL, NULL, &props,
- nb->path, SVN_INVALID_REVNUM, 0, pool));
+ orig_path, orig_rev, 0, pool));
}
for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
@@ -928,6 +1004,29 @@ close_node(void *baton)
{
struct node_baton *nb = baton;
const struct svn_delta_editor_t *commit_editor = nb->rb->pb->commit_editor;
+ apr_pool_t *pool = nb->rb->pool;
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first(pool, nb->prop_changes);
+ hi; hi = apr_hash_next(hi))
+ {
+ const char *name = svn__apr_hash_index_key(hi);
+ svn_prop_t *prop = svn__apr_hash_index_val(hi);
+
+ switch (nb->kind)
+ {
+ case svn_node_file:
+ SVN_ERR(commit_editor->change_file_prop(nb->file_baton,
+ name, prop->value, pool));
+ break;
+ case svn_node_dir:
+ SVN_ERR(commit_editor->change_dir_prop(nb->rb->db->baton,
+ name, prop->value, pool));
+ break;
+ default:
+ break;
+ }
+ }
/* Pass a file node closure through to the editor *unless* we
deleted the file (which doesn't require us to open it). */
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/svnserve/serve.c?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/svnserve/serve.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/svnserve/serve.c Tue Jul 28 11:18:37 2015
@@ -2266,9 +2266,30 @@ static svn_error_t *get_location_segment
abs_path = svn_fspath__join(b->fs_path->data, relative_path, pool);
- if (SVN_IS_VALID_REVNUM(start_rev)
- && SVN_IS_VALID_REVNUM(end_rev)
- && (end_rev > start_rev))
+ SVN_ERR(trivial_auth_request(conn, pool, b));
+ SVN_ERR(log_command(baton, conn, pool, "%s",
+ svn_log__get_location_segments(abs_path, peg_revision,
+ start_rev, end_rev,
+ pool)));
+
+ /* No START_REV or PEG_REVISION? We'll use HEAD. */
+ if (!SVN_IS_VALID_REVNUM(start_rev) || !SVN_IS_VALID_REVNUM(peg_revision))
+ {
+ svn_revnum_t youngest;
+
+ SVN_CMD_ERR(svn_fs_youngest_rev(&youngest, b->fs, pool));
+
+ if (!SVN_IS_VALID_REVNUM(start_rev))
+ start_rev = youngest;
+ if (!SVN_IS_VALID_REVNUM(peg_revision))
+ peg_revision = youngest;
+ }
+
+ /* No END_REV? We'll use 0. */
+ if (!SVN_IS_VALID_REVNUM(end_rev))
+ end_rev = 0;
+
+ if (end_rev > start_rev)
{
err = svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
"Get-location-segments end revision must not be "
@@ -2276,9 +2297,7 @@ static svn_error_t *get_location_segment
return log_fail_and_flush(err, b, conn, pool);
}
- if (SVN_IS_VALID_REVNUM(peg_revision)
- && SVN_IS_VALID_REVNUM(start_rev)
- && (start_rev > peg_revision))
+ if (start_rev > peg_revision)
{
err = svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
"Get-location-segments start revision must not "
@@ -2286,12 +2305,6 @@ static svn_error_t *get_location_segment
return log_fail_and_flush(err, b, conn, pool);
}
- SVN_ERR(trivial_auth_request(conn, pool, b));
- SVN_ERR(log_command(baton, conn, pool, "%s",
- svn_log__get_location_segments(abs_path, peg_revision,
- start_rev, end_rev,
- pool)));
-
/* All the parameters are fine - let's perform the query against the
* repository. */
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/README
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/README?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/README (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/README Tue Jul 28 11:18:37 2015
@@ -83,6 +83,133 @@ paths adjusted appropriately:
Require valid-user
</Location>
+ <Location /authz-test-work/anon>
+ DAV svn
+ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp
+ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz
+ SVNListParentPath On
+ # This may seem unnecessary but granting access to everyone here is necessary
+ # to exercise a bug with httpd 2.3.x+. The "Require all granted" syntax is
+ # new to 2.3.x+ which we can detect with the mod_authz_core.c module
+ # signature. Use the "Allow from all" syntax with older versions for symmetry.
+ <IfModule mod_authz_core.c>
+ Require all granted
+ </IfModule>
+ <IfModule !mod_authz_core.c>
+ Allow from all
+ </IfMOdule>
+ </Location>
+ <Location /authz-test-work/mixed>
+ DAV svn
+ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp
+ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile /usr/local/apache2/conf/users
+ Require valid-user
+ Satisfy Any
+ </Location>
+ <Location /authz-test-work/mixed-noauthwhenanon>
+ DAV svn
+ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp
+ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile /usr/local/apache2/conf/users
+ Require valid-user
+ AuthzSVNNoAuthWhenAnonymousAllowed On
+ </Location>
+ <Location /authz-test-work/authn>
+ DAV svn
+ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp
+ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile /usr/local/apache2/conf/users
+ Require valid-user
+ </Location>
+ <Location /authz-test-work/authn-anonoff>
+ DAV svn
+ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp
+ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile /usr/local/apache2/conf/users
+ Require valid-user
+ AuthzSVNAnonymous Off
+ </Location>
+ <Location /authz-test-work/authn-lcuser>
+ DAV svn
+ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp
+ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile /usr/local/apache2/conf/users
+ Require valid-user
+ AuthzForceUsernameCase Lower
+ </Location>
+ <Location /authz-test-work/authn-lcuser>
+ DAV svn
+ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp
+ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile /usr/local/apache2/conf/users
+ Require valid-user
+ AuthzForceUsernameCase Lower
+ </Location>
+ <Location /authz-test-work/authn-group>
+ DAV svn
+ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp
+ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile /usr/local/apache2/conf/users
+ AuthGroupFile /usr/local/apache2/conf/groups
+ Require group random
+ AuthzSVNAuthoritative Off
+ </Location>
+ <IfModule mod_authz_core.c>
+ <Location /authz-test-work/sallrany>
+ DAV svn
+ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp
+ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile /usr/local/apache2/conf/users
+ AuthzSendForbiddenOnFailure On
+ Satisfy All
+ <RequireAny>
+ Require valid-user
+ Require expr req('ALLOW') == '1'
+ </RequireAny>
+ </Location>
+ <Location /authz-test-work/sallrall>
+ DAV svn
+ SVNParentPath /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/local_tmp
+ AuthzSVNAccessFile /home/yourusernamehere/projects/svn/subversion/tests/cmdline/svn-test-work/authz
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile /usr/local/apache2/conf/users
+ AuthzSendForbiddenOnFailure On
+ Satisfy All
+ <RequireAll>
+ Require valid-user
+ Require expr req('ALLOW') == '1'
+ </RequireAll>
+ </Location>
+ </IfModule>
+
+
RedirectMatch permanent ^/svn-test-work/repositories/REDIRECT-PERM-(.*)$ /svn-test-work/repositories/$1
RedirectMatch ^/svn-test-work/repositories/REDIRECT-TEMP-(.*)$ /svn-test-work/repositories/$1
@@ -101,6 +228,15 @@ just drop the following 2-line snippet i
----------------------------
jrandom:xCGl35kV9oWCY
jconstant:xCGl35kV9oWCY
+JRANDOM:xCGl35kV9oWCY
+JCONSTANT:xCGl35kV9oWCY
+----------------------------
+
+and these lines into the
+/usr/local/apache/conf/groups file:
+----------------------------
+random: jrandom
+constant: jconstant
----------------------------
Now, (re)start Apache and run the tests over mod_dav_svn.
@@ -138,6 +274,8 @@ Note [1]: It would be quite too much to
----------------------------
jrandom:$apr1$3p1.....$FQW6RceW5QhJ2blWDQgKn0
jconstant:$apr1$jp1.....$Usrqji1c9H6AbOxOGAzzb0
+ JRANDOM:$apr1$3p1.....$FQW6RceW5QhJ2blWDQgKn0
+ JCONSTANT:$apr1$jp1.....$Usrqji1c9H6AbOxOGAzzb0
----------------------------
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/authz_tests.py?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/authz_tests.py Tue Jul 28 11:18:37 2015
@@ -608,8 +608,10 @@ def authz_log_and_tracing_test(sbox):
## cat
+ expected_err2 = ".*svn: E195012: Unable to find repository location.*"
+
# now see if we can look at the older version of rho
- svntest.actions.run_and_verify_svn(None, None, expected_err,
+ svntest.actions.run_and_verify_svn(None, None, expected_err2,
'cat', '-r', '2', D_url+'/rho')
if sbox.repo_url.startswith('http'):
@@ -626,10 +628,11 @@ def authz_log_and_tracing_test(sbox):
svntest.actions.run_and_verify_svn(None, None, expected_err,
'diff', '-r', 'HEAD', G_url+'/rho')
- svntest.actions.run_and_verify_svn(None, None, expected_err,
+ # diff treats the unreadable path as indicating an add so no error
+ svntest.actions.run_and_verify_svn(None, None, [],
'diff', '-r', '2', D_url+'/rho')
- svntest.actions.run_and_verify_svn(None, None, expected_err,
+ svntest.actions.run_and_verify_svn(None, None, [],
'diff', '-r', '2:4', D_url+'/rho')
# test whether read access is correctly granted and denied
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/copy_tests.py?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/copy_tests.py Tue Jul 28 11:18:37 2015
@@ -5476,6 +5476,18 @@ def copy_deleted_dir(sbox):
'cp', sbox.ospath('A/D'),
sbox.ospath('new_D'))
+def resurrect_at_root(sbox):
+ "resurrect directory at root"
+ sbox.build(create_wc=False)
+
+ svntest.actions.run_and_verify_svn(None, None, [], 'rm',
+ sbox.repo_url + '/A',
+ '-m', '')
+
+ svntest.actions.run_and_verify_svn(None, None, [], 'cp',
+ sbox.repo_url + '/A/D/H@1',
+ sbox.repo_url + '/A', '-m', '')
+
########################################################################
# Run the tests
@@ -5586,6 +5598,7 @@ test_list = [ None,
case_only_rename,
copy_and_move_conflicts,
copy_deleted_dir,
+ resurrect_at_root,
]
if __name__ == '__main__':
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/davautocheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/davautocheck.sh?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/davautocheck.sh (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/davautocheck.sh Tue Jul 28 11:18:37 2015
@@ -248,8 +248,6 @@ LOAD_MOD_AUTHN_CORE="$(get_loadmodule_co
|| fail "Authn_Core module not found."
LOAD_MOD_AUTHZ_CORE="$(get_loadmodule_config mod_authz_core)" \
|| fail "Authz_Core module not found."
-LOAD_MOD_AUTHZ_HOST="$(get_loadmodule_config mod_authz_host)" \
- || fail "Authz_Host module not found."
LOAD_MOD_UNIXD=$(get_loadmodule_config mod_unixd) \
|| fail "UnixD module not found"
}
@@ -257,6 +255,10 @@ LOAD_MOD_AUTHN_FILE="$(get_loadmodule_co
|| fail "Authn_File module not found."
LOAD_MOD_AUTHZ_USER="$(get_loadmodule_config mod_authz_user)" \
|| fail "Authz_User module not found."
+LOAD_MOD_AUTHZ_GROUPFILE="$(get_loadmodule_config mod_authz_groupfile)" \
+ || fail "Authz_GroupFile module not found."
+LOAD_MOD_AUTHZ_HOST="$(get_loadmodule_config mod_authz_host)" \
+ || fail "Authz_Host module not found."
}
if [ ${APACHE_MPM:+set} ]; then
LOAD_MOD_MPM=$(get_loadmodule_config mod_mpm_$APACHE_MPM) \
@@ -272,6 +274,7 @@ HTTPD_ERROR_LOG="$HTTPD_ROOT/error_log"
HTTPD_MIME_TYPES="$HTTPD_ROOT/mime.types"
BASE_URL="http://localhost:$HTTPD_PORT"
HTTPD_USERS="$HTTPD_ROOT/users"
+HTTPD_GROUPS="$HTTPD_ROOT/groups"
mkdir "$HTTPD_ROOT" \
|| fail "couldn't create temporary directory '$HTTPD_ROOT'"
@@ -281,6 +284,14 @@ say "Using directory '$HTTPD_ROOT'..."
say "Adding users for lock authentication"
$HTPASSWD -bc $HTTPD_USERS jrandom rayjandom
$HTPASSWD -b $HTTPD_USERS jconstant rayjandom
+$HTPASSWD -b $HTTPD_USERS JRANDOM rayjandom
+$HTPASSWD -b $HTTPD_USERS JCONSTANT rayjandom
+
+say "Adding groups for mod_authz_svn tests"
+cat > "$HTTPD_GROUPS" <<__EOF__
+random: jrandom
+constant: jconstant
+__EOF__
touch $HTTPD_MIME_TYPES
@@ -297,7 +308,9 @@ $LOAD_MOD_AUTHN_CORE
$LOAD_MOD_AUTHN_FILE
$LOAD_MOD_AUTHZ_CORE
$LOAD_MOD_AUTHZ_USER
+$LOAD_MOD_AUTHZ_GROUPFILE
$LOAD_MOD_AUTHZ_HOST
+$LOAD_MOD_ACCESS_COMPAT
LoadModule authz_svn_module "$MOD_AUTHZ_SVN"
__EOF__
@@ -309,9 +322,17 @@ User $(id -un)
Group $(id -gn)
__EOF__
else
+HTTPD_LOCK="$HTTPD_ROOT/lock"
+mkdir "$HTTPD_LOCK" \
+ || fail "couldn't create lock directory '$HTTPD_LOCK'"
cat >> "$HTTPD_CFG" <<__EOF__
-# TODO: maybe uncomment this for prefork,worker MPMs only?
-# Mutex file:lock mpm-accept
+# worker and prefork MUST have a mpm-accept lockfile in 2.3.0+
+<IfModule worker.c>
+ Mutex "file:$HTTPD_LOCK" mpm-accept
+</IfModule>
+<IfModule prefork.c>
+ Mutex "file:$HTTPD_LOCK" mpm-accept
+</IfModule>
__EOF__
fi
@@ -369,6 +390,151 @@ CustomLog "$HTTPD_ROOT/ops" "%
SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
${SVN_PATH_AUTHZ_LINE}
</Location>
+<Location /authz-test-work/anon>
+ DAV svn
+ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp"
+ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz"
+ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
+ SVNListParentPath On
+ # This may seem unnecessary but granting access to everyone here is necessary
+ # to exercise a bug with httpd 2.3.x+. The "Require all granted" syntax is
+ # new to 2.3.x+ which we can detect with the mod_authz_core.c module
+ # signature. Use the "Allow from all" syntax with older versions for symmetry.
+ <IfModule mod_authz_core.c>
+ Require all granted
+ </IfModule>
+ <IfModule !mod_authz_core.c>
+ Allow from all
+ </IfMOdule>
+ ${SVN_PATH_AUTHZ_LINE}
+</Location>
+<Location /authz-test-work/mixed>
+ DAV svn
+ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp"
+ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz"
+ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile $HTTPD_USERS
+ Require valid-user
+ Satisfy Any
+ ${SVN_PATH_AUTHZ_LINE}
+</Location>
+<Location /authz-test-work/mixed-noauthwhenanon>
+ DAV svn
+ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp"
+ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz"
+ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile $HTTPD_USERS
+ Require valid-user
+ AuthzSVNNoAuthWhenAnonymousAllowed On
+ SVNPathAuthz On
+</Location>
+<Location /authz-test-work/authn>
+ DAV svn
+ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp"
+ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz"
+ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile $HTTPD_USERS
+ Require valid-user
+ ${SVN_PATH_AUTHZ_LINE}
+</Location>
+<Location /authz-test-work/authn-anonoff>
+ DAV svn
+ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp"
+ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz"
+ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile $HTTPD_USERS
+ Require valid-user
+ AuthzSVNAnonymous Off
+ SVNPathAuthz On
+</Location>
+<Location /authz-test-work/authn-lcuser>
+ DAV svn
+ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp"
+ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz"
+ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile $HTTPD_USERS
+ Require valid-user
+ AuthzForceUsernameCase Lower
+ ${SVN_PATH_AUTHZ_LINE}
+</Location>
+<Location /authz-test-work/authn-lcuser>
+ DAV svn
+ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp"
+ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz"
+ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile $HTTPD_USERS
+ Require valid-user
+ AuthzForceUsernameCase Lower
+ ${SVN_PATH_AUTHZ_LINE}
+</Location>
+<Location /authz-test-work/authn-group>
+ DAV svn
+ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp"
+ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz"
+ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile $HTTPD_USERS
+ AuthGroupFile $HTTPD_GROUPS
+ Require group random
+ AuthzSVNAuthoritative Off
+ SVNPathAuthz On
+</Location>
+<IfModule mod_authz_core.c>
+ <Location /authz-test-work/sallrany>
+ DAV svn
+ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp"
+ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz"
+ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile $HTTPD_USERS
+ AuthzSendForbiddenOnFailure On
+ Satisfy All
+ <RequireAny>
+ Require valid-user
+ Require expr req('ALLOW') == '1'
+ </RequireAny>
+ ${SVN_PATH_AUTHZ_LINE}
+ </Location>
+ <Location /authz-test-work/sallrall>
+ DAV svn
+ SVNParentPath "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/local_tmp"
+ AuthzSVNAccessFile "$ABS_BUILDDIR/subversion/tests/cmdline/svn-test-work/authz"
+ SVNAdvertiseV2Protocol ${ADVERTISE_V2_PROTOCOL}
+ SVNListParentPath On
+ AuthType Basic
+ AuthName "Subversion Repository"
+ AuthUserFile $HTTPD_USERS
+ AuthzSendForbiddenOnFailure On
+ Satisfy All
+ <RequireAll>
+ Require valid-user
+ Require expr req('ALLOW') == '1'
+ </RequireAll>
+ ${SVN_PATH_AUTHZ_LINE}
+ </Location>
+</IfModule>
RedirectMatch permanent ^/svn-test-work/repositories/REDIRECT-PERM-(.*)\$ /svn-test-work/repositories/\$1
RedirectMatch ^/svn-test-work/repositories/REDIRECT-TEMP-(.*)\$ /svn-test-work/repositories/\$1
__EOF__
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/patch_tests.py?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/patch_tests.py Tue Jul 28 11:18:37 2015
@@ -4070,6 +4070,243 @@ def patch_git_with_index_line(sbox):
1, # check-props
1) # dry-run
+@XFail()
+@Issue(4533)
+def patch_hunk_avoid_reorder(sbox):
+ """avoid reordering hunks"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_append('A/mu',
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+ 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+ 'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ 'MM\n' 'NN\n' 'OO\n' 'PP\n' 'QQ\n' 'RR\n'
+ 'SS\n' 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n'
+ 'YY\n' 'ZZ\n', truncate=True)
+ sbox.simple_commit()
+
+ # two hunks, first matches at offset +18, second matches at both -13
+ # and +18 but we want the second match as it is after the first
+ unidiff_patch = [
+ "Index: A/mu\n"
+ "===================================================================\n",
+ "--- A/mu\t(revision 1)\n",
+ "+++ A/mu\t(working copy)\n",
+ "@@ -13,6 +13,7 @@\n",
+ " MM\n",
+ " NN\n",
+ " OO\n",
+ "+11111\n",
+ " PP\n",
+ " QQ\n",
+ " RR\n",
+ "@@ -20,6 +20,7 @@\n",
+ " TT\n",
+ " UU\n",
+ " VV\n",
+ "+22222\n",
+ " WW\n",
+ " XX\n",
+ " YY\n",
+ ]
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ expected_output = [
+ 'U %s\n' % sbox.ospath('A/mu'),
+ '> applied hunk @@ -13,6 +13,7 @@ with offset 18\n',
+ '> applied hunk @@ -20,6 +20,7 @@ with offset 18\n'
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu', contents=
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+ 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+ 'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ 'MM\n' 'NN\n' 'OO\n' '11111\n' 'PP\n' 'QQ\n' 'RR\n'
+ 'SS\n' 'TT\n' 'UU\n' 'VV\n' '22222\n' 'WW\n' 'XX\n'
+ 'YY\n' 'ZZ\n')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', status='M ', wc_rev=2)
+ expected_skip = wc.State('', { })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+ sbox.simple_revert('A/mu')
+
+ # change patch so second hunk matches at both -14 and +17, we still
+ # want the second match
+ unidiff_patch = [
+ "Index: A/mu\n"
+ "===================================================================\n",
+ "--- A/mu\t(revision 1)\n",
+ "+++ A/mu\t(working copy)\n",
+ "@@ -13,6 +13,7 @@\n",
+ " MM\n",
+ " NN\n",
+ " OO\n",
+ "+11111\n",
+ " PP\n",
+ " QQ\n",
+ " RR\n",
+ "@@ -21,6 +21,7 @@\n",
+ " TT\n",
+ " UU\n",
+ " VV\n",
+ "+22222\n",
+ " WW\n",
+ " XX\n",
+ " YY\n",
+ ]
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ expected_output = [
+ 'U %s\n' % sbox.ospath('A/mu'),
+ '> applied hunk @@ -13,6 +13,7 @@ with offset 18\n',
+ '> applied hunk @@ -21,6 +21,7 @@ with offset 17\n'
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu', contents=
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+ 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+ 'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ 'MM\n' 'NN\n' 'OO\n' '11111\n' 'PP\n' 'QQ\n' 'RR\n'
+ 'SS\n' 'TT\n' 'UU\n' 'VV\n' '22222\n' 'WW\n' 'XX\n'
+ 'YY\n' 'ZZ\n')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', status='M ', wc_rev=2)
+ expected_skip = wc.State('', { })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+ sbox.simple_revert('A/mu')
+
+ # change patch so second hunk matches at both -12 and +19, we still
+ # want the second match
+ unidiff_patch = [
+ "Index: A/mu\n"
+ "===================================================================\n",
+ "--- A/mu\t(revision 1)\n",
+ "+++ A/mu\t(working copy)\n",
+ "@@ -13,6 +13,7 @@\n",
+ " MM\n",
+ " NN\n",
+ " OO\n",
+ "+11111\n",
+ " PP\n",
+ " QQ\n",
+ " RR\n",
+ "@@ -19,6 +19,7 @@\n",
+ " TT\n",
+ " UU\n",
+ " VV\n",
+ "+22222\n",
+ " WW\n",
+ " XX\n",
+ " YY\n",
+ ]
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ expected_output = [
+ 'U %s\n' % sbox.ospath('A/mu'),
+ '> applied hunk @@ -13,6 +13,7 @@ with offset 18\n',
+ '> applied hunk @@ -19,6 +19,7 @@ with offset 19\n'
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu', contents=
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n'
+ 'TT\n' 'UU\n' 'VV\n' 'WW\n' 'XX\n' 'YY\n'
+ 'GG\n' 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ '33333\n' '33333\n' '33333\n'
+ 'MM\n' 'NN\n' 'OO\n' '11111\n' 'PP\n' 'QQ\n' 'RR\n'
+ 'SS\n' 'TT\n' 'UU\n' 'VV\n' '22222\n' 'WW\n' 'XX\n'
+ 'YY\n' 'ZZ\n')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', status='M ', wc_rev=2)
+ expected_skip = wc.State('', { })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
+@Issue(4533)
+def patch_hunk_reorder(sbox):
+ """hunks that reorder"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ sbox.simple_append('A/mu',
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' 'EE\n' 'FF\n' 'GG\n'
+ 'HH\n' 'II\n' 'JJ\n' 'KK\n' 'LL\n' 'MM\n' 'NN\n',
+ truncate=True)
+ sbox.simple_commit()
+
+ # Two hunks match in opposite order
+ unidiff_patch = [
+ "Index: A/mu\n"
+ "===================================================================\n",
+ "--- A/mu\t(revision 1)\n",
+ "+++ A/mu\t(working copy)\n",
+ "@@ -2,6 +2,7 @@\n",
+ " II\n",
+ " JJ\n",
+ " KK\n",
+ "+11111\n",
+ " LL\n",
+ " MM\n",
+ " NN\n",
+ "@@ -9,6 +10,7 @@\n",
+ " BB\n",
+ " CC\n",
+ " DD\n",
+ "+22222\n",
+ " EE\n",
+ " FF\n",
+ " GG\n",
+ ]
+
+ patch_file_path = make_patch_path(sbox)
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ expected_output = [
+ 'U %s\n' % sbox.ospath('A/mu'),
+ '> applied hunk @@ -9,6 +10,7 @@ with offset -7\n',
+ '> applied hunk @@ -2,6 +2,7 @@ with offset 7\n',
+ ]
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu', contents=
+ 'AA\n' 'BB\n' 'CC\n' 'DD\n' '22222\n' 'EE\n' 'FF\n' 'GG\n'
+ 'HH\n' 'II\n' 'JJ\n' 'KK\n' '11111\n' 'LL\n' 'MM\n' 'NN\n')
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/mu', status='M ', wc_rev=2)
+ expected_skip = wc.State('', { })
+ svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+ expected_output, expected_disk,
+ expected_status, expected_skip)
+
########################################################################
#Run the tests
@@ -4114,6 +4351,8 @@ test_list = [ None,
patch_target_no_eol_at_eof,
patch_add_and_delete,
patch_git_with_index_line,
+ patch_hunk_avoid_reorder,
+ patch_hunk_reorder,
]
if __name__ == '__main__':
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/svnrdump_tests.py?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/svnrdump_tests.py Tue Jul 28 11:18:37 2015
@@ -762,6 +762,151 @@ def svnrdump_load_partial_incremental_du
svntest.verify.AnyOutput,
[], 0, 'load', sbox.repo_url)
+#----------------------------------------------------------------------
+
+# Regression test for issue 4551 "svnrdump load commits wrong properties,
+# or fails, on a non-deltas dumpfile". In this test, the copy source does
+# not exist and the failure mode is to error out.
+@Issue(4551)
+def load_non_deltas_copy_with_props(sbox):
+ "load non-deltas copy with props"
+ sbox.build()
+
+ # Case (1): Copies that do not replace anything: the copy target path
+ # at (new rev - 1) does not exist
+
+ # Set properties on each node to be copied
+ sbox.simple_propset('p', 'v', 'A/mu', 'A/B', 'A/B/E')
+ sbox.simple_propset('q', 'v', 'A/mu', 'A/B', 'A/B/E')
+ sbox.simple_commit()
+ sbox.simple_update() # avoid mixed-rev
+
+ # Do the copies
+ sbox.simple_copy('A/mu@2', 'A/mu_COPY')
+ sbox.simple_copy('A/B@2', 'A/B_COPY')
+ # Also add new nodes inside the copied dir, to test more code paths
+ sbox.simple_copy('A/B/E@2', 'A/B_COPY/copied')
+ sbox.simple_mkdir('A/B_COPY/added')
+ sbox.simple_copy('A/B/E@2', 'A/B_COPY/added/copied')
+ # On each copied node, delete a prop
+ sbox.simple_propdel('p', 'A/mu_COPY', 'A/B_COPY', 'A/B_COPY/E',
+ 'A/B_COPY/copied', 'A/B_COPY/added/copied')
+
+ sbox.simple_commit()
+
+ # Dump with 'svnadmin' (non-deltas mode)
+ dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir, deltas=False)
+
+ # Load with 'svnrdump'. This used to throw an error:
+ # svnrdump: E160013: File not found: revision 2, path '/A/B_COPY'
+ new_repo_dir, new_repo_url = sbox.add_repo_path('new_repo')
+ svntest.main.create_repos(new_repo_dir)
+ svntest.actions.enable_revprop_changes(new_repo_dir)
+ svntest.actions.run_and_verify_svnrdump(dumpfile,
+ svntest.verify.AnyOutput,
+ [], 0, 'load', new_repo_url)
+
+ # Check that property 'p' really was deleted on each copied node
+ for tgt_path in ['A/mu_COPY', 'A/B_COPY', 'A/B_COPY/E',
+ 'A/B_COPY/copied', 'A/B_COPY/added/copied']:
+ tgt_url = new_repo_url + '/' + tgt_path
+ _, out, _ = svntest.main.run_svn(None, 'proplist', tgt_url)
+ expected = ["Properties on '%s':" % (tgt_url,),
+ 'q']
+ actual = map(str.strip, out)
+ svntest.verify.compare_and_display_lines(None, 'PROPS', expected, actual)
+
+# Regression test for issue 4551 "svnrdump load commits wrong properties,
+# or fails, on a non-deltas dumpfile". In this test, the copy source does
+# exist and the failure mode is to fail to delete a property.
+@Issue(4551)
+def load_non_deltas_replace_copy_with_props(sbox):
+ "load non-deltas replace© with props"
+ sbox.build()
+
+ # Case (2): Copies that replace something: the copy target path
+ # at (new rev - 1) exists and has no property named 'p'
+
+ # Set props on the copy source nodes (a file, a dir, a child of the dir)
+ sbox.simple_propset('p', 'v', 'A/mu', 'A/B', 'A/B/E')
+ sbox.simple_propset('q', 'v', 'A/mu', 'A/B', 'A/B/E')
+ sbox.simple_commit()
+ sbox.simple_update() # avoid mixed-rev
+
+ # Do the copies, replacing something
+ sbox.simple_rm('A/D/gamma', 'A/C')
+ sbox.simple_copy('A/mu@2', 'A/D/gamma')
+ sbox.simple_copy('A/B@2', 'A/C')
+ # On the copy, delete a prop that wasn't present on the node that it replaced
+ sbox.simple_propdel('p', 'A/D/gamma', 'A/C', 'A/C/E')
+
+ sbox.simple_commit()
+
+ # Dump with 'svnadmin' (non-deltas mode)
+ dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir, deltas=False)
+
+ # Load with 'svnrdump'
+ new_repo_dir, new_repo_url = sbox.add_repo_path('new_repo')
+ svntest.main.create_repos(new_repo_dir)
+ svntest.actions.enable_revprop_changes(new_repo_dir)
+ svntest.actions.run_and_verify_svnrdump(dumpfile,
+ svntest.verify.AnyOutput,
+ [], 0, 'load', new_repo_url)
+
+ # Check that property 'p' really was deleted on each copied node
+ # This used to fail, finding that property 'p' was still present
+ for tgt_path in ['A/D/gamma', 'A/C', 'A/C/E']:
+ tgt_url = new_repo_url + '/' + tgt_path
+ _, out, _ = svntest.main.run_svn(None, 'proplist', tgt_url)
+ expected = ["Properties on '%s':" % (tgt_url,),
+ 'q']
+ actual = map(str.strip, out)
+ svntest.verify.compare_and_display_lines(None, 'PROPS', expected, actual)
+
+# Regression test for issue 4551 "svnrdump load commits wrong properties,
+# or fails, on a non-deltas dumpfile". In this test, a node's props are
+# modified, and the failure mode is that RA-serf would end up deleting
+# properties that should remain on the node.
+@Issue(4551)
+def load_non_deltas_with_props(sbox):
+ "load non-deltas with props"
+ sbox.build()
+
+ # Case (3): A node's props are modified, and at least one of its previous
+ # props remains after the modification. svnrdump made two prop mod method
+ # calls for the same property (delete, then set). RA-serf's commit editor
+ # didn't expect this and performed the deletes after the non-deletes, and
+ # so ended up deleting a property that should not be deleted.
+
+ # Set properties on each node to be modified
+ sbox.simple_propset('p', 'v', 'A/mu')
+ sbox.simple_propset('q', 'v', 'A/mu', 'A/B')
+ sbox.simple_commit()
+
+ # Do the modifications: a different kind of mod on each node
+ sbox.simple_propdel('p', 'A/mu')
+ sbox.simple_propset('q', 'v2', 'A/B')
+ sbox.simple_commit()
+
+ # Dump with 'svnadmin' (non-deltas mode)
+ dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir, deltas=False)
+
+ # Load with 'svnrdump'
+ new_repo_dir, new_repo_url = sbox.add_repo_path('new_repo')
+ svntest.main.create_repos(new_repo_dir)
+ svntest.actions.enable_revprop_changes(new_repo_dir)
+ svntest.actions.run_and_verify_svnrdump(dumpfile,
+ svntest.verify.AnyOutput,
+ [], 0, 'load', new_repo_url)
+
+ # Check that property 'q' remains on each modified node
+ for tgt_path in ['A/mu', 'A/B']:
+ tgt_url = new_repo_url + '/' + tgt_path
+ _, out, _ = svntest.main.run_svn(None, 'proplist', tgt_url)
+ expected = ["Properties on '%s':" % (tgt_url,),
+ 'q']
+ actual = map(str.strip, out)
+ svntest.verify.compare_and_display_lines(None, 'PROPS', expected, actual)
########################################################################
# Run the tests
@@ -813,6 +958,9 @@ test_list = [ None,
reflect_dropped_renumbered_revs,
dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads,
svnrdump_load_partial_incremental_dump,
+ load_non_deltas_copy_with_props,
+ load_non_deltas_replace_copy_with_props,
+ load_non_deltas_with_props,
]
if __name__ == '__main__':
Propchange: subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/svntest/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jul 28 11:18:37 2015
@@ -1,6 +1,6 @@
/subversion/1.7.x-issue4059/subversion/tests/cmdline/svntest:1239661-1239744
/subversion/branches/1.5.x-r30215/subversion/tests/cmdline/svntest:870312
-/subversion/branches/1.7.x/subversion/tests/cmdline/svntest:1480943-1645438
+/subversion/branches/1.7.x/subversion/tests/cmdline/svntest:1480943-1693067
/subversion/branches/1.7.x-JavaHL-pools/subversion/tests/cmdline/svntest:1158684-1158722
/subversion/branches/1.7.x-gssapi-solaris10/subversion/tests/cmdline/svntest:1453164-1515067
/subversion/branches/1.7.x-issue3888/subversion/tests/cmdline/svntest:1148937-1149162
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/svntest/main.py?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/tests/cmdline/svntest/main.py Tue Jul 28 11:18:37 2015
@@ -1148,6 +1148,30 @@ def server_enforces_date_syntax():
def server_has_atomic_revprop():
return options.server_minor_version >= 7
+
+# https://issues.apache.org/bugzilla/show_bug.cgi?id=56480
+# https://issues.apache.org/bugzilla/show_bug.cgi?id=55397
+__mod_dav_url_quoting_broken_versions = frozenset([
+ '2.2.27',
+ '2.2.26',
+ '2.2.25',
+ '2.4.9',
+ '2.4.8',
+ '2.4.7',
+ '2.4.6',
+ '2.4.5',
+])
+def is_mod_dav_url_quoting_broken():
+ if is_ra_type_dav():
+ return (options.httpd_version in __mod_dav_url_quoting_broken_versions)
+ return None
+
+def is_httpd_authz_provider_enabled():
+ if is_ra_type_dav():
+ v = options.httpd_version.split('.')
+ return (v[0] == '2' and int(v[1]) >= 3) or int(v[0]) > 2
+ return None
+
######################################################################
@@ -1194,6 +1218,8 @@ class TestSpawningThread(threading.Threa
args.append('--mode-filter=' + options.mode_filter)
if options.milestone_filter:
args.append('--milestone-filter=' + options.milestone_filter)
+ if options.httpd_version:
+ args.append('--httpd-version=' + options.httpd_version)
result, stdout_lines, stderr_lines = spawn_process(command, 0, 0, None,
*args)
@@ -1361,6 +1387,36 @@ class TestRunner:
sandbox.cleanup_test_paths()
return exit_code
+
+# https://issues.apache.org/bugzilla/show_bug.cgi?id=56480
+# https://issues.apache.org/bugzilla/show_bug.cgi?id=55397
+__mod_dav_url_quoting_broken_versions = frozenset([
+ '2.2.27',
+ '2.2.26',
+ '2.2.25',
+ '2.4.9',
+ '2.4.8',
+ '2.4.7',
+ '2.4.6',
+ '2.4.5',
+])
+def is_mod_dav_url_quoting_broken():
+ if is_ra_type_dav():
+ return (options.httpd_version in __mod_dav_url_quoting_broken_versions)
+ return None
+
+def is_httpd_authz_provider_enabled():
+ if is_ra_type_dav():
+ v = options.httpd_version.split('.')
+ return (v[0] == '2' and int(v[1]) >= 3) or int(v[0]) > 2
+ return None
+
+def is_httpd_authz_provider_enabled():
+ if is_ra_type_dav():
+ v = options.httpd_version.split('.')
+ return (v[0] == '2' and int(v[1]) >= 3) or int(v[0]) > 2
+ return None
+
######################################################################
# Main testing functions
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/tests/libsvn_repos/repos-test.c?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/tests/libsvn_repos/repos-test.c Tue Jul 28 11:18:37 2015
@@ -2684,6 +2684,246 @@ test_dump_r0_mergeinfo(const svn_test_op
return SVN_NO_ERROR;
}
+static svn_error_t *
+mkdir_delete_copy(svn_repos_t *repos,
+ const char *src,
+ const char *dst,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs = svn_repos_fs(repos);
+ svn_revnum_t youngest_rev;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root, *rev_root;
+
+ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));
+
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "A/T", pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_delete(txn_root, "A/T", pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, youngest_rev - 1, pool));
+ SVN_ERR(svn_fs_copy(rev_root, src, txn_root, dst, pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ return SVN_NO_ERROR;
+}
+
+struct authz_read_baton_t {
+ apr_hash_t *paths;
+ apr_pool_t *pool;
+ const char *deny;
+};
+
+static svn_error_t *
+authz_read_func(svn_boolean_t *allowed,
+ svn_fs_root_t *root,
+ const char *path,
+ void *baton,
+ apr_pool_t *pool)
+{
+ struct authz_read_baton_t *b = baton;
+
+ if (b->deny && !strcmp(b->deny, path))
+ *allowed = FALSE;
+ else
+ *allowed = TRUE;
+
+ apr_hash_set(b->paths, apr_pstrdup(b->pool, path), APR_HASH_KEY_STRING,
+ (void*)1);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+verify_locations(apr_hash_t *actual,
+ apr_hash_t *expected,
+ apr_hash_t *checked,
+ apr_pool_t *pool)
+{
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first(pool, expected); hi; hi = apr_hash_next(hi))
+ {
+ const svn_revnum_t *rev = svn__apr_hash_index_key(hi);
+ const char *path = apr_hash_get(actual, rev, sizeof(svn_revnum_t));
+
+ if (!path)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "expected %s for %d found (null)",
+ (char*)svn__apr_hash_index_val(hi),
+ (int)*rev);
+ else if (strcmp(path, svn__apr_hash_index_val(hi)))
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "expected %s for %d found %s",
+ (char*)svn__apr_hash_index_val(hi),
+ (int)*rev, path);
+
+ }
+
+ for (hi = apr_hash_first(pool, actual); hi; hi = apr_hash_next(hi))
+ {
+ const svn_revnum_t *rev = svn__apr_hash_index_key(hi);
+ const char *path = apr_hash_get(expected, rev, sizeof(svn_revnum_t));
+
+ if (!path)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "found %s for %d expected (null)",
+ (char*)svn__apr_hash_index_val(hi),
+ (int)*rev);
+ else if (strcmp(path, svn__apr_hash_index_val(hi)))
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "found %s for %d expected %s",
+ (char*)svn__apr_hash_index_val(hi),
+ (int)*rev, path);
+
+ if (!apr_hash_get(checked, path, APR_HASH_KEY_STRING))
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "did not check %s", path);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static void
+set_expected(apr_hash_t *expected,
+ svn_revnum_t rev,
+ const char *path,
+ apr_pool_t *pool)
+{
+ svn_revnum_t *rp = apr_palloc(pool, sizeof(svn_revnum_t));
+ *rp = rev;
+ apr_hash_set(expected, rp, sizeof(svn_revnum_t), path);
+}
+
+static svn_error_t *
+trace_node_locations_authz(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_repos_t *repos;
+ svn_fs_t *fs;
+ svn_revnum_t youngest_rev = 0;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ struct authz_read_baton_t arb;
+ apr_array_header_t *revs = apr_array_make(pool, 10, sizeof(svn_revnum_t));
+ apr_hash_t *locations;
+ apr_hash_t *expected = apr_hash_make(pool);
+ int i;
+
+ /* Create test repository. */
+ SVN_ERR(svn_test__create_repos(&repos, "test-repo-trace-node-locations-authz",
+ opts, pool));
+ fs = svn_repos_fs(repos);
+
+ /* r1 create A */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "A", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "A/f", pool));
+ SVN_ERR(svn_test__set_file_contents(txn_root, "A/f", "foobar", pool));
+ SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+ /* r4 copy A to B */
+ SVN_ERR(mkdir_delete_copy(repos, "A", "B", pool));
+
+ /* r7 copy B to C */
+ SVN_ERR(mkdir_delete_copy(repos, "B", "C", pool));
+
+ /* r10 copy C to D */
+ SVN_ERR(mkdir_delete_copy(repos, "C", "D", pool));
+
+ SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));
+ SVN_ERR_ASSERT(youngest_rev == 10);
+
+ arb.paths = apr_hash_make(pool);
+ arb.pool = pool;
+ arb.deny = NULL;
+
+ apr_array_clear(revs);
+ for (i = 0; i <= youngest_rev; ++i)
+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
+ set_expected(expected, 10, "/D/f", pool);
+ set_expected(expected, 8, "/C/f", pool);
+ set_expected(expected, 7, "/C/f", pool);
+ set_expected(expected, 5, "/B/f", pool);
+ set_expected(expected, 4, "/B/f", pool);
+ set_expected(expected, 2, "/A/f", pool);
+ set_expected(expected, 1, "/A/f", pool);
+ apr_hash_clear(arb.paths);
+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
+ authz_read_func, &arb, pool));
+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
+
+ apr_array_clear(revs);
+ for (i = 1; i <= youngest_rev; ++i)
+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
+ apr_hash_clear(arb.paths);
+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
+ authz_read_func, &arb, pool));
+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
+
+ apr_array_clear(revs);
+ for (i = 2; i <= youngest_rev; ++i)
+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
+ set_expected(expected, 1, NULL, pool);
+ apr_hash_clear(arb.paths);
+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
+ authz_read_func, &arb, pool));
+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
+
+ apr_array_clear(revs);
+ for (i = 3; i <= youngest_rev; ++i)
+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
+ set_expected(expected, 2, NULL, pool);
+ apr_hash_clear(arb.paths);
+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
+ authz_read_func, &arb, pool));
+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
+
+ apr_array_clear(revs);
+ for (i = 6; i <= youngest_rev; ++i)
+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
+ set_expected(expected, 5, NULL, pool);
+ set_expected(expected, 4, NULL, pool);
+ apr_hash_clear(arb.paths);
+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
+ authz_read_func, &arb, pool));
+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
+
+ arb.deny = "/B/f";
+ apr_array_clear(revs);
+ for (i = 0; i <= youngest_rev; ++i)
+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
+ apr_hash_clear(arb.paths);
+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
+ authz_read_func, &arb, pool));
+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
+
+ apr_array_clear(revs);
+ for (i = 6; i <= youngest_rev; ++i)
+ APR_ARRAY_PUSH(revs, svn_revnum_t) = i;
+ apr_hash_clear(arb.paths);
+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
+ authz_read_func, &arb, pool));
+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
+
+ APR_ARRAY_PUSH(revs, svn_revnum_t) = 0;
+ apr_hash_clear(arb.paths);
+ SVN_ERR(svn_repos_trace_node_locations(fs, &locations, "D/f", 10, revs,
+ authz_read_func, &arb, pool));
+ SVN_ERR(verify_locations(locations, expected, arb.paths, pool));
+
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
struct svn_test_descriptor_t test_funcs[] =
@@ -2723,5 +2963,7 @@ struct svn_test_descriptor_t test_funcs[
"test dumping with r0 mergeinfo"),
SVN_TEST_OPTS_PASS(filename_with_control_chars,
"test filenames with control characters"),
+ SVN_TEST_OPTS_PASS(trace_node_locations_authz,
+ "authz for svn_repos_trace_node_locations"),
SVN_TEST_NULL
};
Modified: subversion/branches/1.7.x-issue4340-repos/subversion/tests/libsvn_subr/config-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/subversion/tests/libsvn_subr/config-test.c?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/subversion/tests/libsvn_subr/config-test.c (original)
+++ subversion/branches/1.7.x-issue4340-repos/subversion/tests/libsvn_subr/config-test.c Tue Jul 28 11:18:37 2015
@@ -231,6 +231,32 @@ test_has_section(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_expand(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_config_t *cfg;
+ const char *cfg_file, *val;
+
+ if (!srcdir)
+ SVN_ERR(init_params(pool));
+
+ cfg_file = apr_pstrcat(pool, srcdir, "/", "config-test.cfg", (char *)NULL);
+ SVN_ERR(svn_config_read2(&cfg, cfg_file, TRUE, FALSE, pool));
+
+ /* Get expanded "g" which requires expanding "c". */
+ svn_config_get(cfg, &val, "section1", "g", NULL);
+
+ /* Get expanded "c". */
+ svn_config_get(cfg, &val, "section1", "c", NULL);
+
+ /* With pool debugging enabled this ensures that the expanded value
+ of "c" was not created in a temporary pool when expanding "g". */
+ SVN_TEST_STRING_ASSERT(val, "bar");
+
+ return SVN_NO_ERROR;
+}
+
/*
====================================================================
If you add a new test to this file, update this array.
@@ -248,5 +274,7 @@ struct svn_test_descriptor_t test_funcs[
"test svn_config boolean conversion"),
SVN_TEST_PASS2(test_has_section,
"test svn_config_has_section"),
+ SVN_TEST_OPTS_PASS(test_expand,
+ "test variable expansion"),
SVN_TEST_NULL
};
Modified: subversion/branches/1.7.x-issue4340-repos/win-tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4340-repos/win-tests.py?rev=1693068&r1=1693067&r2=1693068&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4340-repos/win-tests.py (original)
+++ subversion/branches/1.7.x-issue4340-repos/win-tests.py Tue Jul 28 11:18:37 2015
@@ -466,6 +466,7 @@ class Httpd:
self.httpd_config = os.path.join(self.root, 'httpd.conf')
self.httpd_users = os.path.join(self.root, 'users')
self.httpd_mime_types = os.path.join(self.root, 'mime.types')
+ self.httpd_groups = os.path.join(self.root, 'groups')
self.abs_builddir = abs_builddir
self.abs_objdir = abs_objdir
self.service_name = 'svn-test-httpd-' + str(httpd_port)
@@ -479,6 +480,7 @@ class Httpd:
create_target_dir(self.root_dir)
self._create_users_file()
+ self._create_groups_file()
self._create_mime_types_file()
# Determine version.
@@ -520,6 +522,8 @@ class Httpd:
if self.httpd_ver >= 2.2:
fp.write(self._sys_module('auth_basic_module', 'mod_auth_basic.so'))
fp.write(self._sys_module('authn_file_module', 'mod_authn_file.so'))
+ fp.write(self._sys_module('authz_groupfile_module', 'mod_authz_groupfile.so'))
+ fp.write(self._sys_module('authz_host_module', 'mod_authz_host.so'))
else:
fp.write(self._sys_module('auth_module', 'mod_auth.so'))
fp.write(self._sys_module('alias_module', 'mod_alias.so'))
@@ -533,6 +537,7 @@ class Httpd:
# Define two locations for repositories
fp.write(self._svn_repo('repositories'))
fp.write(self._svn_repo('local_tmp'))
+ fp.write(self._svn_authz_repo())
# And two redirects for the redirect tests
fp.write('RedirectMatch permanent ^/svn-test-work/repositories/'
@@ -562,6 +567,17 @@ class Httpd:
'jrandom', 'rayjandom'])
os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-mb', self.httpd_users,
'jconstant', 'rayjandom'])
+ os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users,
+ 'JRANDOM', 'rayjandom'])
+ os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users,
+ 'JCONSTANT', 'rayjandom'])
+
+ def _create_groups_file(self):
+ "Create groups for mod_authz_svn tests"
+ fp = open(self.httpd_groups, 'w')
+ fp.write('random: jrandom\n')
+ fp.write('constant: jconstant\n')
+ fp.close()
def _create_mime_types_file(self):
"Create empty mime.types file"
@@ -595,6 +611,153 @@ class Httpd:
' Require valid-user\n' \
'</Location>\n'
+ def _svn_authz_repo(self):
+ local_tmp = os.path.join(self.abs_builddir,
+ CMDLINE_TEST_SCRIPT_NATIVE_PATH,
+ 'svn-test-work', 'local_tmp')
+ return \
+ '<Location /authz-test-work/anon>' + '\n' \
+ ' DAV svn' + '\n' \
+ ' SVNParentPath ' + local_tmp + '\n' \
+ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
+ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
+ ' SVNListParentPath On' + '\n' \
+ ' <IfModule mod_authz_core.c>' + '\n' \
+ ' Require all granted' + '\n' \
+ ' </IfModule>' + '\n' \
+ ' <IfModule !mod_authz_core.c>' + '\n' \
+ ' Allow from all' + '\n' \
+ ' </IfModule>' + '\n' \
+ ' SVNPathAuthz ' + self.path_authz_option + '\n' \
+ '</Location>' + '\n' \
+ '<Location /authz-test-work/mixed>' + '\n' \
+ ' DAV svn' + '\n' \
+ ' SVNParentPath ' + local_tmp + '\n' \
+ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
+ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
+ ' SVNListParentPath On' + '\n' \
+ ' AuthType Basic' + '\n' \
+ ' AuthName "Subversion Repository"' + '\n' \
+ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
+ ' Require valid-user' + '\n' \
+ ' Satisfy Any' + '\n' \
+ ' SVNPathAuthz ' + self.path_authz_option + '\n' \
+ '</Location>' + '\n' \
+ '<Location /authz-test-work/mixed-noauthwhenanon>' + '\n' \
+ ' DAV svn' + '\n' \
+ ' SVNParentPath ' + local_tmp + '\n' \
+ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
+ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
+ ' SVNListParentPath On' + '\n' \
+ ' AuthType Basic' + '\n' \
+ ' AuthName "Subversion Repository"' + '\n' \
+ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
+ ' Require valid-user' + '\n' \
+ ' AuthzSVNNoAuthWhenAnonymousAllowed On' + '\n' \
+ ' SVNPathAuthz On' + '\n' \
+ '</Location>' + '\n' \
+ '<Location /authz-test-work/authn>' + '\n' \
+ ' DAV svn' + '\n' \
+ ' SVNParentPath ' + local_tmp + '\n' \
+ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
+ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
+ ' SVNListParentPath On' + '\n' \
+ ' AuthType Basic' + '\n' \
+ ' AuthName "Subversion Repository"' + '\n' \
+ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
+ ' Require valid-user' + '\n' \
+ ' SVNPathAuthz ' + self.path_authz_option + '\n' \
+ '</Location>' + '\n' \
+ '<Location /authz-test-work/authn-anonoff>' + '\n' \
+ ' DAV svn' + '\n' \
+ ' SVNParentPath ' + local_tmp + '\n' \
+ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
+ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
+ ' SVNListParentPath On' + '\n' \
+ ' AuthType Basic' + '\n' \
+ ' AuthName "Subversion Repository"' + '\n' \
+ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
+ ' Require valid-user' + '\n' \
+ ' AuthzSVNAnonymous Off' + '\n' \
+ ' SVNPathAuthz On' + '\n' \
+ '</Location>' + '\n' \
+ '<Location /authz-test-work/authn-lcuser>' + '\n' \
+ ' DAV svn' + '\n' \
+ ' SVNParentPath ' + local_tmp + '\n' \
+ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
+ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
+ ' SVNListParentPath On' + '\n' \
+ ' AuthType Basic' + '\n' \
+ ' AuthName "Subversion Repository"' + '\n' \
+ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
+ ' Require valid-user' + '\n' \
+ ' AuthzForceUsernameCase Lower' + '\n' \
+ ' SVNPathAuthz ' + self.path_authz_option + '\n' \
+ '</Location>' + '\n' \
+ '<Location /authz-test-work/authn-lcuser>' + '\n' \
+ ' DAV svn' + '\n' \
+ ' SVNParentPath ' + local_tmp + '\n' \
+ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
+ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
+ ' SVNListParentPath On' + '\n' \
+ ' AuthType Basic' + '\n' \
+ ' AuthName "Subversion Repository"' + '\n' \
+ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
+ ' Require valid-user' + '\n' \
+ ' AuthzForceUsernameCase Lower' + '\n' \
+ ' SVNPathAuthz ' + self.path_authz_option + '\n' \
+ '</Location>' + '\n' \
+ '<Location /authz-test-work/authn-group>' + '\n' \
+ ' DAV svn' + '\n' \
+ ' SVNParentPath ' + local_tmp + '\n' \
+ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
+ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
+ ' SVNListParentPath On' + '\n' \
+ ' AuthType Basic' + '\n' \
+ ' AuthName "Subversion Repository"' + '\n' \
+ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
+ ' AuthGroupFile ' + self._quote(self.httpd_groups) + '\n' \
+ ' Require group random' + '\n' \
+ ' AuthzSVNAuthoritative Off' + '\n' \
+ ' SVNPathAuthz On' + '\n' \
+ '</Location>' + '\n' \
+ '<IfModule mod_authz_core.c>' + '\n' \
+ '<Location /authz-test-work/sallrany>' + '\n' \
+ ' DAV svn' + '\n' \
+ ' SVNParentPath ' + local_tmp + '\n' \
+ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
+ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
+ ' SVNListParentPath On' + '\n' \
+ ' AuthType Basic' + '\n' \
+ ' AuthName "Subversion Repository"' + '\n' \
+ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
+ ' AuthzSendForbiddenOnFailure On' + '\n' \
+ ' Satisfy All' + '\n' \
+ ' <RequireAny>' + '\n' \
+ ' Require valid-user' + '\n' \
+ ' Require expr req(\'ALLOW\') == \'1\'' + '\n' \
+ ' </RequireAny>' + '\n' \
+ ' SVNPathAuthz ' + self.path_authz_option + '\n' \
+ '</Location>' + '\n' \
+ '<Location /authz-test-work/sallrall>'+ '\n' \
+ ' DAV svn' + '\n' \
+ ' SVNParentPath ' + local_tmp + '\n' \
+ ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
+ ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
+ ' SVNListParentPath On' + '\n' \
+ ' AuthType Basic' + '\n' \
+ ' AuthName "Subversion Repository"' + '\n' \
+ ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
+ ' AuthzSendForbiddenOnFailure On' + '\n' \
+ ' Satisfy All' + '\n' \
+ ' <RequireAll>' + '\n' \
+ ' Require valid-user' + '\n' \
+ ' Require expr req(\'ALLOW\') == \'1\'' + '\n' \
+ ' </RequireAll>' + '\n' \
+ ' SVNPathAuthz ' + self.path_authz_option + '\n' \
+ '</Location>' + '\n' \
+ '</IfModule>' + '\n' \
+
def start(self):
if self.service:
self._start_service()
@@ -728,6 +891,10 @@ if not test_javahl:
log_file = os.path.join(abs_builddir, log)
fail_log_file = os.path.join(abs_builddir, faillog)
+ if run_httpd:
+ httpd_version = "%.1f" % daemon.httpd_ver
+ else:
+ httpd_version = None
th = run_tests.TestHarness(abs_srcdir, abs_builddir,
log_file,
fail_log_file,
@@ -736,7 +903,8 @@ if not test_javahl:
cleanup, enable_sasl, parallel, config_file,
fsfs_sharding, fsfs_packing,
list_tests, svn_bin, mode_filter,
- milestone_filter)
+ milestone_filter,
+ httpd_version=httpd_version)
old_cwd = os.getcwd()
try:
os.chdir(abs_builddir)