aboutsummaryrefslogtreecommitdiffstats
path: root/subversion
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2014-08-11 19:19:17 +0000
committerPeter Wemm <peter@FreeBSD.org>2014-08-11 19:19:17 +0000
commit6f0665939667af9f780762878fc35982e8b7d745 (patch)
tree7641ccc1b31a300b13c0cfcf8ab6c33e17646de1 /subversion
parent41a48a0a1803245a188068c5200383b9543c25b2 (diff)
downloadsrc-6f0665939667af9f780762878fc35982e8b7d745.tar.gz
src-6f0665939667af9f780762878fc35982e8b7d745.zip
Notes
Notes: svn path=/vendor/subversion/dist/; revision=269829 svn path=/vendor/subversion/subversion-1.8.10/; revision=269830; tag=vendor/subversion/subversion-1.8.10
Diffstat (limited to 'subversion')
-rw-r--r--subversion/include/private/svn_cert.h68
-rw-r--r--subversion/include/svn_version.h6
-rw-r--r--subversion/libsvn_client/delete.c7
-rw-r--r--subversion/libsvn_client/externals.c23
-rw-r--r--subversion/libsvn_fs_fs/fs_fs.c7
-rw-r--r--subversion/libsvn_fs_fs/rep-cache-db.h2
-rw-r--r--subversion/libsvn_ra_serf/commit.c185
-rw-r--r--subversion/libsvn_ra_serf/options.c2
-rw-r--r--subversion/libsvn_ra_serf/util.c57
-rw-r--r--subversion/libsvn_subr/config_auth.c6
-rw-r--r--subversion/libsvn_subr/dirent_uri.c79
-rw-r--r--subversion/libsvn_subr/internal_statements.h2
-rw-r--r--subversion/libsvn_subr/opt.c4
-rw-r--r--subversion/libsvn_wc/wc-checks.h2
-rw-r--r--subversion/libsvn_wc/wc-metadata.h2
-rw-r--r--subversion/libsvn_wc/wc-queries.h2
-rw-r--r--subversion/libsvn_wc/wc_db.c22
17 files changed, 357 insertions, 119 deletions
diff --git a/subversion/include/private/svn_cert.h b/subversion/include/private/svn_cert.h
new file mode 100644
index 000000000000..32e32a01f7d9
--- /dev/null
+++ b/subversion/include/private/svn_cert.h
@@ -0,0 +1,68 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file svn_cert.h
+ * @brief Implementation of certificate validation functions
+ */
+
+#ifndef SVN_CERT_H
+#define SVN_CERT_H
+
+#include <apr.h>
+
+#include "svn_types.h"
+#include "svn_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Return TRUE iff @a pattern matches @a hostname as defined
+ * by the matching rules of RFC 6125. In the context of RFC
+ * 6125 the pattern is the domain name portion of the presented
+ * identifier (which comes from the Common Name or a DNSName
+ * portion of the subjectAltName of an X.509 certificate) and
+ * the hostname is the source domain (i.e. the host portion
+ * of the URI the user entered).
+ *
+ * @note With respect to wildcards we only support matching
+ * wildcards in the left-most label and as the only character
+ * in the left-most label (i.e. we support RFC 6125 ยง 6.4.3
+ * Rule 1 and 2 but not the optional Rule 3). This may change
+ * in the future.
+ *
+ * @note Subversion does not at current support internationalized
+ * domain names. Both values are presumed to be in NR-LDH label
+ * or A-label form (see RFC 5890 for the definition).
+ *
+ * @since New in 1.9.
+ */
+svn_boolean_t
+svn_cert__match_dns_identity(svn_string_t *pattern, svn_string_t *hostname);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SVN_CERT_H */
diff --git a/subversion/include/svn_version.h b/subversion/include/svn_version.h
index ee97c88a2f05..8788fa56ea0a 100644
--- a/subversion/include/svn_version.h
+++ b/subversion/include/svn_version.h
@@ -72,7 +72,7 @@ extern "C" {
*
* @since New in 1.1.
*/
-#define SVN_VER_PATCH 9
+#define SVN_VER_PATCH 10
/** @deprecated Provided for backward compatibility with the 1.0 API. */
@@ -95,7 +95,7 @@ extern "C" {
*
* Always change this at the same time as SVN_VER_NUMTAG.
*/
-#define SVN_VER_TAG " (r1591380)"
+#define SVN_VER_TAG " (r1615264)"
/** Number tag: a string describing the version.
@@ -121,7 +121,7 @@ extern "C" {
* When rolling a tarball, we automatically replace it with what we
* guess to be the correct revision number.
*/
-#define SVN_VER_REVISION 1591380
+#define SVN_VER_REVISION 1615264
/* Version strings composed from the above definitions. */
diff --git a/subversion/libsvn_client/delete.c b/subversion/libsvn_client/delete.c
index 2f4ee664f335..803b70c1fb23 100644
--- a/subversion/libsvn_client/delete.c
+++ b/subversion/libsvn_client/delete.c
@@ -193,7 +193,7 @@ path_driver_cb_func(void **dir_baton,
static svn_error_t *
single_repos_delete(svn_ra_session_t *ra_session,
- const char *repos_root,
+ const char *base_uri,
const apr_array_header_t *relpaths,
const apr_hash_t *revprop_table,
svn_commit_callback2_t commit_callback,
@@ -221,7 +221,7 @@ single_repos_delete(svn_ra_session_t *ra_session,
const char *relpath = APR_ARRAY_IDX(relpaths, i, const char *);
item = svn_client_commit_item3_create(pool);
- item->url = svn_path_url_add_component2(repos_root, relpath, pool);
+ item->url = svn_path_url_add_component2(base_uri, relpath, pool);
item->state_flags = SVN_CLIENT_COMMIT_ITEM_DELETE;
APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
}
@@ -361,7 +361,6 @@ delete_urls_multi_repos(const apr_array_header_t *uris,
iterpool = svn_pool_create(pool);
for (hi = apr_hash_first(pool, deletables); hi; hi = apr_hash_next(hi))
{
- const char *repos_root = svn__apr_hash_index_key(hi);
struct repos_deletables_t *repos_deletables = svn__apr_hash_index_val(hi);
const char *base_uri;
apr_array_header_t *target_relpaths;
@@ -398,7 +397,7 @@ delete_urls_multi_repos(const apr_array_header_t *uris,
}
SVN_ERR(svn_ra_reparent(repos_deletables->ra_session, base_uri, pool));
- SVN_ERR(single_repos_delete(repos_deletables->ra_session, repos_root,
+ SVN_ERR(single_repos_delete(repos_deletables->ra_session, base_uri,
target_relpaths,
revprop_table, commit_callback,
commit_baton, ctx, iterpool));
diff --git a/subversion/libsvn_client/externals.c b/subversion/libsvn_client/externals.c
index e572dc7b3f00..8c08f405279e 100644
--- a/subversion/libsvn_client/externals.c
+++ b/subversion/libsvn_client/externals.c
@@ -1017,19 +1017,30 @@ svn_client__handle_externals(apr_hash_t *externals_new,
parent_abspath = svn_dirent_dirname(parent_abspath, iterpool);
SVN_ERR(svn_wc_read_kind2(&kind, ctx->wc_ctx, parent_abspath,
- TRUE, FALSE, iterpool));
+ FALSE /* show_deleted*/,
+ FALSE /* show_hidden */,
+ iterpool));
if (kind == svn_node_none)
{
svn_error_t *err;
err = svn_io_dir_remove_nonrecursive(parent_abspath, iterpool);
- if (err && APR_STATUS_IS_ENOTEMPTY(err->apr_err))
+ if (err)
{
- svn_error_clear(err);
- break;
+ if (APR_STATUS_IS_ENOTEMPTY(err->apr_err))
+ {
+ svn_error_clear(err);
+ break; /* No parents to delete */
+ }
+ else if (APR_STATUS_IS_ENOENT(err->apr_err)
+ || APR_STATUS_IS_ENOTDIR(err->apr_err))
+ {
+ svn_error_clear(err);
+ /* Fall through; parent dir might be unversioned */
+ }
+ else
+ return svn_error_trace(err);
}
- else
- SVN_ERR(err);
}
} while (strcmp(parent_abspath, defining_abspath) != 0);
}
diff --git a/subversion/libsvn_fs_fs/fs_fs.c b/subversion/libsvn_fs_fs/fs_fs.c
index 372455d2d735..89816a8bcb6f 100644
--- a/subversion/libsvn_fs_fs/fs_fs.c
+++ b/subversion/libsvn_fs_fs/fs_fs.c
@@ -8877,7 +8877,12 @@ svn_fs_fs__create(svn_fs_t *fs,
SVN_ERR(write_revision_zero(fs));
- SVN_ERR(write_config(fs, pool));
+ /* Create the fsfs.conf file if supported. Older server versions would
+ simply ignore the file but that might result in a different behavior
+ than with the later releases. Also, hotcopy would ignore, i.e. not
+ copy, a fsfs.conf with old formats. */
+ if (ffd->format >= SVN_FS_FS__MIN_CONFIG_FILE)
+ SVN_ERR(write_config(fs, pool));
SVN_ERR(read_config(ffd, fs->path, pool));
diff --git a/subversion/libsvn_fs_fs/rep-cache-db.h b/subversion/libsvn_fs_fs/rep-cache-db.h
index 5e1510784800..0c9b821fec4b 100644
--- a/subversion/libsvn_fs_fs/rep-cache-db.h
+++ b/subversion/libsvn_fs_fs/rep-cache-db.h
@@ -1,4 +1,4 @@
-/* This file is automatically generated from rep-cache-db.sql and .dist_sandbox/subversion-1.8.9/subversion/libsvn_fs_fs/token-map.h.
+/* This file is automatically generated from rep-cache-db.sql and .dist_sandbox/subversion-1.8.10/subversion/libsvn_fs_fs/token-map.h.
* Do not edit this file -- edit the source and rerun gen-make.py */
#define STMT_CREATE_SCHEMA 0
diff --git a/subversion/libsvn_ra_serf/commit.c b/subversion/libsvn_ra_serf/commit.c
index 4950ac48911a..1f9f1cc99f06 100644
--- a/subversion/libsvn_ra_serf/commit.c
+++ b/subversion/libsvn_ra_serf/commit.c
@@ -99,14 +99,11 @@ typedef struct proppatch_context_t {
} proppatch_context_t;
typedef struct delete_context_t {
- const char *path;
+ const char *relpath;
svn_revnum_t revision;
- const char *lock_token;
- apr_hash_t *lock_token_hash;
- svn_boolean_t keep_locks;
-
+ commit_context_t *commit;
} delete_context_t;
/* Represents a directory. */
@@ -149,7 +146,6 @@ typedef struct dir_context_t {
/* The checked-out working resource for this directory. May be NULL; if so
call checkout_dir() first. */
const char *working_url;
-
} dir_context_t;
/* Represents a file to be committed. */
@@ -1078,6 +1074,96 @@ setup_copy_file_headers(serf_bucket_t *headers,
}
static svn_error_t *
+setup_if_header_recursive(svn_boolean_t *added,
+ serf_bucket_t *headers,
+ commit_context_t *commit_ctx,
+ const char *rq_relpath,
+ apr_pool_t *pool)
+{
+ svn_stringbuf_t *sb = NULL;
+ apr_hash_index_t *hi;
+ apr_pool_t *iterpool = NULL;
+
+ if (!commit_ctx->lock_tokens)
+ {
+ *added = FALSE;
+ return SVN_NO_ERROR;
+ }
+
+ /* We try to create a directory, so within the Subversion world that
+ would imply that there is nothing here, but mod_dav_svn still sees
+ locks on the old nodes here as in DAV it is perfectly legal to lock
+ something that is not there...
+
+ Let's make mod_dav, mod_dav_svn and the DAV RFC happy by providing
+ the locks we know of with the request */
+
+ for (hi = apr_hash_first(pool, commit_ctx->lock_tokens);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *relpath = svn__apr_hash_index_key(hi);
+ apr_uri_t uri;
+
+ if (!svn_relpath_skip_ancestor(rq_relpath, relpath))
+ continue;
+ else if (svn_hash_gets(commit_ctx->deleted_entries, relpath))
+ {
+ /* When a path is already explicit deleted then its lock
+ will be removed by mod_dav. But mod_dav doesn't remove
+ locks on descendants */
+ continue;
+ }
+
+ if (!iterpool)
+ iterpool = svn_pool_create(pool);
+ else
+ svn_pool_clear(iterpool);
+
+ if (sb == NULL)
+ sb = svn_stringbuf_create("", pool);
+ else
+ svn_stringbuf_appendbyte(sb, ' ');
+
+ uri = commit_ctx->session->session_url;
+ uri.path = (char *)svn_path_url_add_component2(uri.path, relpath,
+ iterpool);
+
+ svn_stringbuf_appendbyte(sb, '<');
+ svn_stringbuf_appendcstr(sb, apr_uri_unparse(iterpool, &uri, 0));
+ svn_stringbuf_appendcstr(sb, "> (<");
+ svn_stringbuf_appendcstr(sb, svn__apr_hash_index_val(hi));
+ svn_stringbuf_appendcstr(sb, ">)");
+ }
+
+ if (iterpool)
+ svn_pool_destroy(iterpool);
+
+ if (sb)
+ {
+ serf_bucket_headers_set(headers, "If", sb->data);
+ *added = TRUE;
+ }
+ else
+ *added = FALSE;
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+setup_add_dir_common_headers(serf_bucket_t *headers,
+ void *baton,
+ apr_pool_t *pool)
+{
+ dir_context_t *dir = baton;
+ svn_boolean_t added;
+
+ return svn_error_trace(
+ setup_if_header_recursive(&added, headers, dir->commit, dir->relpath,
+ pool));
+}
+
+static svn_error_t *
setup_copy_dir_headers(serf_bucket_t *headers,
void *baton,
apr_pool_t *pool)
@@ -1109,7 +1195,7 @@ setup_copy_dir_headers(serf_bucket_t *headers,
/* Implicitly checkout this dir now. */
dir->working_url = apr_pstrdup(dir->pool, uri.path);
- return SVN_NO_ERROR;
+ return svn_error_trace(setup_add_dir_common_headers(headers, baton, pool));
}
static svn_error_t *
@@ -1117,54 +1203,22 @@ setup_delete_headers(serf_bucket_t *headers,
void *baton,
apr_pool_t *pool)
{
- delete_context_t *ctx = baton;
+ delete_context_t *del = baton;
+ svn_boolean_t added;
serf_bucket_headers_set(headers, SVN_DAV_VERSION_NAME_HEADER,
- apr_ltoa(pool, ctx->revision));
+ apr_ltoa(pool, del->revision));
- if (ctx->lock_token_hash)
- {
- ctx->lock_token = svn_hash_gets(ctx->lock_token_hash, ctx->path);
+ SVN_ERR(setup_if_header_recursive(&added, headers, del->commit,
+ del->relpath, pool));
- if (ctx->lock_token)
- {
- const char *token_header;
-
- token_header = apr_pstrcat(pool, "<", ctx->path, "> (<",
- ctx->lock_token, ">)", (char *)NULL);
-
- serf_bucket_headers_set(headers, "If", token_header);
-
- if (ctx->keep_locks)
- serf_bucket_headers_setn(headers, SVN_DAV_OPTIONS_HEADER,
- SVN_DAV_OPTION_KEEP_LOCKS);
- }
- }
+ if (added && del->commit->keep_locks)
+ serf_bucket_headers_setn(headers, SVN_DAV_OPTIONS_HEADER,
+ SVN_DAV_OPTION_KEEP_LOCKS);
return SVN_NO_ERROR;
}
-/* Implements svn_ra_serf__request_body_delegate_t */
-static svn_error_t *
-create_delete_body(serf_bucket_t **body_bkt,
- void *baton,
- serf_bucket_alloc_t *alloc,
- apr_pool_t *pool)
-{
- delete_context_t *ctx = baton;
- serf_bucket_t *body;
-
- body = serf_bucket_aggregate_create(alloc);
-
- svn_ra_serf__add_xml_header_buckets(body, alloc);
-
- svn_ra_serf__merge_lock_token_list(ctx->lock_token_hash, ctx->path,
- body, alloc, pool);
-
- *body_bkt = body;
- return SVN_NO_ERROR;
-}
-
/* Helper function to write the svndiff stream to temporary file. */
static svn_error_t *
svndiff_stream_write(void *file_baton,
@@ -1541,7 +1595,6 @@ delete_entry(const char *path,
delete_context_t *delete_ctx;
svn_ra_serf__handler_t *handler;
const char *delete_target;
- svn_error_t *err;
if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit))
{
@@ -1560,10 +1613,9 @@ delete_entry(const char *path,
/* DELETE our entry */
delete_ctx = apr_pcalloc(pool, sizeof(*delete_ctx));
- delete_ctx->path = apr_pstrdup(pool, path);
+ delete_ctx->relpath = apr_pstrdup(pool, path);
delete_ctx->revision = revision;
- delete_ctx->lock_token_hash = dir->commit->lock_tokens;
- delete_ctx->keep_locks = dir->commit->keep_locks;
+ delete_ctx->commit = dir->commit;
handler = apr_pcalloc(pool, sizeof(*handler));
handler->handler_pool = pool;
@@ -1579,30 +1631,7 @@ delete_entry(const char *path,
handler->method = "DELETE";
handler->path = delete_target;
- err = svn_ra_serf__context_run_one(handler, pool);
-
- if (err &&
- (err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN ||
- err->apr_err == SVN_ERR_FS_NO_LOCK_TOKEN ||
- err->apr_err == SVN_ERR_FS_LOCK_OWNER_MISMATCH ||
- err->apr_err == SVN_ERR_FS_PATH_ALREADY_LOCKED))
- {
- svn_error_clear(err);
-
- /* An error has been registered on the connection. Reset the thing
- so that we can use it again. */
- serf_connection_reset(handler->conn->conn);
-
- handler->body_delegate = create_delete_body;
- handler->body_delegate_baton = delete_ctx;
- handler->body_type = "text/xml";
-
- SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
- }
- else if (err)
- {
- return err;
- }
+ SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
/* 204 No Content: item successfully deleted */
if (handler->sline.code != 204)
@@ -1673,6 +1702,9 @@ add_directory(const char *path,
{
handler->method = "MKCOL";
handler->path = mkcol_target;
+
+ handler->header_delegate = setup_add_dir_common_headers;
+ handler->header_delegate_baton = dir;
}
else
{
@@ -2341,7 +2373,8 @@ svn_ra_serf__get_commit_editor(svn_ra_session_t *ra_session,
ctx->callback = callback;
ctx->callback_baton = callback_baton;
- ctx->lock_tokens = lock_tokens;
+ ctx->lock_tokens = (lock_tokens && apr_hash_count(lock_tokens))
+ ? lock_tokens : NULL;
ctx->keep_locks = keep_locks;
ctx->deleted_entries = apr_hash_make(ctx->pool);
diff --git a/subversion/libsvn_ra_serf/options.c b/subversion/libsvn_ra_serf/options.c
index a3c2fb95c881..f61ee87142c6 100644
--- a/subversion/libsvn_ra_serf/options.c
+++ b/subversion/libsvn_ra_serf/options.c
@@ -302,7 +302,7 @@ capabilities_headers_iterator_callback(void *baton,
/* May contain multiple values, separated by commas. */
int i;
apr_array_header_t *vals = svn_cstring_split(val, ",", TRUE,
- opt_ctx->pool);
+ session->pool);
for (i = 0; i < vals->nelts; i++)
{
diff --git a/subversion/libsvn_ra_serf/util.c b/subversion/libsvn_ra_serf/util.c
index 60fa3c44af17..8f6c1bb5d4fa 100644
--- a/subversion/libsvn_ra_serf/util.c
+++ b/subversion/libsvn_ra_serf/util.c
@@ -28,7 +28,6 @@
#define APR_WANT_STRFUNC
#include <apr.h>
#include <apr_want.h>
-#include <apr_fnmatch.h>
#include <serf.h>
#include <serf_bucket_types.h>
@@ -49,6 +48,7 @@
#include "private/svn_fspath.h"
#include "private/svn_subr_private.h"
#include "private/svn_auth_private.h"
+#include "private/svn_cert.h"
#include "ra_serf.h"
@@ -274,7 +274,6 @@ ssl_server_cert(void *baton, int failures,
apr_hash_t *subject = NULL;
apr_hash_t *serf_cert = NULL;
void *creds;
- int found_matching_hostname = 0;
svn_failures = (ssl_convert_serf_failures(failures)
| conn->server_cert_failures);
@@ -286,26 +285,37 @@ ssl_server_cert(void *baton, int failures,
### This should really be handled by serf, which should pass an error
for this case, but that has backwards compatibility issues. */
apr_array_header_t *san;
+ svn_boolean_t found_san_entry = FALSE;
+ svn_boolean_t found_matching_hostname = FALSE;
+ svn_string_t *actual_hostname =
+ svn_string_create(conn->session->session_url.hostname, scratch_pool);
serf_cert = serf_ssl_cert_certificate(cert, scratch_pool);
san = svn_hash_gets(serf_cert, "subjectAltName");
/* Try to find matching server name via subjectAltName first... */
- if (san) {
+ if (san)
+ {
int i;
- for (i = 0; i < san->nelts; i++) {
+ found_san_entry = san->nelts > 0;
+ for (i = 0; i < san->nelts; i++)
+ {
const char *s = APR_ARRAY_IDX(san, i, const char*);
- if (apr_fnmatch(s, conn->session->session_url.hostname,
- APR_FNM_PERIOD | APR_FNM_CASE_BLIND) == APR_SUCCESS)
- {
- found_matching_hostname = 1;
+ svn_string_t *cert_hostname = svn_string_create(s, scratch_pool);
+
+ if (svn_cert__match_dns_identity(cert_hostname, actual_hostname))
+ {
+ found_matching_hostname = TRUE;
break;
- }
- }
- }
+ }
+ }
+ }
- /* Match server certificate CN with the hostname of the server */
- if (!found_matching_hostname)
+ /* Match server certificate CN with the hostname of the server iff
+ * we didn't find any subjectAltName fields and try to match them.
+ * Per RFC 2818 they are authoritative if present and CommonName
+ * should be ignored. */
+ if (!found_matching_hostname && !found_san_entry)
{
const char *hostname = NULL;
@@ -314,13 +324,20 @@ ssl_server_cert(void *baton, int failures,
if (subject)
hostname = svn_hash_gets(subject, "CN");
- if (!hostname
- || apr_fnmatch(hostname, conn->session->session_url.hostname,
- APR_FNM_PERIOD | APR_FNM_CASE_BLIND) != APR_SUCCESS)
- {
- svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
- }
- }
+ if (hostname)
+ {
+ svn_string_t *cert_hostname = svn_string_create(hostname,
+ scratch_pool);
+
+ if (svn_cert__match_dns_identity(cert_hostname, actual_hostname))
+ {
+ found_matching_hostname = TRUE;
+ }
+ }
+ }
+
+ if (!found_matching_hostname)
+ svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
}
if (!svn_failures)
diff --git a/subversion/libsvn_subr/config_auth.c b/subversion/libsvn_subr/config_auth.c
index 091e4e84abcd..ed26a58cb362 100644
--- a/subversion/libsvn_subr/config_auth.c
+++ b/subversion/libsvn_subr/config_auth.c
@@ -94,6 +94,7 @@ svn_config_read_auth_data(apr_hash_t **hash,
if (kind == svn_node_file)
{
svn_stream_t *stream;
+ svn_string_t *stored_realm;
SVN_ERR_W(svn_stream_open_readonly(&stream, auth_path, pool, pool),
_("Unable to open auth file for reading"));
@@ -104,6 +105,11 @@ svn_config_read_auth_data(apr_hash_t **hash,
apr_psprintf(pool, _("Error parsing '%s'"),
svn_dirent_local_style(auth_path, pool)));
+ stored_realm = svn_hash_gets(*hash, SVN_CONFIG_REALMSTRING_KEY);
+
+ if (!stored_realm || strcmp(stored_realm->data, realmstring) != 0)
+ *hash = NULL; /* Hash collision, or somebody tampering with storage */
+
SVN_ERR(svn_stream_close(stream));
}
diff --git a/subversion/libsvn_subr/dirent_uri.c b/subversion/libsvn_subr/dirent_uri.c
index 4801f8c8e114..6886a3e7550e 100644
--- a/subversion/libsvn_subr/dirent_uri.c
+++ b/subversion/libsvn_subr/dirent_uri.c
@@ -38,6 +38,7 @@
#include "dirent_uri.h"
#include "private/svn_fspath.h"
+#include "private/svn_cert.h"
/* The canonical empty path. Can this be changed? Well, change the empty
test below and the path library will work, not so sure about the fs/wc
@@ -2597,3 +2598,81 @@ svn_urlpath__canonicalize(const char *uri,
}
return uri;
}
+
+
+/* -------------- The cert API (see private/svn_cert.h) ------------- */
+
+svn_boolean_t
+svn_cert__match_dns_identity(svn_string_t *pattern, svn_string_t *hostname)
+{
+ apr_size_t pattern_pos = 0, hostname_pos = 0;
+
+ /* support leading wildcards that composed of the only character in the
+ * left-most label. */
+ if (pattern->len >= 2 &&
+ pattern->data[pattern_pos] == '*' &&
+ pattern->data[pattern_pos + 1] == '.')
+ {
+ while (hostname_pos < hostname->len &&
+ hostname->data[hostname_pos] != '.')
+ {
+ hostname_pos++;
+ }
+ /* Assume that the wildcard must match something. Rule 2 says
+ * that *.example.com should not match example.com. If the wildcard
+ * ends up not matching anything then it matches .example.com which
+ * seems to be essentially the same as just example.com */
+ if (hostname_pos == 0)
+ return FALSE;
+
+ pattern_pos++;
+ }
+
+ while (pattern_pos < pattern->len && hostname_pos < hostname->len)
+ {
+ char pattern_c = pattern->data[pattern_pos];
+ char hostname_c = hostname->data[hostname_pos];
+
+ /* fold case as described in RFC 4343.
+ * Note: We actually convert to lowercase, since our URI
+ * canonicalization code converts to lowercase and generally
+ * most certs are issued with lowercase DNS names, meaning
+ * this avoids the fold operation in most cases. The RFC
+ * suggests the opposite transformation, but doesn't require
+ * any specific implementation in any case. It is critical
+ * that this folding be locale independent so you can't use
+ * tolower(). */
+ pattern_c = canonicalize_to_lower(pattern_c);
+ hostname_c = canonicalize_to_lower(hostname_c);
+
+ if (pattern_c != hostname_c)
+ {
+ /* doesn't match */
+ return FALSE;
+ }
+ else
+ {
+ /* characters match so skip both */
+ pattern_pos++;
+ hostname_pos++;
+ }
+ }
+
+ /* ignore a trailing period on the hostname since this has no effect on the
+ * security of the matching. See the following for the long explanation as
+ * to why:
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=134402#c28
+ */
+ if (pattern_pos == pattern->len &&
+ hostname_pos == hostname->len - 1 &&
+ hostname->data[hostname_pos] == '.')
+ hostname_pos++;
+
+ if (pattern_pos != pattern->len || hostname_pos != hostname->len)
+ {
+ /* end didn't match */
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/subversion/libsvn_subr/internal_statements.h b/subversion/libsvn_subr/internal_statements.h
index 4fa938932ecc..58616f4c450f 100644
--- a/subversion/libsvn_subr/internal_statements.h
+++ b/subversion/libsvn_subr/internal_statements.h
@@ -1,4 +1,4 @@
-/* This file is automatically generated from internal_statements.sql and .dist_sandbox/subversion-1.8.9/subversion/libsvn_subr/token-map.h.
+/* This file is automatically generated from internal_statements.sql and .dist_sandbox/subversion-1.8.10/subversion/libsvn_subr/token-map.h.
* Do not edit this file -- edit the source and rerun gen-make.py */
#define STMT_INTERNAL_SAVEPOINT_SVN 0
diff --git a/subversion/libsvn_subr/opt.c b/subversion/libsvn_subr/opt.c
index 28ffed178725..bfaa8b4f6c3e 100644
--- a/subversion/libsvn_subr/opt.c
+++ b/subversion/libsvn_subr/opt.c
@@ -417,7 +417,9 @@ svn_opt_subcommand_help3(const char *subcommand,
_("\"%s\": unknown command.\n\n"), subcommand);
if (err) {
- svn_handle_error2(err, stderr, FALSE, "svn: ");
+ /* Issue #3014: Don't print anything on broken pipes. */
+ if (err->apr_err != SVN_ERR_IO_PIPE_WRITE_ERROR)
+ svn_handle_error2(err, stderr, FALSE, "svn: ");
svn_error_clear(err);
}
}
diff --git a/subversion/libsvn_wc/wc-checks.h b/subversion/libsvn_wc/wc-checks.h
index 9fd40bd9fad9..43a006645426 100644
--- a/subversion/libsvn_wc/wc-checks.h
+++ b/subversion/libsvn_wc/wc-checks.h
@@ -1,4 +1,4 @@
-/* This file is automatically generated from wc-checks.sql and .dist_sandbox/subversion-1.8.9/subversion/libsvn_wc/token-map.h.
+/* This file is automatically generated from wc-checks.sql and .dist_sandbox/subversion-1.8.10/subversion/libsvn_wc/token-map.h.
* Do not edit this file -- edit the source and rerun gen-make.py */
#define STMT_VERIFICATION_TRIGGERS 0
diff --git a/subversion/libsvn_wc/wc-metadata.h b/subversion/libsvn_wc/wc-metadata.h
index e39db8ab6ba1..b24f24ff3fbc 100644
--- a/subversion/libsvn_wc/wc-metadata.h
+++ b/subversion/libsvn_wc/wc-metadata.h
@@ -1,4 +1,4 @@
-/* This file is automatically generated from wc-metadata.sql and .dist_sandbox/subversion-1.8.9/subversion/libsvn_wc/token-map.h.
+/* This file is automatically generated from wc-metadata.sql and .dist_sandbox/subversion-1.8.10/subversion/libsvn_wc/token-map.h.
* Do not edit this file -- edit the source and rerun gen-make.py */
#define STMT_CREATE_SCHEMA 0
diff --git a/subversion/libsvn_wc/wc-queries.h b/subversion/libsvn_wc/wc-queries.h
index 3fc6b2fe0f5f..2508bcf256e2 100644
--- a/subversion/libsvn_wc/wc-queries.h
+++ b/subversion/libsvn_wc/wc-queries.h
@@ -1,4 +1,4 @@
-/* This file is automatically generated from wc-queries.sql and .dist_sandbox/subversion-1.8.9/subversion/libsvn_wc/token-map.h.
+/* This file is automatically generated from wc-queries.sql and .dist_sandbox/subversion-1.8.10/subversion/libsvn_wc/token-map.h.
* Do not edit this file -- edit the source and rerun gen-make.py */
#define STMT_SELECT_NODE_INFO 0
diff --git a/subversion/libsvn_wc/wc_db.c b/subversion/libsvn_wc/wc_db.c
index 81056c9a4a6a..ed59d4cf6456 100644
--- a/subversion/libsvn_wc/wc_db.c
+++ b/subversion/libsvn_wc/wc_db.c
@@ -3815,8 +3815,15 @@ cross_db_copy(svn_wc__db_wcroot_t *src_wcroot,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
src_wcroot, src_relpath, scratch_pool, scratch_pool));
- SVN_ERR(db_read_pristine_props(&props, src_wcroot, src_relpath, FALSE,
- scratch_pool, scratch_pool));
+ if (dst_status != svn_wc__db_status_not_present
+ && dst_status != svn_wc__db_status_excluded
+ && dst_status != svn_wc__db_status_server_excluded)
+ {
+ SVN_ERR(db_read_pristine_props(&props, src_wcroot, src_relpath, FALSE,
+ scratch_pool, scratch_pool));
+ }
+ else
+ props = NULL;
blank_iwb(&iwb);
iwb.presence = dst_status;
@@ -5131,6 +5138,17 @@ db_op_copy_shadowed_layer(svn_wc__db_wcroot_t *src_wcroot,
scratch_pool));
}
+ if (dst_presence == svn_wc__db_status_not_present)
+ {
+ /* Don't create descendants of a not present node! */
+
+ /* This code is currently still triggered by copying deleted nodes
+ between separate working copies. See ### comment above. */
+
+ svn_pool_destroy(iterpool);
+ return SVN_NO_ERROR;
+ }
+
SVN_ERR(gather_repo_children(&children, src_wcroot, src_relpath,
src_op_depth, scratch_pool, iterpool));