aboutsummaryrefslogtreecommitdiff
path: root/contrib/subversion/subversion
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/subversion/subversion')
-rw-r--r--contrib/subversion/subversion/include/private/svn_dep_compat.h11
-rw-r--r--contrib/subversion/subversion/include/private/svn_sorts_private.h10
-rw-r--r--contrib/subversion/subversion/include/svn_ra.h2
-rw-r--r--contrib/subversion/subversion/include/svn_types.h29
-rw-r--r--contrib/subversion/subversion/include/svn_version.h6
-rw-r--r--contrib/subversion/subversion/libsvn_client/merge.c40
-rw-r--r--contrib/subversion/subversion/libsvn_client/mergeinfo.h2
-rw-r--r--contrib/subversion/subversion/libsvn_client/mtcc.c3
-rw-r--r--contrib/subversion/subversion/libsvn_fs_fs/index.c2
-rw-r--r--contrib/subversion/subversion/libsvn_repos/authz.c31
-rw-r--r--contrib/subversion/subversion/libsvn_repos/config_file.c4
-rw-r--r--contrib/subversion/subversion/libsvn_subr/apr_escape.c135
-rw-r--r--contrib/subversion/subversion/libsvn_subr/cmdline.c101
-rw-r--r--contrib/subversion/subversion/libsvn_subr/iter.c26
-rw-r--r--contrib/subversion/subversion/libsvn_subr/opt.c2
-rw-r--r--contrib/subversion/subversion/libsvn_subr/version.c2
-rw-r--r--contrib/subversion/subversion/libsvn_wc/wc-metadata.h2
-rw-r--r--contrib/subversion/subversion/libsvn_wc/wc-metadata.sql2
-rw-r--r--contrib/subversion/subversion/libsvn_wc/wc-queries.h2
-rw-r--r--contrib/subversion/subversion/svn/cl-conflicts.c6
-rw-r--r--contrib/subversion/subversion/svn/filesize.c57
21 files changed, 409 insertions, 66 deletions
diff --git a/contrib/subversion/subversion/include/private/svn_dep_compat.h b/contrib/subversion/subversion/include/private/svn_dep_compat.h
index 7e6603826135..9a2e49a19cba 100644
--- a/contrib/subversion/subversion/include/private/svn_dep_compat.h
+++ b/contrib/subversion/subversion/include/private/svn_dep_compat.h
@@ -29,6 +29,7 @@
#define SVN_DEP_COMPAT_H
#include <apr_version.h>
+#include <apr_errno.h>
#ifdef __cplusplus
extern "C" {
@@ -193,6 +194,16 @@ extern "C" {
((major*1000000 + minor*1000 + patch) <= SVN_SQLITE_MIN_VERSION_NUMBER)
#endif /* SQLITE_VERSION_AT_LEAST */
+/**
+ * Support for 'apr_escape_shell() which was introduced in APR 1.5.
+ */
+#if !APR_VERSION_AT_LEAST(1,5,0)
+/* from apr_escape.h */
+#define APR_ESCAPE_STRING (-1)
+APR_DECLARE(apr_status_t) apr_escape_shell(char *escaped, const char *str,
+ apr_ssize_t slen, apr_size_t *len);
+#endif
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/contrib/subversion/subversion/include/private/svn_sorts_private.h b/contrib/subversion/subversion/include/private/svn_sorts_private.h
index d0fddc0c6488..d11ebbe1a992 100644
--- a/contrib/subversion/subversion/include/private/svn_sorts_private.h
+++ b/contrib/subversion/subversion/include/private/svn_sorts_private.h
@@ -80,7 +80,7 @@ svn_sort__array(apr_array_header_t *array,
int (*comparison_func)(const void *,
const void *));
-/* Return the lowest index at which the element @a *key should be inserted into
+/** Return the lowest index at which the element @a *key should be inserted into
* the array @a array, according to the ordering defined by @a compare_func.
* The array must already be sorted in the ordering defined by @a compare_func.
* @a compare_func is defined as for the C stdlib function bsearch(); the
@@ -93,7 +93,7 @@ svn_sort__bsearch_lower_bound(const apr_array_header_t *array,
const void *key,
int (*compare_func)(const void *, const void *));
-/* Find the lowest index at which the element @a *key should be inserted into
+/** Find the lowest index at which the element @a *key should be inserted into
* the array @a array, according to the ordering defined by @a compare_func.
* The array must already be sorted in the ordering defined by @a compare_func.
* @a compare_func is defined as for the C stdlib function bsearch(); the
@@ -116,7 +116,7 @@ svn_sort__array_lookup(const apr_array_header_t *array,
int (*compare_func)(const void *, const void *));
-/* Insert a shallow copy of @a *new_element into the array @a array at the index
+/** Insert a shallow copy of @a *new_element into the array @a array at the index
* @a insert_index, growing the array and shuffling existing elements along to
* make room.
*
@@ -131,7 +131,7 @@ svn_sort__array_insert2(apr_array_header_t *array,
int insert_index);
-/* Remove @a elements_to_delete elements starting at @a delete_index from the
+/** Remove @a elements_to_delete elements starting at @a delete_index from the
* array @a arr.
*
* Raise an error if the indexes to delete extends outside the array bounds
@@ -144,7 +144,7 @@ svn_sort__array_delete2(apr_array_header_t *arr,
int delete_index,
int elements_to_delete);
-/* Reverse the order of elements in @a array, in place.
+/** Reverse the order of elements in @a array, in place.
*
* @note Private. For use by Subversion's own code only.
*/
diff --git a/contrib/subversion/subversion/include/svn_ra.h b/contrib/subversion/subversion/include/svn_ra.h
index 4c71520dd1ff..d534ab70caa1 100644
--- a/contrib/subversion/subversion/include/svn_ra.h
+++ b/contrib/subversion/subversion/include/svn_ra.h
@@ -2244,7 +2244,7 @@ svn_ra_has_capability(svn_ra_session_t *session,
/**
* The capability of a server to automatically remove transaction
- * properties prefixed with SVN_PROP_EPHEMERAL_PREFIX.
+ * properties prefixed with #SVN_PROP_TXN_PREFIX.
*
* @since New in 1.8.
*/
diff --git a/contrib/subversion/subversion/include/svn_types.h b/contrib/subversion/subversion/include/svn_types.h
index 418d6ac9cc84..d9f98f23150a 100644
--- a/contrib/subversion/subversion/include/svn_types.h
+++ b/contrib/subversion/subversion/include/svn_types.h
@@ -249,6 +249,35 @@ typedef struct svn_version_t svn_version_t;
+/** @defgroup apr_hash_utilities APR Hash Table Helpers
+ * These functions enable the caller to dereference an APR hash table index
+ * without type casts or temporary variables.
+ *
+ * These functions are provided by APR itself from version 1.5.
+ * Definitions are provided here for when using older versions of APR.
+ * @{
+ */
+
+#if !APR_VERSION_AT_LEAST(1, 5, 0)
+
+/** Return the key of the hash table entry indexed by @a hi. */
+const void *
+apr_hash_this_key(apr_hash_index_t *hi);
+
+/** Return the key length of the hash table entry indexed by @a hi. */
+apr_ssize_t
+apr_hash_this_key_len(apr_hash_index_t *hi);
+
+/** Return the value of the hash table entry indexed by @a hi. */
+void *
+apr_hash_this_val(apr_hash_index_t *hi);
+
+#endif
+
+/** @} */
+
+
+
/** On Windows, APR_STATUS_IS_ENOTDIR includes several kinds of
* invalid-pathname error but not ERROR_INVALID_NAME, so we include it.
* We also include ERROR_DIRECTORY as that was not included in apr versions
diff --git a/contrib/subversion/subversion/include/svn_version.h b/contrib/subversion/subversion/include/svn_version.h
index 25bbe542df5b..69e886cc5437 100644
--- a/contrib/subversion/subversion/include/svn_version.h
+++ b/contrib/subversion/subversion/include/svn_version.h
@@ -70,7 +70,7 @@ extern "C" {
*
* @since New in 1.1.
*/
-#define SVN_VER_PATCH 0
+#define SVN_VER_PATCH 1
/** @deprecated Provided for backward compatibility with the 1.0 API. */
@@ -93,7 +93,7 @@ extern "C" {
*
* Always change this at the same time as SVN_VER_NUMTAG.
*/
-#define SVN_VER_TAG " (r1876290)"
+#define SVN_VER_TAG " (r1886195)"
/** Number tag: a string describing the version.
@@ -117,7 +117,7 @@ extern "C" {
* file version. Its value remains 0 in the repository except in release
* tags where it is the revision from which the tag was created.
*/
-#define SVN_VER_REVISION 1876290
+#define SVN_VER_REVISION 1886195
/* Version strings composed from the above definitions. */
diff --git a/contrib/subversion/subversion/libsvn_client/merge.c b/contrib/subversion/subversion/libsvn_client/merge.c
index 9d9a1c300a10..e535647d8649 100644
--- a/contrib/subversion/subversion/libsvn_client/merge.c
+++ b/contrib/subversion/subversion/libsvn_client/merge.c
@@ -264,7 +264,7 @@ typedef struct merge_cmd_baton_t {
/* Reference to the one-and-only CHILDREN_WITH_MERGEINFO (see global
comment) or a similar list for single-file-merges */
- const apr_array_header_t *children_with_mergeinfo;
+ apr_array_header_t *children_with_mergeinfo;
svn_client_ctx_t *ctx; /* Client context for callbacks, etc. */
@@ -1545,6 +1545,25 @@ record_update_delete(merge_cmd_baton_t *merge_b,
svn_node_kind_to_word(kind));
}
+ /* Note in children_with_mergeinfo that all paths in this subtree are
+ * being deleted, to avoid trying to set mergeinfo on them later. */
+ if (merge_b->children_with_mergeinfo)
+ {
+ int i;
+
+ for (i = 0; i < merge_b->children_with_mergeinfo->nelts; i++)
+ {
+ svn_client__merge_path_t *child
+ = APR_ARRAY_IDX(merge_b->children_with_mergeinfo, i,
+ svn_client__merge_path_t *);
+
+ if (svn_dirent_is_ancestor(local_abspath, child->abspath))
+ {
+ SVN_ERR(svn_sort__array_delete2(merge_b->children_with_mergeinfo, i--, 1));
+ }
+ }
+ }
+
return SVN_NO_ERROR;
}
@@ -5595,7 +5614,7 @@ svn_client__make_merge_conflict_error(svn_client__conflict_report_t *report,
with paths (svn_client__merge_path_t *) arranged in depth first order,
which have mergeinfo set on them or meet one of the other criteria
defined in get_mergeinfo_paths(). Remove any paths absent from disk
- or scheduled for deletion from CHILDREN_WITH_MERGEINFO which are equal to
+ from CHILDREN_WITH_MERGEINFO which are equal to
or are descendants of TARGET_WCPATH by setting those children to NULL. */
static svn_error_t *
remove_absent_children(const char *target_wcpath,
@@ -5609,7 +5628,7 @@ remove_absent_children(const char *target_wcpath,
{
svn_client__merge_path_t *child =
APR_ARRAY_IDX(children_with_mergeinfo, i, svn_client__merge_path_t *);
- if ((child->absent || child->scheduled_for_deletion)
+ if (child->absent
&& svn_dirent_is_ancestor(target_wcpath, child->abspath))
{
SVN_ERR(svn_sort__array_delete2(children_with_mergeinfo, i--, 1));
@@ -7896,18 +7915,23 @@ process_children_with_new_mergeinfo(merge_cmd_baton_t *merge_b,
apr_pool_t *pool)
{
apr_pool_t *iterpool;
- apr_hash_index_t *hi;
+ apr_array_header_t *a;
+ int i;
if (!merge_b->paths_with_new_mergeinfo || merge_b->dry_run)
return SVN_NO_ERROR;
/* Iterate over each path with explicit mergeinfo added by the merge. */
+ /* Iterate over the paths in a parent-to-child order so that inherited
+ * mergeinfo is propagated consistently from each parent path to its
+ * children. (Issue #4862) */
+ a = svn_sort__hash(merge_b->paths_with_new_mergeinfo,
+ svn_sort_compare_items_as_paths, pool);
iterpool = svn_pool_create(pool);
- for (hi = apr_hash_first(pool, merge_b->paths_with_new_mergeinfo);
- hi;
- hi = apr_hash_next(hi))
+ for (i = 0; i < a->nelts; i++)
{
- const char *abspath_with_new_mergeinfo = apr_hash_this_key(hi);
+ svn_sort__item_t *item = &APR_ARRAY_IDX(a, i, svn_sort__item_t);
+ const char *abspath_with_new_mergeinfo = item->key;
svn_mergeinfo_t path_inherited_mergeinfo;
svn_mergeinfo_t path_explicit_mergeinfo;
svn_client__merge_path_t *new_child;
diff --git a/contrib/subversion/subversion/libsvn_client/mergeinfo.h b/contrib/subversion/subversion/libsvn_client/mergeinfo.h
index 1d6d524f5dd2..99e1bf9f80c7 100644
--- a/contrib/subversion/subversion/libsvn_client/mergeinfo.h
+++ b/contrib/subversion/subversion/libsvn_client/mergeinfo.h
@@ -74,8 +74,6 @@ typedef struct svn_client__merge_path_t
prior to a merge. May be NULL. */
svn_boolean_t inherited_mergeinfo; /* Whether PRE_MERGE_MERGEINFO was
explicit or inherited. */
- svn_boolean_t scheduled_for_deletion; /* ABSPATH is scheduled for
- deletion. */
svn_boolean_t immediate_child_dir; /* ABSPATH is an immediate child
directory of the merge target,
has no explicit mergeinfo prior
diff --git a/contrib/subversion/subversion/libsvn_client/mtcc.c b/contrib/subversion/subversion/libsvn_client/mtcc.c
index 48ddcccbc164..a7c86a49a472 100644
--- a/contrib/subversion/subversion/libsvn_client/mtcc.c
+++ b/contrib/subversion/subversion/libsvn_client/mtcc.c
@@ -453,7 +453,8 @@ mtcc_verify_create(svn_client__mtcc_t *mtcc,
if (op)
return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
- _("Path '%s' already exists"),
+ _("Path '%s' already exists, or was created "
+ "by an earlier operation"),
new_relpath);
SVN_ERR(mtcc_op_find(&op, NULL, new_relpath, mtcc->root_op, TRUE, TRUE,
diff --git a/contrib/subversion/subversion/libsvn_fs_fs/index.c b/contrib/subversion/subversion/libsvn_fs_fs/index.c
index b7ba79f96313..168022e63eb3 100644
--- a/contrib/subversion/subversion/libsvn_fs_fs/index.c
+++ b/contrib/subversion/subversion/libsvn_fs_fs/index.c
@@ -827,7 +827,7 @@ svn_fs_fs__l2p_index_append(svn_checksum_t **checksum,
&eof, local_pool));
/* handle new revision */
- if ((entry > 0 && proto_entry.offset == 0) || eof)
+ if (eof || (entry > 0 && proto_entry.offset == 0))
{
/* dump entries, grouped into pages */
diff --git a/contrib/subversion/subversion/libsvn_repos/authz.c b/contrib/subversion/subversion/libsvn_repos/authz.c
index 9f8dbc5a08f7..0a47a0928638 100644
--- a/contrib/subversion/subversion/libsvn_repos/authz.c
+++ b/contrib/subversion/subversion/libsvn_repos/authz.c
@@ -889,9 +889,7 @@ create_user_authz(authz_full_t *authz,
/* Use a separate sub-pool to keep memory usage tight. */
apr_pool_t *subpool = svn_pool_create(scratch_pool);
- /* Find all ACLs for REPOSITORY.
- * Note that repo-specific rules replace global rules,
- * even if they don't apply to the current user. */
+ /* Find all ACLs for REPOSITORY. */
apr_array_header_t *acls = apr_array_make(subpool, authz->acls->nelts,
sizeof(authz_acl_t *));
for (i = 0; i < authz->acls->nelts; ++i)
@@ -908,15 +906,36 @@ create_user_authz(authz_full_t *authz,
= APR_ARRAY_IDX(acls, acls->nelts - 1, const authz_acl_t *);
if (svn_authz__compare_paths(&prev_acl->rule, &acl->rule) == 0)
{
+ svn_boolean_t global_acl_applies;
+ svn_boolean_t repos_acl_applies;
+
+ /* Previous ACL is a global rule. */
SVN_ERR_ASSERT_NO_RETURN(!strcmp(prev_acl->rule.repos,
AUTHZ_ANY_REPOSITORY));
+ /* Current ACL is a per-repository rule. */
SVN_ERR_ASSERT_NO_RETURN(strcmp(acl->rule.repos,
AUTHZ_ANY_REPOSITORY));
- apr_array_pop(acls);
+
+ global_acl_applies =
+ svn_authz__get_acl_access(NULL, prev_acl, user, repository);
+ repos_acl_applies =
+ svn_authz__get_acl_access(NULL, acl, user, repository);
+
+ /* Prefer rules which apply to both this user and this path
+ * over rules which apply only to the path. In cases where
+ * both rules apply to user and path, always prefer the
+ * repository-specific rule. */
+ if (!global_acl_applies || repos_acl_applies)
+ {
+ apr_array_pop(acls);
+ APR_ARRAY_PUSH(acls, const authz_acl_t *) = acl;
+ }
}
+ else
+ APR_ARRAY_PUSH(acls, const authz_acl_t *) = acl;
}
-
- APR_ARRAY_PUSH(acls, const authz_acl_t *) = acl;
+ else
+ APR_ARRAY_PUSH(acls, const authz_acl_t *) = acl;
}
}
diff --git a/contrib/subversion/subversion/libsvn_repos/config_file.c b/contrib/subversion/subversion/libsvn_repos/config_file.c
index 4bec766e3dd5..31b9441ca0da 100644
--- a/contrib/subversion/subversion/libsvn_repos/config_file.c
+++ b/contrib/subversion/subversion/libsvn_repos/config_file.c
@@ -237,6 +237,10 @@ get_repos_config(svn_stream_t **stream,
{
/* Search for a repository in the full path. */
repos_root_dirent = svn_repos_find_root_path(dirent, scratch_pool);
+ if (repos_root_dirent == NULL)
+ return svn_error_trace(handle_missing_file(stream, checksum, access,
+ url, must_exist,
+ svn_node_none));
/* Attempt to open a repository at repos_root_dirent. */
SVN_ERR(svn_repos_open3(&access->repos, repos_root_dirent, NULL,
diff --git a/contrib/subversion/subversion/libsvn_subr/apr_escape.c b/contrib/subversion/subversion/libsvn_subr/apr_escape.c
new file mode 100644
index 000000000000..caa25d9fc573
--- /dev/null
+++ b/contrib/subversion/subversion/libsvn_subr/apr_escape.c
@@ -0,0 +1,135 @@
+/* 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.
+ */
+
+/* The code in this file is copied from APR (initially from APR 1.7.0)
+ * to provide compatibility for building against APR < 1.5.0.
+ */
+
+#include "private/svn_dep_compat.h"
+
+#if !APR_VERSION_AT_LEAST(1,5,0)
+
+#include <apr_lib.h>
+#include <apr_strings.h>
+
+/* from apr_escape_test_char.h */
+#define T_ESCAPE_SHELL_CMD (1)
+#define T_ESCAPE_PATH_SEGMENT (2)
+#define T_OS_ESCAPE_PATH (4)
+#define T_ESCAPE_ECHO (8)
+#define T_ESCAPE_URLENCODED (16)
+#define T_ESCAPE_XML (32)
+#define T_ESCAPE_LDAP_DN (64)
+#define T_ESCAPE_LDAP_FILTER (128)
+
+static const unsigned char test_char_table[256] = {
+ 224,222,222,222,222,222,222,222,222,222,223,222,222,222,222,222,222,222,222,222,
+ 222,222,222,222,222,222,222,222,222,222,222,222,6,16,127,22,17,22,49,17,
+ 145,145,129,80,80,0,0,18,0,0,0,0,0,0,0,0,0,0,16,87,
+ 119,16,119,23,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,23,223,23,23,0,23,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,23,23,23,17,222,222,222,222,222,222,222,222,222,222,222,222,222,
+ 222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+ 222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+ 222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+ 222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+ 222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+ 222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222
+};
+
+/* from apr_encode_private.h */
+#if APR_CHARSET_EBCDIC
+#error This Subversion compatibility code for APR<1.5 does not support EBCDIC.
+#else /* APR_CHARSET_EBCDIC */
+#define ENCODE_TO_ASCII(ch) (ch)
+#define ENCODE_TO_NATIVE(ch) (ch)
+#endif /* !APR_CHARSET_EBCDIC */
+
+/* we assume the folks using this ensure 0 <= c < 256... which means
+ * you need a cast to (unsigned char) first, you can't just plug a
+ * char in here and get it to work, because if char is signed then it
+ * will first be sign extended.
+ */
+#define TEST_CHAR(c, f) (test_char_table[(unsigned)(c)] & (f))
+
+APR_DECLARE(apr_status_t) apr_escape_shell(char *escaped, const char *str,
+ apr_ssize_t slen, apr_size_t *len)
+{
+ unsigned char *d;
+ const unsigned char *s;
+ apr_size_t size = 1;
+ int found = 0;
+
+ d = (unsigned char *) escaped;
+ s = (const unsigned char *) str;
+
+ if (s) {
+ if (d) {
+ for (; *s && slen; ++s, slen--) {
+#if defined(OS2) || defined(WIN32)
+ /*
+ * Newlines to Win32/OS2 CreateProcess() are ill advised.
+ * Convert them to spaces since they are effectively white
+ * space to most applications
+ */
+ if (*s == '\r' || *s == '\n') {
+ if (d) {
+ *d++ = ' ';
+ found = 1;
+ }
+ continue;
+ }
+#endif
+ if (TEST_CHAR(*s, T_ESCAPE_SHELL_CMD)) {
+ *d++ = '\\';
+ size++;
+ found = 1;
+ }
+ *d++ = *s;
+ size++;
+ }
+ *d = '\0';
+ }
+ else {
+ for (; *s && slen; ++s, slen--) {
+ if (TEST_CHAR(*s, T_ESCAPE_SHELL_CMD)) {
+ size++;
+ found = 1;
+ }
+ size++;
+ }
+ }
+ }
+
+ if (len) {
+ *len = size;
+ }
+ if (!found) {
+ return APR_NOTFOUND;
+ }
+
+ return APR_SUCCESS;
+}
+
+#else /* APR_VERSION_AT_LEAST(1,5,0) */
+
+/* Silence OSX ranlib warnings about object files with no symbols. */
+#include <apr.h>
+extern const apr_uint32_t svn__fake__apr_escape;
+const apr_uint32_t svn__fake__apr_escape = 0xdeadbeef;
+
+#endif /* !APR_VERSION_AT_LEAST(1,5,0) */
diff --git a/contrib/subversion/subversion/libsvn_subr/cmdline.c b/contrib/subversion/subversion/libsvn_subr/cmdline.c
index d1aad71b234a..bc27788ec03a 100644
--- a/contrib/subversion/subversion/libsvn_subr/cmdline.c
+++ b/contrib/subversion/subversion/libsvn_subr/cmdline.c
@@ -39,9 +39,15 @@
#include <apr.h> /* for STDIN_FILENO */
#include <apr_errno.h> /* for apr_strerror */
+#include <apr_version.h>
+#if APR_VERSION_AT_LEAST(1,5,0)
#include <apr_escape.h>
+#else
+#include "private/svn_dep_compat.h"
+#endif
#include <apr_general.h> /* for apr_initialize/apr_terminate */
#include <apr_strings.h> /* for apr_snprintf */
+#include <apr_env.h> /* for apr_env_get */
#include <apr_pools.h>
#include <apr_signal.h>
@@ -1235,38 +1241,84 @@ svn_cmdline__be_interactive(svn_boolean_t non_interactive,
/* Helper for the edit_externally functions. Set *EDITOR to some path to an
- editor binary. Sources to search include: the EDITOR_CMD argument
- (if not NULL), $SVN_EDITOR, the runtime CONFIG variable (if CONFIG
+ editor binary, in native C string on Unix/Linux platforms and in UTF-8
+ string on Windows platform. Sources to search include: the EDITOR_CMD
+ argument (if not NULL), $SVN_EDITOR, the runtime CONFIG variable (if CONFIG
is not NULL), $VISUAL, $EDITOR. Return
SVN_ERR_CL_NO_EXTERNAL_EDITOR if no binary can be found. */
static svn_error_t *
find_editor_binary(const char **editor,
const char *editor_cmd,
- apr_hash_t *config)
+ apr_hash_t *config,
+ apr_pool_t *pool)
{
const char *e;
+ const char *e_cfg;
struct svn_config_t *cfg;
+ apr_status_t status;
/* Use the editor specified on the command line via --editor-cmd, if any. */
+#ifdef WIN32
+ /* On Windows, editor_cmd is transcoded to the system active code page
+ because we use main() as a entry point without APR's (or our own) wrapper
+ in command line tools. */
+ if (editor_cmd)
+ {
+ SVN_ERR(svn_utf_cstring_to_utf8(&e, editor_cmd, pool));
+ }
+ else
+ {
+ e = NULL;
+ }
+#else
e = editor_cmd;
+#endif
/* Otherwise look for the Subversion-specific environment variable. */
if (! e)
- e = getenv("SVN_EDITOR");
+ {
+ status = apr_env_get((char **)&e, "SVN_EDITOR", pool);
+ if (status || ! *e)
+ {
+ e = NULL;
+ }
+ }
/* If not found then fall back on the config file. */
if (! e)
{
cfg = config ? svn_hash_gets(config, SVN_CONFIG_CATEGORY_CONFIG) : NULL;
- svn_config_get(cfg, &e, SVN_CONFIG_SECTION_HELPERS,
+ svn_config_get(cfg, &e_cfg, SVN_CONFIG_SECTION_HELPERS,
SVN_CONFIG_OPTION_EDITOR_CMD, NULL);
+#ifdef WIN32
+ if (e_cfg)
+ {
+ /* On Windows, we assume that config values are set in system active
+ code page, so we need transcode it here. */
+ SVN_ERR(svn_utf_cstring_to_utf8(&e, e_cfg, pool));
+ }
+#else
+ e = e_cfg;
+#endif
}
/* If not found yet then try general purpose environment variables. */
if (! e)
- e = getenv("VISUAL");
+ {
+ status = apr_env_get((char**)&e, "VISUAL", pool);
+ if (status || ! *e)
+ {
+ e = NULL;
+ }
+ }
if (! e)
- e = getenv("EDITOR");
+ {
+ status = apr_env_get((char**)&e, "EDITOR", pool);
+ if (status || ! *e)
+ {
+ e = NULL;
+ }
+ }
#ifdef SVN_CLIENT_EDITOR
/* If still not found then fall back on the hard-coded default. */
@@ -1400,13 +1452,17 @@ svn_cmdline__edit_file_externally(const char *path,
apr_pool_t *pool)
{
const char *editor, *cmd, *base_dir, *file_name, *base_dir_apr;
+ const char *file_name_local;
+#ifdef WIN32
+ const WCHAR *wcmd;
+#endif
char *old_cwd;
int sys_err;
apr_status_t apr_err;
svn_dirent_split(&base_dir, &file_name, path, pool);
- SVN_ERR(find_editor_binary(&editor, editor_cmd, config));
+ SVN_ERR(find_editor_binary(&editor, editor_cmd, config, pool));
apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
if (apr_err)
@@ -1423,10 +1479,18 @@ svn_cmdline__edit_file_externally(const char *path,
return svn_error_wrap_apr
(apr_err, _("Can't change working directory to '%s'"), base_dir);
+ SVN_ERR(svn_path_cstring_from_utf8(&file_name_local,
+ escape_path(pool, file_name), pool));
/* editor is explicitly documented as being interpreted by the user's shell,
and as such should already be quoted/escaped as needed. */
- cmd = apr_psprintf(pool, "%s %s", editor, escape_path(pool, file_name));
+#ifndef WIN32
+ cmd = apr_psprintf(pool, "%s %s", editor, file_name_local);
sys_err = system(cmd);
+#else
+ cmd = apr_psprintf(pool, "\"%s %s\"", editor, file_name_local);
+ SVN_ERR(svn_utf__win32_utf8_to_utf16(&wcmd, cmd, NULL, pool));
+ sys_err = _wsystem(wcmd);
+#endif
apr_err = apr_filepath_set(old_cwd, pool);
if (apr_err)
@@ -1458,6 +1522,9 @@ svn_cmdline__edit_string_externally(svn_string_t **edited_contents /* UTF-8! */,
{
const char *editor;
const char *cmd;
+#ifdef WIN32
+ const WCHAR *wcmd;
+#endif
apr_file_t *tmp_file;
const char *tmpfile_name;
const char *tmpfile_native;
@@ -1471,7 +1538,7 @@ svn_cmdline__edit_string_externally(svn_string_t **edited_contents /* UTF-8! */,
int sys_err;
svn_boolean_t remove_file = TRUE;
- SVN_ERR(find_editor_binary(&editor, editor_cmd, config));
+ SVN_ERR(find_editor_binary(&editor, editor_cmd, config, pool));
/* Convert file contents from UTF-8/LF if desired. */
if (as_text)
@@ -1581,13 +1648,18 @@ svn_cmdline__edit_string_externally(svn_string_t **edited_contents /* UTF-8! */,
goto cleanup;
/* Prepare the editor command line. */
- err = svn_utf_cstring_from_utf8(&tmpfile_native, tmpfile_name, pool);
+ err = svn_utf_cstring_from_utf8(&tmpfile_native,
+ escape_path(pool, tmpfile_name), pool);
if (err)
goto cleanup;
/* editor is explicitly documented as being interpreted by the user's shell,
and as such should already be quoted/escaped as needed. */
- cmd = apr_psprintf(pool, "%s %s", editor, escape_path(pool, tmpfile_native));
+#ifndef WIN32
+ cmd = apr_psprintf(pool, "%s %s", editor, tmpfile_native);
+#else
+ cmd = apr_psprintf(pool, "\"%s %s\"", editor, tmpfile_native);
+#endif
/* If the caller wants us to leave the file around, return the path
of the file we'll use, and make a note not to destroy it. */
@@ -1598,7 +1670,12 @@ svn_cmdline__edit_string_externally(svn_string_t **edited_contents /* UTF-8! */,
}
/* Now, run the editor command line. */
+#ifndef WIN32
sys_err = system(cmd);
+#else
+ SVN_ERR(svn_utf__win32_utf8_to_utf16(&wcmd, cmd, NULL, pool));
+ sys_err = _wsystem(wcmd);
+#endif
if (sys_err != 0)
{
/* Extracting any meaning from sys_err is platform specific, so just
diff --git a/contrib/subversion/subversion/libsvn_subr/iter.c b/contrib/subversion/subversion/libsvn_subr/iter.c
index 6d04846e8378..1a303b511945 100644
--- a/contrib/subversion/subversion/libsvn_subr/iter.c
+++ b/contrib/subversion/subversion/libsvn_subr/iter.c
@@ -143,3 +143,29 @@ svn_iter__break(void)
{
return &internal_break_error;
}
+
+#if !APR_VERSION_AT_LEAST(1, 5, 0)
+const void *apr_hash_this_key(apr_hash_index_t *hi)
+{
+ const void *key;
+
+ apr_hash_this((apr_hash_index_t *)hi, &key, NULL, NULL);
+ return key;
+}
+
+apr_ssize_t apr_hash_this_key_len(apr_hash_index_t *hi)
+{
+ apr_ssize_t klen;
+
+ apr_hash_this((apr_hash_index_t *)hi, NULL, &klen, NULL);
+ return klen;
+}
+
+void *apr_hash_this_val(apr_hash_index_t *hi)
+{
+ void *val;
+
+ apr_hash_this((apr_hash_index_t *)hi, NULL, NULL, &val);
+ return val;
+}
+#endif
diff --git a/contrib/subversion/subversion/libsvn_subr/opt.c b/contrib/subversion/subversion/libsvn_subr/opt.c
index a7439f7235ea..dca71eaf6593 100644
--- a/contrib/subversion/subversion/libsvn_subr/opt.c
+++ b/contrib/subversion/subversion/libsvn_subr/opt.c
@@ -326,7 +326,7 @@ print_command_info3(const svn_opt_subcommand_desc3_t *cmd,
}
}
- if (!verbose)
+ if (!verbose && global_options && *global_options)
SVN_ERR(svn_cmdline_fputs(_("\n(Use '-v' to show global and experimental options.)\n"),
stream, pool));
if (have_options)
diff --git a/contrib/subversion/subversion/libsvn_subr/version.c b/contrib/subversion/subversion/libsvn_subr/version.c
index 4cbbe2d7199d..1131b1ec0fb6 100644
--- a/contrib/subversion/subversion/libsvn_subr/version.c
+++ b/contrib/subversion/subversion/libsvn_subr/version.c
@@ -143,7 +143,7 @@ svn_version_extended(svn_boolean_t verbose,
info->build_time = NULL;
info->build_host = SVN_BUILD_HOST;
info->copyright = apr_pstrdup
- (pool, _("Copyright (C) 2020 The Apache Software Foundation.\n"
+ (pool, _("Copyright (C) 2021 The Apache Software Foundation.\n"
"This software consists of contributions made by many people;\n"
"see the NOTICE file for more information.\n"
"Subversion is open source software, see "
diff --git a/contrib/subversion/subversion/libsvn_wc/wc-metadata.h b/contrib/subversion/subversion/libsvn_wc/wc-metadata.h
index 75e7503c3f3f..b0f72dfaec99 100644
--- a/contrib/subversion/subversion/libsvn_wc/wc-metadata.h
+++ b/contrib/subversion/subversion/libsvn_wc/wc-metadata.h
@@ -177,7 +177,7 @@
"CREATE UNIQUE INDEX IF NOT EXISTS I_NODES_MOVED " \
"ON NODES (wc_id, moved_to, op_depth); " \
"CREATE INDEX IF NOT EXISTS I_PRISTINE_MD5 ON PRISTINE (md5_checksum); " \
- "UPDATE nodes SET presence = \"server-excluded\" WHERE presence = \"absent\"; " \
+ "UPDATE nodes SET presence = 'server-excluded' WHERE presence = 'absent'; " \
"UPDATE nodes SET file_external=1 WHERE file_external IS NOT NULL; " \
""
diff --git a/contrib/subversion/subversion/libsvn_wc/wc-metadata.sql b/contrib/subversion/subversion/libsvn_wc/wc-metadata.sql
index e34cf1422e60..5dd7294f3694 100644
--- a/contrib/subversion/subversion/libsvn_wc/wc-metadata.sql
+++ b/contrib/subversion/subversion/libsvn_wc/wc-metadata.sql
@@ -636,7 +636,7 @@ ON NODES (wc_id, moved_to, op_depth);
CREATE INDEX IF NOT EXISTS I_PRISTINE_MD5 ON PRISTINE (md5_checksum);
-UPDATE nodes SET presence = "server-excluded" WHERE presence = "absent";
+UPDATE nodes SET presence = 'server-excluded' WHERE presence = 'absent';
/* Just to be sure clear out file external skels from pre 1.7.0 development
working copies that were never updated by 1.7.0+ style clients */
diff --git a/contrib/subversion/subversion/libsvn_wc/wc-queries.h b/contrib/subversion/subversion/libsvn_wc/wc-queries.h
index b6254e1a5bca..778e679f4a43 100644
--- a/contrib/subversion/subversion/libsvn_wc/wc-queries.h
+++ b/contrib/subversion/subversion/libsvn_wc/wc-queries.h
@@ -2443,7 +2443,7 @@
"CREATE UNIQUE INDEX IF NOT EXISTS I_NODES_MOVED " \
"ON NODES (wc_id, moved_to, op_depth); " \
"CREATE INDEX IF NOT EXISTS I_PRISTINE_MD5 ON PRISTINE (md5_checksum); " \
- "UPDATE nodes SET presence = \"server-excluded\" WHERE presence = \"absent\"; " \
+ "UPDATE nodes SET presence = 'server-excluded' WHERE presence = 'absent'; " \
"UPDATE nodes SET file_external=1 WHERE file_external IS NOT NULL; " \
""
diff --git a/contrib/subversion/subversion/svn/cl-conflicts.c b/contrib/subversion/subversion/svn/cl-conflicts.c
index 0dc0abf29114..24a4607b62b7 100644
--- a/contrib/subversion/subversion/svn/cl-conflicts.c
+++ b/contrib/subversion/subversion/svn/cl-conflicts.c
@@ -452,7 +452,7 @@ append_tree_conflict_info_xml(svn_stringbuf_t *str,
repos_root_url, repos_relpath, peg_rev,
node_kind, pool));
- SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(&repos_relpath,
+ SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(&repos_relpath,
&peg_rev,
&node_kind,
conflict,
@@ -529,7 +529,7 @@ svn_cl__append_conflict_info_xml(svn_stringbuf_t *str,
repos_root_url, repos_relpath, peg_rev,
node_kind, scratch_pool));
- SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
+ SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
&repos_relpath, &peg_rev, &node_kind, conflict,
scratch_pool, scratch_pool));
if (repos_root_url && repos_relpath)
@@ -576,7 +576,7 @@ svn_cl__append_conflict_info_xml(svn_stringbuf_t *str,
repos_root_url, repos_relpath, peg_rev,
node_kind, scratch_pool));
- SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
+ SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
&repos_relpath, &peg_rev, &node_kind, conflict,
scratch_pool, scratch_pool));
if (repos_root_url && repos_relpath)
diff --git a/contrib/subversion/subversion/svn/filesize.c b/contrib/subversion/subversion/svn/filesize.c
index ba1c35626b61..c6e2bc40fd8d 100644
--- a/contrib/subversion/subversion/svn/filesize.c
+++ b/contrib/subversion/subversion/svn/filesize.c
@@ -88,15 +88,24 @@ format_size(double human_readable_size,
+ 1 nul terminator
---
= 5 characters of space needed in the buffer. */
- char buffer[8];
+ char buffer[64];
+
+ assert(absolute_human_readable_size < 1000);
+
+ /* When the adjusted size has only one significant digit left of
+ the decimal point, show tenths of a unit, too. Except when
+ the absolute size is actually a single-digit number, because
+ files can't have fractional byte sizes. */
+ if (absolute_human_readable_size >= 10)
+ sprintf(buffer, "%.0f", human_readable_size);
+ else
+ {
+ double integral;
+ const double frac = modf(absolute_human_readable_size, &integral);
+ const int decimals = (index > 0 && (integral < 9 || frac <= .949999999));
+ sprintf(buffer, "%.*f", decimals, human_readable_size);
+ }
- assert(absolute_human_readable_size < 1000.0);
-
- /* When the adjusted size has only one significant digit left of the
- decimal point, show tenths of a unit, too. */
- sprintf(buffer, "%.*f",
- absolute_human_readable_size < 10.0 ? 1 : 0,
- human_readable_size);
return apr_pstrcat(result_pool, buffer, suffix, SVN_VA_NULL);
}
@@ -138,8 +147,9 @@ get_base2_unit_file_size(svn_filesize_t size,
assert(index < order_size - 1);
++index;
}
+
human_readable_size = (index == 0 ? (double)size
- : (size >> 3 * index) / 128.0 / index);
+ : (size >> (10 * index - 10)) / 1024.0);
return format_size(human_readable_size,
long_units, order, index, result_pool);
@@ -160,7 +170,7 @@ get_base10_unit_file_size(svn_filesize_t size,
{APR_INT64_C( 999999999999), " TB", "T"}, /* tera */
{APR_INT64_C( 999999999999999), " EB", "E"}, /* exa */
{APR_INT64_C(999999999999999999), " PB", "P"} /* peta */
- /* 18446744073709551615 is the maximum value. */
+ /* 9223372036854775807 is the maximum value. */
};
static const apr_size_t order_size = sizeof(order) / sizeof(order[0]);
@@ -170,20 +180,29 @@ get_base10_unit_file_size(svn_filesize_t size,
/* Adjust the size to the given order of magnitude.
- This is division by (order[index].mask + 1), which is the base-1000
- magnitude of the size. For large file sizes, we split the operation
- into an integer and a floating-point division, so that we don't
+ This is division by (order[index].mask + 1), which is the
+ base-1000 magnitude of the size. We split the operation into an
+ integer and a floating-point division, so that we don't
overflow the mantissa. */
if (index == 0)
human_readable_size = (double)size;
- else if (index <= 3)
- human_readable_size = (double)size / (order[index].mask + 1);
else
{
- /* [ Keep integer division here! ] */
- const double divisor = (double)((order[index].mask + 1) / 1000000);
- human_readable_size = (size / 1000000) / divisor;
- /* [ And here! ] */
+ const svn_filesize_t divisor = (order[index - 1].mask + 1);
+ /* [Keep integer arithmetic here!] */
+ human_readable_size = (size / divisor) / 1000.0;
+ }
+
+ /* Adjust index and number for rounding. */
+ if (human_readable_size >= 999.5)
+ {
+ /* This assertion should never fail, because we only have one
+ decimal digit in the petabyte range and so the number of
+ petabytes can't be large enough to cause the program flow
+ to enter this conditional block. */
+ assert(index < order_size - 1);
+ human_readable_size /= 1000.0;
+ ++index;
}
return format_size(human_readable_size,