diff options
Diffstat (limited to 'contrib/subversion/subversion')
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, |