Update subversion 1.9.5 -> 1.9.7
This includes a client-side fix for CVE-2017-9800.
This commit is contained in:
parent
20e07adbe0
commit
a24d3930d5
@ -1,3 +1,63 @@
|
||||
Version 1.9.7
|
||||
(10 Aug 2017, from /branches/1.9.x)
|
||||
http://svn.apache.org/repos/asf/subversion/tags/1.9.7
|
||||
|
||||
User-visible changes:
|
||||
- Client-side bugfixes:
|
||||
* Fix arbitrary code execution vulnerability CVE-2017-9800
|
||||
See <https://subversion.apache.org/security/CVE-2017-9800-advisory.txt>
|
||||
for details.
|
||||
|
||||
- Server-side bugfixes:
|
||||
(none)
|
||||
|
||||
- Bindings bugfixes:
|
||||
(none)
|
||||
|
||||
Developer-visible changes:
|
||||
- General:
|
||||
(none)
|
||||
|
||||
- API changes:
|
||||
(none)
|
||||
|
||||
|
||||
Version 1.9.6
|
||||
(5 Jul 2017, from /branches/1.9.x)
|
||||
http://svn.apache.org/repos/asf/subversion/tags/1.9.6
|
||||
|
||||
User-visible changes:
|
||||
- Client-side bugfixes:
|
||||
* cp/mv: improve error message when target is an unversioned dir (r1779948)
|
||||
* merge: reduce memory usage with large amounts of mergeinfo (issue #4667)
|
||||
|
||||
- Server-side bugfixes:
|
||||
* 'svnadmin freeze': document the purpose more clearly (r1774109)
|
||||
* dump: fix segfault when a revision has no revprops (r1781507)
|
||||
* fsfs: improve error message upon failure to open rep-cache (r1781655)
|
||||
* fsfs: never attempt to share directory representations (r1785053)
|
||||
* fsfs: make consistency independent of hash algorithms (r1785737 et al)
|
||||
This change makes Subversion resilient to collision attacks, including
|
||||
SHA-1 collision attacks such as <http://shattered.io/>. See also our
|
||||
documentation at <https://subversion.apache.org/faq#shattered-sha1> and
|
||||
<https://subversion.apache.org/docs/release-notes/1.9#shattered-sha1>.
|
||||
|
||||
- Client-side and server-side bugfixes:
|
||||
* work around an APR bug related to file truncation (r1759116)
|
||||
|
||||
- Bindings bugfixes:
|
||||
* javahl: follow redirects when opening a connection (r1667738, r1796720)
|
||||
|
||||
Developer-visible changes:
|
||||
- General:
|
||||
* win_tests.py: make the --bin option work, rather than abort (r1706432)
|
||||
(regression introduced in 1.9.2)
|
||||
* windows: support building with 'zlibstat.lib' in install-layout (r1783704)
|
||||
|
||||
- API changes:
|
||||
(none)
|
||||
|
||||
|
||||
Version 1.9.5
|
||||
(29 Nov 2016, from /branches/1.9.x)
|
||||
http://svn.apache.org/repos/asf/subversion/tags/1.9.5
|
||||
@ -19,7 +79,7 @@ http://svn.apache.org/repos/asf/subversion/tags/1.9.5
|
||||
* fsfs: fix "offset too large" error during pack (issue #4657)
|
||||
* svnserve: enable hook script environments (r1769152)
|
||||
* fsfs: fix possible data reconstruction error (issue #4658)
|
||||
* fix source of spurious 'incoming edit' tree conflicts (r1770108)
|
||||
* fix source of spurious 'incoming edit' tree conflicts (r1760570)
|
||||
* fsfs: improve caching for large directories (r1721285)
|
||||
* fsfs: fix crash when encountering all-zero checksums (r1759686)
|
||||
* fsfs: fix potential source of repository corruptions (r1756266)
|
||||
@ -34,19 +94,19 @@ http://svn.apache.org/repos/asf/subversion/tags/1.9.5
|
||||
|
||||
- Bindings bugfixes:
|
||||
* swig-pl: do not corrupt "{DATE}" revision variable (r1767768)
|
||||
* javahl: fix temporary accepting SSL server certificates (r1764851)
|
||||
* javahl: fix temporarily accepting SSL server certificates (r1764851)
|
||||
* swig-pl: fix possible stack corruption (r1683266, r1683267)
|
||||
|
||||
Developer-visible changes:
|
||||
- General:
|
||||
* add zlib discovery through pkg-config (issue #4655)
|
||||
* fix potential build issue with invalid SVN_LOCALE_DIR (issue #4653)
|
||||
* ruby: fix test failures with ruby >= 2.2 (r1766621)
|
||||
* fix link error with --disable-keychain on OS X (r1765385)
|
||||
* ruby: fix test failures with ruby >= 2.2 (r1766240)
|
||||
* fix link error with --disable-keychain on OS X (r1761755)
|
||||
* swig: enable building with SWIG >= 3.0.6 (r1721488 et al)
|
||||
* swig: fix building with -Wdate-time in $CPPFLAGS (r1722164)
|
||||
* update serf download URI in build scripts (r1700130 et al)
|
||||
* raise minimal httpd version from 2.0 to 2.2 (r1754193)
|
||||
* raise minimal httpd version from 2.0 to 2.2 (r1754190)
|
||||
|
||||
|
||||
Version 1.9.4
|
||||
@ -105,7 +165,6 @@ http://svn.apache.org/repos/asf/subversion/tags/1.9.3
|
||||
* svn: report lock/unlock errors as failures (r1701598 et al)
|
||||
* svn: cleanup user deleted external registrations (r1705843, r1710558)
|
||||
* svn: allow simple resolving of binary file text conflicts (r1703581)
|
||||
* svnlook: properly remove tempfiles on diff errors (r1711346)
|
||||
* ra_serf: report built- and run-time versions of libserf (r1704847)
|
||||
* ra_serf: set Content-Type header in outgoing requests (r1715224 et al)
|
||||
* svn: fix merging deletes of svn:eol-style CRLF/CR files (r1703689 et al)
|
||||
@ -118,6 +177,7 @@ http://svn.apache.org/repos/asf/subversion/tags/1.9.3
|
||||
* mod_dav_svn: use LimitXMLRequestBody for skel-encoded requests (r1687812)
|
||||
* svnadmin dump: preserve no-op changes (r1709388 et al, issue #4598)
|
||||
* fsfs: avoid unneeded I/O when opening transactions (r1715793)
|
||||
* svnlook: properly remove tempfiles on diff errors (r1711346)
|
||||
|
||||
- Client-side and server-side bugfixes:
|
||||
* fix heap overflow in svn:// protocol parser (CVE-2015-5259)
|
||||
@ -942,18 +1002,18 @@ http://svn.apache.org/repos/asf/subversion/tags/1.8.17
|
||||
- Client-side bugfixes:
|
||||
* fix handling of newly secured subdirectories in working copy (r1724448)
|
||||
* ra_serf: fix deleting directories with many files (issue #4557)
|
||||
* svnlook: properly remove tempfiles on diff errors (r1711346)
|
||||
* gpg-agent: properly handle passwords with percent characters (issue #4611)
|
||||
* merge: fix crash when merging to a local add (r1702299 et al)
|
||||
|
||||
- Server-side bugfixes:
|
||||
* fsfs: fix possible data reconstruction error (issue #4658)
|
||||
* svnlook: properly remove tempfiles on diff errors (r1711346)
|
||||
|
||||
- Client-side and server-side bugfixes:
|
||||
* fix potential memory access bugs (r1722860 et al)
|
||||
|
||||
- Bindings bugfixes:
|
||||
* javahl: fix temporary accepting SSL server certificates (r1764851)
|
||||
* javahl: fix temporarily accepting SSL server certificates (r1764851)
|
||||
* swig-pl: do not corrupt "{DATE}" revision variable (r1767768)
|
||||
* swig-pl: fix possible stack corruption (r1683266)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
Apache Subversion
|
||||
Copyright 2016 The Apache Software Foundation
|
||||
Copyright 2017 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by many people, and distributed
|
||||
under Contributor License Agreements to The Apache Software Foundation
|
||||
|
@ -2782,7 +2782,7 @@ subversion/libsvn_ra_serf/util_error.lo: subversion/libsvn_ra_serf/util_error.c
|
||||
|
||||
subversion/libsvn_ra_serf/xml.lo: subversion/libsvn_ra_serf/xml.c subversion/include/private/svn_dav_protocol.h subversion/include/private/svn_debug.h subversion/include/private/svn_editor.h subversion/include/private/svn_ra_private.h subversion/include/private/svn_string_private.h subversion/include/private/svn_subr_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_config.h subversion/include/svn_dav.h subversion/include/svn_delta.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_hash.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_ra.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/include/svn_version.h subversion/include/svn_xml.h subversion/libsvn_ra/ra_loader.h subversion/libsvn_ra_serf/blncache.h subversion/libsvn_ra_serf/ra_serf.h subversion/svn_private_config.h
|
||||
|
||||
subversion/libsvn_ra_svn/client.lo: subversion/libsvn_ra_svn/client.c subversion/include/private/svn_debug.h subversion/include/private/svn_editor.h subversion/include/private/svn_fspath.h subversion/include/private/svn_ra_private.h subversion/include/private/svn_ra_svn_private.h subversion/include/private/svn_subr_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_compat.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_hash.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_props.h subversion/include/svn_ra.h subversion/include/svn_ra_svn.h subversion/include/svn_string.h subversion/include/svn_time.h subversion/include/svn_types.h subversion/include/svn_version.h subversion/libsvn_ra/ra_loader.h subversion/libsvn_ra/wrapper_template.h subversion/libsvn_ra_svn/ra_svn.h subversion/svn_private_config.h
|
||||
subversion/libsvn_ra_svn/client.lo: subversion/libsvn_ra_svn/client.c subversion/include/private/svn_debug.h subversion/include/private/svn_editor.h subversion/include/private/svn_fspath.h subversion/include/private/svn_ra_private.h subversion/include/private/svn_ra_svn_private.h subversion/include/private/svn_subr_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_compat.h subversion/include/svn_config.h subversion/include/svn_ctype.h subversion/include/svn_delta.h subversion/include/svn_dirent_uri.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_hash.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_path.h subversion/include/svn_pools.h subversion/include/svn_props.h subversion/include/svn_ra.h subversion/include/svn_ra_svn.h subversion/include/svn_string.h subversion/include/svn_time.h subversion/include/svn_types.h subversion/include/svn_version.h subversion/libsvn_ra/ra_loader.h subversion/libsvn_ra/wrapper_template.h subversion/libsvn_ra_svn/ra_svn.h subversion/svn_private_config.h
|
||||
|
||||
subversion/libsvn_ra_svn/cram.lo: subversion/libsvn_ra_svn/cram.c subversion/include/private/svn_debug.h subversion/include/private/svn_editor.h subversion/include/private/svn_ra_svn_private.h subversion/include/svn_auth.h subversion/include/svn_checksum.h subversion/include/svn_config.h subversion/include/svn_delta.h subversion/include/svn_error.h subversion/include/svn_error_codes.h subversion/include/svn_io.h subversion/include/svn_mergeinfo.h subversion/include/svn_ra.h subversion/include/svn_ra_svn.h subversion/include/svn_string.h subversion/include/svn_types.h subversion/libsvn_ra_svn/ra_svn.h subversion/svn_private_config.h
|
||||
|
||||
|
22
contrib/subversion/configure
vendored
22
contrib/subversion/configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for subversion 1.9.5.
|
||||
# Generated by GNU Autoconf 2.69 for subversion 1.9.7.
|
||||
#
|
||||
# Report bugs to <http://subversion.apache.org/>.
|
||||
#
|
||||
@ -590,8 +590,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='subversion'
|
||||
PACKAGE_TARNAME='subversion'
|
||||
PACKAGE_VERSION='1.9.5'
|
||||
PACKAGE_STRING='subversion 1.9.5'
|
||||
PACKAGE_VERSION='1.9.7'
|
||||
PACKAGE_STRING='subversion 1.9.7'
|
||||
PACKAGE_BUGREPORT='http://subversion.apache.org/'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -1471,7 +1471,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures subversion 1.9.5 to adapt to many kinds of systems.
|
||||
\`configure' configures subversion 1.9.7 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1537,7 +1537,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of subversion 1.9.5:";;
|
||||
short | recursive ) echo "Configuration of subversion 1.9.7:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1751,7 +1751,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
subversion configure 1.9.5
|
||||
subversion configure 1.9.7
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@ -2295,7 +2295,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by subversion $as_me 1.9.5, which was
|
||||
It was created by subversion $as_me 1.9.7, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -2675,8 +2675,8 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
|
||||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring Subversion 1.9.5" >&5
|
||||
$as_echo "$as_me: Configuring Subversion 1.9.5" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring Subversion 1.9.7" >&5
|
||||
$as_echo "$as_me: Configuring Subversion 1.9.7" >&6;}
|
||||
|
||||
abs_srcdir="`cd $srcdir && pwd`"
|
||||
|
||||
@ -26756,7 +26756,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by subversion $as_me 1.9.5, which was
|
||||
This file was extended by subversion $as_me 1.9.7, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -26822,7 +26822,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
subversion config.status 1.9.5
|
||||
subversion config.status 1.9.7
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
@ -70,7 +70,7 @@ extern "C" {
|
||||
*
|
||||
* @since New in 1.1.
|
||||
*/
|
||||
#define SVN_VER_PATCH 5
|
||||
#define SVN_VER_PATCH 7
|
||||
|
||||
|
||||
/** @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 " (r1770682)"
|
||||
#define SVN_VER_TAG " (r1800392)"
|
||||
|
||||
|
||||
/** 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 1770682
|
||||
#define SVN_VER_REVISION 1800392
|
||||
|
||||
|
||||
/* Version strings composed from the above definitions. */
|
||||
|
@ -1057,10 +1057,24 @@ verify_wc_dsts(const apr_array_header_t *copy_pairs,
|
||||
ctx->wc_ctx, pair->dst_parent_abspath,
|
||||
FALSE, TRUE,
|
||||
iterpool));
|
||||
if (make_parents && dst_parent_kind == svn_node_none)
|
||||
if (dst_parent_kind == svn_node_none)
|
||||
{
|
||||
SVN_ERR(svn_client__make_local_parents(pair->dst_parent_abspath,
|
||||
TRUE, ctx, iterpool));
|
||||
if (make_parents)
|
||||
SVN_ERR(svn_client__make_local_parents(pair->dst_parent_abspath,
|
||||
TRUE, ctx, iterpool));
|
||||
else
|
||||
{
|
||||
SVN_ERR(svn_io_check_path(pair->dst_parent_abspath,
|
||||
&dst_parent_kind, scratch_pool));
|
||||
return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
|
||||
(dst_parent_kind == svn_node_dir)
|
||||
? _("Directory '%s' is not under "
|
||||
"version control")
|
||||
: _("Path '%s' is not a directory"),
|
||||
svn_dirent_local_style(
|
||||
pair->dst_parent_abspath,
|
||||
scratch_pool));
|
||||
}
|
||||
}
|
||||
else if (dst_parent_kind != svn_node_dir)
|
||||
{
|
||||
|
@ -6465,6 +6465,7 @@ get_mergeinfo_paths(apr_array_header_t *children_with_mergeinfo,
|
||||
{
|
||||
int i;
|
||||
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
|
||||
apr_pool_t *swmi_pool;
|
||||
apr_hash_t *subtrees_with_mergeinfo;
|
||||
apr_hash_t *excluded_subtrees;
|
||||
apr_hash_t *switched_subtrees;
|
||||
@ -6473,10 +6474,13 @@ get_mergeinfo_paths(apr_array_header_t *children_with_mergeinfo,
|
||||
struct pre_merge_status_baton_t pre_merge_status_baton;
|
||||
|
||||
/* Case 1: Subtrees with explicit mergeinfo. */
|
||||
/* Use a subpool for subtrees_with_mergeinfo, as it can be very large
|
||||
and is temporary. */
|
||||
swmi_pool = svn_pool_create(scratch_pool);
|
||||
SVN_ERR(get_wc_explicit_mergeinfo_catalog(&subtrees_with_mergeinfo,
|
||||
target->abspath,
|
||||
depth, ctx,
|
||||
result_pool, scratch_pool));
|
||||
swmi_pool, swmi_pool));
|
||||
if (subtrees_with_mergeinfo)
|
||||
{
|
||||
apr_hash_index_t *hi;
|
||||
@ -6513,6 +6517,7 @@ get_mergeinfo_paths(apr_array_header_t *children_with_mergeinfo,
|
||||
children_with_mergeinfo->elt_size,
|
||||
compare_merge_path_t_as_paths);
|
||||
}
|
||||
svn_pool_destroy(swmi_pool);
|
||||
|
||||
/* Case 2: Switched subtrees
|
||||
Case 10: Paths at depths of 'empty' or 'files'
|
||||
@ -12331,6 +12336,10 @@ find_last_merged_location(svn_client__pathrev_t **base_p,
|
||||
svn_revnum_t youngest_merged_rev = SVN_INVALID_REVNUM;
|
||||
svn_mergeinfo_catalog_t target_mergeinfo_cat = NULL;
|
||||
|
||||
/* Using a local subpool for 'target_mergeinfo_cat' can make a big
|
||||
reduction in overall memory usage. */
|
||||
apr_pool_t *tmic_pool = svn_pool_create(scratch_pool);
|
||||
|
||||
source_peg_rev.kind = svn_opt_revision_number;
|
||||
source_peg_rev.value.number = source_branch->tip->rev;
|
||||
source_start_rev.kind = svn_opt_revision_number;
|
||||
@ -12351,7 +12360,7 @@ find_last_merged_location(svn_client__pathrev_t **base_p,
|
||||
operative_rev_receiver,
|
||||
&youngest_merged_rev,
|
||||
ctx, ra_session,
|
||||
result_pool, scratch_pool));
|
||||
tmic_pool, tmic_pool));
|
||||
|
||||
if (!SVN_IS_VALID_REVNUM(youngest_merged_rev))
|
||||
{
|
||||
@ -12387,7 +12396,7 @@ find_last_merged_location(svn_client__pathrev_t **base_p,
|
||||
operative_rev_receiver,
|
||||
&oldest_eligible_rev,
|
||||
ctx, ra_session,
|
||||
scratch_pool, scratch_pool));
|
||||
tmic_pool, tmic_pool));
|
||||
|
||||
/* If there are revisions eligible for merging, use the oldest one
|
||||
to calculate the base. Otherwise there are no operative revisions
|
||||
@ -12409,6 +12418,7 @@ find_last_merged_location(svn_client__pathrev_t **base_p,
|
||||
result_pool, scratch_pool));
|
||||
}
|
||||
|
||||
svn_pool_destroy(tmic_pool);
|
||||
return SVN_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -2029,8 +2029,13 @@ rep_read_contents(void *baton,
|
||||
SVN_ERR(skip_contents(rb, rb->fulltext_delivered));
|
||||
}
|
||||
|
||||
/* Get the next block of data. */
|
||||
SVN_ERR(get_contents_from_windows(rb, buf, len));
|
||||
/* Get the next block of data.
|
||||
* Keep in mind that the representation might be empty and leave us
|
||||
* already positioned at the end of the rep. */
|
||||
if (rb->off == rb->len)
|
||||
*len = 0;
|
||||
else
|
||||
SVN_ERR(get_contents_from_windows(rb, buf, len));
|
||||
|
||||
if (rb->current_fulltext)
|
||||
svn_stringbuf_appendbytes(rb->current_fulltext, buf, *len);
|
||||
@ -2123,6 +2128,96 @@ svn_fs_fs__get_contents(svn_stream_t **contents_p,
|
||||
return SVN_NO_ERROR;
|
||||
}
|
||||
|
||||
svn_error_t *
|
||||
svn_fs_fs__get_contents_from_file(svn_stream_t **contents_p,
|
||||
svn_fs_t *fs,
|
||||
representation_t *rep,
|
||||
apr_file_t *file,
|
||||
apr_off_t offset,
|
||||
apr_pool_t *pool)
|
||||
{
|
||||
struct rep_read_baton *rb;
|
||||
pair_cache_key_t fulltext_cache_key = { SVN_INVALID_REVNUM, 0 };
|
||||
rep_state_t *rs = apr_pcalloc(pool, sizeof(*rs));
|
||||
svn_fs_fs__rep_header_t *rh;
|
||||
|
||||
/* Initialize the reader baton. Some members may added lazily
|
||||
* while reading from the stream. */
|
||||
SVN_ERR(rep_read_get_baton(&rb, fs, rep, fulltext_cache_key, pool));
|
||||
|
||||
/* Continue constructing RS. Leave caches as NULL. */
|
||||
rs->size = rep->size;
|
||||
rs->revision = SVN_INVALID_REVNUM;
|
||||
rs->item_index = 0;
|
||||
rs->ver = -1;
|
||||
rs->start = -1;
|
||||
|
||||
/* Provide just enough file access info to allow for a basic read from
|
||||
* FILE but leave all index / footer info with empty values b/c FILE
|
||||
* probably is not a complete revision file. */
|
||||
rs->sfile = apr_pcalloc(pool, sizeof(*rs->sfile));
|
||||
rs->sfile->revision = rep->revision;
|
||||
rs->sfile->pool = pool;
|
||||
rs->sfile->fs = fs;
|
||||
rs->sfile->rfile = apr_pcalloc(pool, sizeof(*rs->sfile->rfile));
|
||||
rs->sfile->rfile->start_revision = SVN_INVALID_REVNUM;
|
||||
rs->sfile->rfile->file = file;
|
||||
rs->sfile->rfile->stream = svn_stream_from_aprfile2(file, TRUE, pool);
|
||||
|
||||
/* Read the rep header. */
|
||||
SVN_ERR(aligned_seek(fs, file, NULL, offset, pool));
|
||||
SVN_ERR(svn_fs_fs__read_rep_header(&rh, rs->sfile->rfile->stream,
|
||||
pool, pool));
|
||||
SVN_ERR(get_file_offset(&rs->start, rs, pool));
|
||||
rs->header_size = rh->header_size;
|
||||
|
||||
/* Log the access. */
|
||||
SVN_ERR(dbg_log_access(fs, SVN_INVALID_REVNUM, 0, rh,
|
||||
SVN_FS_FS__ITEM_TYPE_ANY_REP, pool));
|
||||
|
||||
/* Build the representation list (delta chain). */
|
||||
if (rh->type == svn_fs_fs__rep_plain)
|
||||
{
|
||||
rb->rs_list = apr_array_make(pool, 0, sizeof(rep_state_t *));
|
||||
rb->src_state = rs;
|
||||
}
|
||||
else if (rh->type == svn_fs_fs__rep_self_delta)
|
||||
{
|
||||
rb->rs_list = apr_array_make(pool, 1, sizeof(rep_state_t *));
|
||||
APR_ARRAY_PUSH(rb->rs_list, rep_state_t *) = rs;
|
||||
rb->src_state = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
representation_t next_rep = { 0 };
|
||||
|
||||
/* skip "SVNx" diff marker */
|
||||
rs->current = 4;
|
||||
|
||||
/* REP's base rep is inside a proper revision.
|
||||
* It can be reconstructed in the usual way. */
|
||||
next_rep.revision = rh->base_revision;
|
||||
next_rep.item_index = rh->base_item_index;
|
||||
next_rep.size = rh->base_length;
|
||||
svn_fs_fs__id_txn_reset(&next_rep.txn_id);
|
||||
|
||||
SVN_ERR(build_rep_list(&rb->rs_list, &rb->base_window,
|
||||
&rb->src_state, &rb->len, rb->fs, &next_rep,
|
||||
rb->filehandle_pool));
|
||||
|
||||
/* Insert the access to REP as the first element of the delta chain. */
|
||||
svn_sort__array_insert(rb->rs_list, &rs, 0);
|
||||
}
|
||||
|
||||
/* Now, the baton is complete and we can assemble the stream around it. */
|
||||
*contents_p = svn_stream_create(rb, pool);
|
||||
svn_stream_set_read2(*contents_p, NULL /* only full read support */,
|
||||
rep_read_contents);
|
||||
svn_stream_set_close(*contents_p, rep_read_contents_close);
|
||||
|
||||
return SVN_NO_ERROR;
|
||||
}
|
||||
|
||||
/* Baton for cache_access_wrapper. Wraps the original parameters of
|
||||
* svn_fs_fs__try_process_file_content().
|
||||
*/
|
||||
|
@ -81,6 +81,18 @@ svn_fs_fs__get_contents(svn_stream_t **contents_p,
|
||||
svn_boolean_t cache_fulltext,
|
||||
apr_pool_t *pool);
|
||||
|
||||
/* Set *CONTENTS_P to be a readable svn_stream_t that receives the text
|
||||
representation REP as seen in filesystem FS. Read the latest element
|
||||
of the delta chain from FILE at offset OFFSET.
|
||||
Use POOL for allocations. */
|
||||
svn_error_t *
|
||||
svn_fs_fs__get_contents_from_file(svn_stream_t **contents_p,
|
||||
svn_fs_t *fs,
|
||||
representation_t *rep,
|
||||
apr_file_t *file,
|
||||
apr_off_t offset,
|
||||
apr_pool_t *pool);
|
||||
|
||||
/* Attempt to fetch the text representation of node-revision NODEREV as
|
||||
seen in filesystem FS and pass it along with the BATON to the PROCESSOR.
|
||||
Set *SUCCESS only of the data could be provided and the processing
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* This file is automatically generated from rep-cache-db.sql and .dist_sandbox/subversion-1.9.5/subversion/libsvn_fs_fs/token-map.h.
|
||||
/* This file is automatically generated from rep-cache-db.sql and .dist_sandbox/subversion-1.9.7/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
|
||||
|
@ -128,7 +128,10 @@ svn_fs_fs__open_rep_cache(svn_fs_t *fs,
|
||||
fs_fs_data_t *ffd = fs->fsap_data;
|
||||
svn_error_t *err = svn_atomic__init_once(&ffd->rep_cache_db_opened,
|
||||
open_rep_cache, fs, pool);
|
||||
return svn_error_quick_wrap(err, _("Couldn't open rep-cache database"));
|
||||
return svn_error_quick_wrapf(err,
|
||||
_("Couldn't open rep-cache database '%s'"),
|
||||
svn_dirent_local_style(
|
||||
path_rep_cache_db(fs->path, pool), pool));
|
||||
}
|
||||
|
||||
svn_error_t *
|
||||
|
@ -2128,6 +2128,11 @@ rep_write_get_baton(struct rep_write_baton **wb_p,
|
||||
there may be new duplicate representations within the same uncommitted
|
||||
revision, those can be passed in REPS_HASH (maps a sha1 digest onto
|
||||
representation_t*), otherwise pass in NULL for REPS_HASH.
|
||||
|
||||
The content of both representations will be compared, taking REP's content
|
||||
from FILE at OFFSET. Only if they actually match, will *OLD_REP not be
|
||||
NULL.
|
||||
|
||||
Use RESULT_POOL for *OLD_REP allocations and SCRATCH_POOL for temporaries.
|
||||
The lifetime of *OLD_REP is limited by both, RESULT_POOL and REP lifetime.
|
||||
*/
|
||||
@ -2135,6 +2140,8 @@ static svn_error_t *
|
||||
get_shared_rep(representation_t **old_rep,
|
||||
svn_fs_t *fs,
|
||||
representation_t *rep,
|
||||
apr_file_t *file,
|
||||
apr_off_t offset,
|
||||
apr_hash_t *reps_hash,
|
||||
apr_pool_t *result_pool,
|
||||
apr_pool_t *scratch_pool)
|
||||
@ -2142,6 +2149,10 @@ get_shared_rep(representation_t **old_rep,
|
||||
svn_error_t *err;
|
||||
fs_fs_data_t *ffd = fs->fsap_data;
|
||||
|
||||
svn_checksum_t checksum;
|
||||
checksum.digest = rep->sha1_digest;
|
||||
checksum.kind = svn_checksum_sha1;
|
||||
|
||||
/* Return NULL, if rep sharing has been disabled. */
|
||||
*old_rep = NULL;
|
||||
if (!ffd->rep_sharing_allowed)
|
||||
@ -2158,9 +2169,6 @@ get_shared_rep(representation_t **old_rep,
|
||||
/* If we haven't found anything yet, try harder and consult our DB. */
|
||||
if (*old_rep == NULL)
|
||||
{
|
||||
svn_checksum_t checksum;
|
||||
checksum.digest = rep->sha1_digest;
|
||||
checksum.kind = svn_checksum_sha1;
|
||||
err = svn_fs_fs__get_rep_reference(old_rep, fs, &checksum, result_pool);
|
||||
/* ### Other error codes that we shouldn't mask out? */
|
||||
if (err == SVN_NO_ERROR)
|
||||
@ -2235,6 +2243,72 @@ get_shared_rep(representation_t **old_rep,
|
||||
(*old_rep)->uniquifier = rep->uniquifier;
|
||||
}
|
||||
|
||||
/* If we (very likely) found a matching representation, compare the actual
|
||||
* contents such that we can be sure that no rep-cache.db corruption or
|
||||
* hash collision produced a false positive. */
|
||||
if (*old_rep)
|
||||
{
|
||||
apr_off_t old_position;
|
||||
svn_stream_t *contents;
|
||||
svn_stream_t *old_contents;
|
||||
svn_boolean_t same;
|
||||
|
||||
/* The existing representation may itself be part of the current
|
||||
* transaction. In that case, it may be in different stages of
|
||||
* the commit finalization process.
|
||||
*
|
||||
* OLD_REP_NORM is the same as that OLD_REP but it is assigned
|
||||
* explicitly to REP's transaction if OLD_REP does not point
|
||||
* to an already committed revision. This then prevents the
|
||||
* revision lookup and the txn data will be accessed.
|
||||
*/
|
||||
representation_t old_rep_norm = **old_rep;
|
||||
if ( !SVN_IS_VALID_REVNUM(old_rep_norm.revision)
|
||||
|| old_rep_norm.revision > ffd->youngest_rev_cache)
|
||||
old_rep_norm.txn_id = rep->txn_id;
|
||||
|
||||
/* Make sure we can later restore FILE's current position. */
|
||||
SVN_ERR(svn_fs_fs__get_file_offset(&old_position, file, scratch_pool));
|
||||
|
||||
/* Compare the two representations.
|
||||
* Note that the stream comparison might also produce MD5 checksum
|
||||
* errors or other failures in case of SHA1 collisions. */
|
||||
SVN_ERR(svn_fs_fs__get_contents_from_file(&contents, fs, rep, file,
|
||||
offset, scratch_pool));
|
||||
SVN_ERR(svn_fs_fs__get_contents(&old_contents, fs, &old_rep_norm,
|
||||
FALSE, scratch_pool));
|
||||
err = svn_stream_contents_same2(&same, contents, old_contents,
|
||||
scratch_pool);
|
||||
|
||||
/* A mismatch should be extremely rare.
|
||||
* If it does happen, reject the commit. */
|
||||
if (!same || err)
|
||||
{
|
||||
/* SHA1 collision or worse. */
|
||||
svn_stringbuf_t *old_rep_str
|
||||
= svn_fs_fs__unparse_representation(*old_rep,
|
||||
ffd->format, FALSE,
|
||||
scratch_pool,
|
||||
scratch_pool);
|
||||
svn_stringbuf_t *rep_str
|
||||
= svn_fs_fs__unparse_representation(rep,
|
||||
ffd->format, FALSE,
|
||||
scratch_pool,
|
||||
scratch_pool);
|
||||
const char *checksum__str
|
||||
= svn_checksum_to_cstring_display(&checksum, scratch_pool);
|
||||
|
||||
return svn_error_createf(SVN_ERR_FS_GENERAL,
|
||||
err, "SHA1 of reps '%s' and '%s' "
|
||||
"matches (%s) but contents differ",
|
||||
old_rep_str->data, rep_str->data,
|
||||
checksum__str);
|
||||
}
|
||||
|
||||
/* Restore FILE's read / write position. */
|
||||
SVN_ERR(svn_io_file_seek(file, APR_SET, &old_position, scratch_pool));
|
||||
}
|
||||
|
||||
return SVN_NO_ERROR;
|
||||
}
|
||||
|
||||
@ -2293,8 +2367,8 @@ rep_write_contents_close(void *baton)
|
||||
|
||||
/* Check and see if we already have a representation somewhere that's
|
||||
identical to the one we just wrote out. */
|
||||
SVN_ERR(get_shared_rep(&old_rep, b->fs, rep, NULL, b->result_pool,
|
||||
b->scratch_pool));
|
||||
SVN_ERR(get_shared_rep(&old_rep, b->fs, rep, b->file, b->rep_offset, NULL,
|
||||
b->result_pool, b->scratch_pool));
|
||||
|
||||
if (old_rep)
|
||||
{
|
||||
@ -2519,11 +2593,16 @@ write_directory_to_stream(svn_stream_t *stream,
|
||||
/* Write out the COLLECTION as a text representation to file FILE using
|
||||
WRITER. In the process, record position, the total size of the dump and
|
||||
MD5 as well as SHA1 in REP. Add the representation of type ITEM_TYPE to
|
||||
the indexes if necessary. If rep sharing has been enabled and REPS_HASH
|
||||
is not NULL, it will be used in addition to the on-disk cache to find
|
||||
earlier reps with the same content. When such existing reps can be
|
||||
found, we will truncate the one just written from the file and return
|
||||
the existing rep. Perform temporary allocations in SCRATCH_POOL. */
|
||||
the indexes if necessary.
|
||||
|
||||
If ALLOW_REP_SHARING is FALSE, rep-sharing will not be used, regardless
|
||||
of any other option and rep-sharing settings. If rep sharing has been
|
||||
enabled and REPS_HASH is not NULL, it will be used in addition to the
|
||||
on-disk cache to find earlier reps with the same content. If such
|
||||
existing reps can be found, we will truncate the one just written from
|
||||
the file and return the existing rep.
|
||||
|
||||
Perform temporary allocations in SCRATCH_POOL. */
|
||||
static svn_error_t *
|
||||
write_container_rep(representation_t *rep,
|
||||
apr_file_t *file,
|
||||
@ -2531,14 +2610,15 @@ write_container_rep(representation_t *rep,
|
||||
collection_writer_t writer,
|
||||
svn_fs_t *fs,
|
||||
apr_hash_t *reps_hash,
|
||||
svn_boolean_t allow_rep_sharing,
|
||||
apr_uint32_t item_type,
|
||||
apr_pool_t *scratch_pool)
|
||||
{
|
||||
svn_stream_t *stream;
|
||||
struct write_container_baton *whb;
|
||||
svn_checksum_ctx_t *fnv1a_checksum_ctx;
|
||||
representation_t *old_rep;
|
||||
apr_off_t offset = 0;
|
||||
svn_fs_fs__p2l_entry_t entry;
|
||||
|
||||
SVN_ERR(svn_fs_fs__get_file_offset(&offset, file, scratch_pool));
|
||||
|
||||
@ -2562,45 +2642,46 @@ write_container_rep(representation_t *rep,
|
||||
/* Store the results. */
|
||||
SVN_ERR(digests_final(rep, whb->md5_ctx, whb->sha1_ctx, scratch_pool));
|
||||
|
||||
/* Update size info. */
|
||||
rep->expanded_size = whb->size;
|
||||
rep->size = whb->size;
|
||||
|
||||
/* Check and see if we already have a representation somewhere that's
|
||||
identical to the one we just wrote out. */
|
||||
SVN_ERR(get_shared_rep(&old_rep, fs, rep, reps_hash, scratch_pool,
|
||||
scratch_pool));
|
||||
|
||||
if (old_rep)
|
||||
if (allow_rep_sharing)
|
||||
{
|
||||
/* We need to erase from the protorev the data we just wrote. */
|
||||
SVN_ERR(svn_io_file_trunc(file, offset, scratch_pool));
|
||||
representation_t *old_rep;
|
||||
SVN_ERR(get_shared_rep(&old_rep, fs, rep, file, offset, reps_hash,
|
||||
scratch_pool, scratch_pool));
|
||||
|
||||
/* Use the old rep for this content. */
|
||||
memcpy(rep, old_rep, sizeof (*rep));
|
||||
if (old_rep)
|
||||
{
|
||||
/* We need to erase from the protorev the data we just wrote. */
|
||||
SVN_ERR(svn_io_file_trunc(file, offset, scratch_pool));
|
||||
|
||||
/* Use the old rep for this content. */
|
||||
memcpy(rep, old_rep, sizeof (*rep));
|
||||
return SVN_NO_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
svn_fs_fs__p2l_entry_t entry;
|
||||
|
||||
/* Write out our cosmetic end marker. */
|
||||
SVN_ERR(svn_stream_puts(whb->stream, "ENDREP\n"));
|
||||
/* Write out our cosmetic end marker. */
|
||||
SVN_ERR(svn_stream_puts(whb->stream, "ENDREP\n"));
|
||||
|
||||
SVN_ERR(allocate_item_index(&rep->item_index, fs, &rep->txn_id,
|
||||
offset, scratch_pool));
|
||||
SVN_ERR(allocate_item_index(&rep->item_index, fs, &rep->txn_id,
|
||||
offset, scratch_pool));
|
||||
|
||||
entry.offset = offset;
|
||||
SVN_ERR(svn_fs_fs__get_file_offset(&offset, file, scratch_pool));
|
||||
entry.size = offset - entry.offset;
|
||||
entry.type = item_type;
|
||||
entry.item.revision = SVN_INVALID_REVNUM;
|
||||
entry.item.number = rep->item_index;
|
||||
SVN_ERR(fnv1a_checksum_finalize(&entry.fnv1_checksum,
|
||||
fnv1a_checksum_ctx,
|
||||
scratch_pool));
|
||||
entry.offset = offset;
|
||||
SVN_ERR(svn_fs_fs__get_file_offset(&offset, file, scratch_pool));
|
||||
entry.size = offset - entry.offset;
|
||||
entry.type = item_type;
|
||||
entry.item.revision = SVN_INVALID_REVNUM;
|
||||
entry.item.number = rep->item_index;
|
||||
SVN_ERR(fnv1a_checksum_finalize(&entry.fnv1_checksum,
|
||||
fnv1a_checksum_ctx,
|
||||
scratch_pool));
|
||||
|
||||
SVN_ERR(store_p2l_index_entry(fs, &rep->txn_id, &entry, scratch_pool));
|
||||
|
||||
/* update the representation */
|
||||
rep->size = whb->size;
|
||||
rep->expanded_size = whb->size;
|
||||
}
|
||||
SVN_ERR(store_p2l_index_entry(fs, &rep->txn_id, &entry, scratch_pool));
|
||||
|
||||
return SVN_NO_ERROR;
|
||||
}
|
||||
@ -2608,11 +2689,14 @@ write_container_rep(representation_t *rep,
|
||||
/* Write out the COLLECTION pertaining to the NODEREV in FS as a deltified
|
||||
text representation to file FILE using WRITER. In the process, record the
|
||||
total size and the md5 digest in REP and add the representation of type
|
||||
ITEM_TYPE to the indexes if necessary. If rep sharing has been enabled and
|
||||
REPS_HASH is not NULL, it will be used in addition to the on-disk cache to
|
||||
find earlier reps with the same content. When such existing reps can be
|
||||
found, we will truncate the one just written from the file and return the
|
||||
existing rep.
|
||||
ITEM_TYPE to the indexes if necessary.
|
||||
|
||||
If ALLOW_REP_SHARING is FALSE, rep-sharing will not be used, regardless
|
||||
of any other option and rep-sharing settings. If rep sharing has been
|
||||
enabled and REPS_HASH is not NULL, it will be used in addition to the
|
||||
on-disk cache to find earlier reps with the same content. If such
|
||||
existing reps can be found, we will truncate the one just written from
|
||||
the file and return the existing rep.
|
||||
|
||||
If ITEM_TYPE is IS_PROPS equals SVN_FS_FS__ITEM_TYPE_*_PROPS, assume
|
||||
that we want to a props representation as the base for our delta.
|
||||
@ -2626,6 +2710,7 @@ write_container_delta_rep(representation_t *rep,
|
||||
svn_fs_t *fs,
|
||||
node_revision_t *noderev,
|
||||
apr_hash_t *reps_hash,
|
||||
svn_boolean_t allow_rep_sharing,
|
||||
apr_uint32_t item_type,
|
||||
apr_pool_t *scratch_pool)
|
||||
{
|
||||
@ -2635,10 +2720,10 @@ write_container_delta_rep(representation_t *rep,
|
||||
svn_stream_t *file_stream;
|
||||
svn_stream_t *stream;
|
||||
representation_t *base_rep;
|
||||
representation_t *old_rep;
|
||||
svn_checksum_ctx_t *fnv1a_checksum_ctx;
|
||||
svn_stream_t *source;
|
||||
svn_fs_fs__rep_header_t header = { 0 };
|
||||
svn_fs_fs__p2l_entry_t entry;
|
||||
|
||||
apr_off_t rep_end = 0;
|
||||
apr_off_t delta_start = 0;
|
||||
@ -2701,46 +2786,47 @@ write_container_delta_rep(representation_t *rep,
|
||||
/* Store the results. */
|
||||
SVN_ERR(digests_final(rep, whb->md5_ctx, whb->sha1_ctx, scratch_pool));
|
||||
|
||||
/* Update size info. */
|
||||
SVN_ERR(svn_fs_fs__get_file_offset(&rep_end, file, scratch_pool));
|
||||
rep->size = rep_end - delta_start;
|
||||
rep->expanded_size = whb->size;
|
||||
|
||||
/* Check and see if we already have a representation somewhere that's
|
||||
identical to the one we just wrote out. */
|
||||
SVN_ERR(get_shared_rep(&old_rep, fs, rep, reps_hash, scratch_pool,
|
||||
scratch_pool));
|
||||
|
||||
if (old_rep)
|
||||
if (allow_rep_sharing)
|
||||
{
|
||||
/* We need to erase from the protorev the data we just wrote. */
|
||||
SVN_ERR(svn_io_file_trunc(file, offset, scratch_pool));
|
||||
representation_t *old_rep;
|
||||
SVN_ERR(get_shared_rep(&old_rep, fs, rep, file, offset, reps_hash,
|
||||
scratch_pool, scratch_pool));
|
||||
|
||||
/* Use the old rep for this content. */
|
||||
memcpy(rep, old_rep, sizeof (*rep));
|
||||
if (old_rep)
|
||||
{
|
||||
/* We need to erase from the protorev the data we just wrote. */
|
||||
SVN_ERR(svn_io_file_trunc(file, offset, scratch_pool));
|
||||
|
||||
/* Use the old rep for this content. */
|
||||
memcpy(rep, old_rep, sizeof (*rep));
|
||||
return SVN_NO_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
svn_fs_fs__p2l_entry_t entry;
|
||||
|
||||
/* Write out our cosmetic end marker. */
|
||||
SVN_ERR(svn_fs_fs__get_file_offset(&rep_end, file, scratch_pool));
|
||||
SVN_ERR(svn_stream_puts(file_stream, "ENDREP\n"));
|
||||
/* Write out our cosmetic end marker. */
|
||||
SVN_ERR(svn_stream_puts(file_stream, "ENDREP\n"));
|
||||
|
||||
SVN_ERR(allocate_item_index(&rep->item_index, fs, &rep->txn_id,
|
||||
offset, scratch_pool));
|
||||
SVN_ERR(allocate_item_index(&rep->item_index, fs, &rep->txn_id,
|
||||
offset, scratch_pool));
|
||||
|
||||
entry.offset = offset;
|
||||
SVN_ERR(svn_fs_fs__get_file_offset(&offset, file, scratch_pool));
|
||||
entry.size = offset - entry.offset;
|
||||
entry.type = item_type;
|
||||
entry.item.revision = SVN_INVALID_REVNUM;
|
||||
entry.item.number = rep->item_index;
|
||||
SVN_ERR(fnv1a_checksum_finalize(&entry.fnv1_checksum,
|
||||
fnv1a_checksum_ctx,
|
||||
scratch_pool));
|
||||
entry.offset = offset;
|
||||
SVN_ERR(svn_fs_fs__get_file_offset(&offset, file, scratch_pool));
|
||||
entry.size = offset - entry.offset;
|
||||
entry.type = item_type;
|
||||
entry.item.revision = SVN_INVALID_REVNUM;
|
||||
entry.item.number = rep->item_index;
|
||||
SVN_ERR(fnv1a_checksum_finalize(&entry.fnv1_checksum,
|
||||
fnv1a_checksum_ctx,
|
||||
scratch_pool));
|
||||
|
||||
SVN_ERR(store_p2l_index_entry(fs, &rep->txn_id, &entry, scratch_pool));
|
||||
|
||||
/* update the representation */
|
||||
rep->expanded_size = whb->size;
|
||||
rep->size = rep_end - delta_start;
|
||||
}
|
||||
SVN_ERR(store_p2l_index_entry(fs, &rep->txn_id, &entry, scratch_pool));
|
||||
|
||||
return SVN_NO_ERROR;
|
||||
}
|
||||
@ -2920,13 +3006,14 @@ write_final_rev(const svn_fs_id_t **new_id_p,
|
||||
SVN_ERR(write_container_delta_rep(noderev->data_rep, file,
|
||||
entries,
|
||||
write_directory_to_stream,
|
||||
fs, noderev, NULL,
|
||||
fs, noderev, NULL, FALSE,
|
||||
SVN_FS_FS__ITEM_TYPE_DIR_REP,
|
||||
pool));
|
||||
else
|
||||
SVN_ERR(write_container_rep(noderev->data_rep, file, entries,
|
||||
write_directory_to_stream, fs, NULL,
|
||||
SVN_FS_FS__ITEM_TYPE_DIR_REP, pool));
|
||||
FALSE, SVN_FS_FS__ITEM_TYPE_DIR_REP,
|
||||
pool));
|
||||
|
||||
reset_txn_in_rep(noderev->data_rep);
|
||||
}
|
||||
@ -2971,11 +3058,11 @@ write_final_rev(const svn_fs_id_t **new_id_p,
|
||||
if (ffd->deltify_properties)
|
||||
SVN_ERR(write_container_delta_rep(noderev->prop_rep, file, proplist,
|
||||
write_hash_to_stream, fs, noderev,
|
||||
reps_hash, item_type, pool));
|
||||
reps_hash, TRUE, item_type, pool));
|
||||
else
|
||||
SVN_ERR(write_container_rep(noderev->prop_rep, file, proplist,
|
||||
write_hash_to_stream, fs, reps_hash,
|
||||
item_type, pool));
|
||||
TRUE, item_type, pool));
|
||||
|
||||
reset_txn_in_rep(noderev->prop_rep);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* This file is automatically generated from rep-cache-db.sql and .dist_sandbox/subversion-1.9.5/subversion/libsvn_fs_x/token-map.h.
|
||||
/* This file is automatically generated from rep-cache-db.sql and .dist_sandbox/subversion-1.9.7/subversion/libsvn_fs_x/token-map.h.
|
||||
* Do not edit this file -- edit the source and rerun gen-make.py */
|
||||
|
||||
#define STMT_CREATE_SCHEMA 0
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "svn_props.h"
|
||||
#include "svn_mergeinfo.h"
|
||||
#include "svn_version.h"
|
||||
#include "svn_ctype.h"
|
||||
|
||||
#include "svn_private_config.h"
|
||||
|
||||
@ -396,7 +397,7 @@ static svn_error_t *find_tunnel_agent(const char *tunnel,
|
||||
* versions have it too. If the user is using some other ssh
|
||||
* implementation that doesn't accept it, they can override it
|
||||
* in the [tunnels] section of the config. */
|
||||
val = "$SVN_SSH ssh -q";
|
||||
val = "$SVN_SSH ssh -q --";
|
||||
}
|
||||
|
||||
if (!val || !*val)
|
||||
@ -441,7 +442,7 @@ static svn_error_t *find_tunnel_agent(const char *tunnel,
|
||||
for (n = 0; cmd_argv[n] != NULL; n++)
|
||||
argv[n] = cmd_argv[n];
|
||||
|
||||
argv[n++] = svn_path_uri_decode(hostinfo, pool);
|
||||
argv[n++] = hostinfo;
|
||||
argv[n++] = "svnserve";
|
||||
argv[n++] = "-t";
|
||||
argv[n] = NULL;
|
||||
@ -802,6 +803,32 @@ ra_svn_get_schemes(apr_pool_t *pool)
|
||||
}
|
||||
|
||||
|
||||
/* A simple whitelist to ensure the following are valid:
|
||||
* user@server
|
||||
* [::1]:22
|
||||
* server-name
|
||||
* server_name
|
||||
* 127.0.0.1
|
||||
* with an extra restriction that a leading '-' is invalid.
|
||||
*/
|
||||
static svn_boolean_t
|
||||
is_valid_hostinfo(const char *hostinfo)
|
||||
{
|
||||
const char *p = hostinfo;
|
||||
|
||||
if (p[0] == '-')
|
||||
return FALSE;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (!svn_ctype_isalnum(*p) && !strchr(":.-_[]@", *p))
|
||||
return FALSE;
|
||||
|
||||
++p;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static svn_error_t *ra_svn_open(svn_ra_session_t *session,
|
||||
const char **corrected_url,
|
||||
@ -835,8 +862,18 @@ static svn_error_t *ra_svn_open(svn_ra_session_t *session,
|
||||
|| (callbacks->check_tunnel_func && callbacks->open_tunnel_func
|
||||
&& !callbacks->check_tunnel_func(callbacks->tunnel_baton,
|
||||
tunnel))))
|
||||
SVN_ERR(find_tunnel_agent(tunnel, uri.hostinfo, &tunnel_argv, config,
|
||||
result_pool));
|
||||
{
|
||||
const char *decoded_hostinfo;
|
||||
|
||||
decoded_hostinfo = svn_path_uri_decode(uri.hostinfo, result_pool);
|
||||
|
||||
if (!is_valid_hostinfo(decoded_hostinfo))
|
||||
return svn_error_createf(SVN_ERR_BAD_URL, NULL, _("Invalid host '%s'"),
|
||||
uri.hostinfo);
|
||||
|
||||
SVN_ERR(find_tunnel_agent(tunnel, decoded_hostinfo, &tunnel_argv,
|
||||
config, result_pool));
|
||||
}
|
||||
else
|
||||
tunnel_argv = NULL;
|
||||
|
||||
|
@ -546,11 +546,15 @@ svn_repos__dump_revision_record(svn_stream_t *dump_stream,
|
||||
"%" APR_SIZE_T_FMT, propstring->len));
|
||||
}
|
||||
|
||||
/* Write out a regular Content-length header for the benefit of
|
||||
non-Subversion RFC-822 parsers. */
|
||||
svn_hash_sets(headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
|
||||
apr_psprintf(scratch_pool,
|
||||
"%" APR_SIZE_T_FMT, propstring->len));
|
||||
if (propstring)
|
||||
{
|
||||
/* Write out a regular Content-length header for the benefit of
|
||||
non-Subversion RFC-822 parsers. */
|
||||
svn_hash_sets(headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
|
||||
apr_psprintf(scratch_pool,
|
||||
"%" APR_SIZE_T_FMT, propstring->len));
|
||||
}
|
||||
|
||||
SVN_ERR(write_revision_headers(dump_stream, headers, scratch_pool));
|
||||
|
||||
/* End of headers */
|
||||
|
@ -1248,12 +1248,12 @@ svn_config_ensure(const char *config_dir, apr_pool_t *pool)
|
||||
"### passed to the tunnel agent as <user>@<hostname>.) If the" NL
|
||||
"### built-in ssh scheme were not predefined, it could be defined" NL
|
||||
"### as:" NL
|
||||
"# ssh = $SVN_SSH ssh -q" NL
|
||||
"# ssh = $SVN_SSH ssh -q --" NL
|
||||
"### If you wanted to define a new 'rsh' scheme, to be used with" NL
|
||||
"### 'svn+rsh:' URLs, you could do so as follows:" NL
|
||||
"# rsh = rsh" NL
|
||||
"# rsh = rsh --" NL
|
||||
"### Or, if you wanted to specify a full path and arguments:" NL
|
||||
"# rsh = /path/to/rsh -l myusername" NL
|
||||
"# rsh = /path/to/rsh -l myusername --" NL
|
||||
"### On Windows, if you are specifying a full path to a command," NL
|
||||
"### use a forward slash (/) or a paired backslash (\\\\) as the" NL
|
||||
"### path separator. A single backslash will be treated as an" NL
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* This file is automatically generated from internal_statements.sql and .dist_sandbox/subversion-1.9.5/subversion/libsvn_subr/token-map.h.
|
||||
/* This file is automatically generated from internal_statements.sql and .dist_sandbox/subversion-1.9.7/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
|
||||
|
@ -4044,6 +4044,26 @@ svn_io_write_atomic(const char *final_path,
|
||||
svn_error_t *
|
||||
svn_io_file_trunc(apr_file_t *file, apr_off_t offset, apr_pool_t *pool)
|
||||
{
|
||||
/* Workaround for yet another APR issue with trunc.
|
||||
|
||||
If the APR file internally is in read mode, the current buffer pointer
|
||||
will not be clipped to the valid data range. get_file_offset may then
|
||||
return an invalid position *after* new data was written to it.
|
||||
|
||||
To prevent this, write 1 dummy byte just after the OFFSET at which we
|
||||
will trunc it. That will force the APR file into write mode
|
||||
internally and the flush() work-around below becomes affective. */
|
||||
apr_off_t position = 0;
|
||||
|
||||
/* A frequent usage is OFFSET==0, in which case we don't need to preserve
|
||||
any file content or file pointer. */
|
||||
if (offset)
|
||||
{
|
||||
SVN_ERR(svn_io_file_seek(file, APR_CUR, &position, pool));
|
||||
SVN_ERR(svn_io_file_seek(file, APR_SET, &offset, pool));
|
||||
}
|
||||
SVN_ERR(svn_io_file_putc(0, file, pool));
|
||||
|
||||
/* This is a work-around. APR would flush the write buffer
|
||||
_after_ truncating the file causing now invalid buffered
|
||||
data to be written behind OFFSET. */
|
||||
@ -4052,10 +4072,17 @@ svn_io_file_trunc(apr_file_t *file, apr_off_t offset, apr_pool_t *pool)
|
||||
N_("Can't flush stream"),
|
||||
pool));
|
||||
|
||||
return do_io_file_wrapper_cleanup(file, apr_file_trunc(file, offset),
|
||||
N_("Can't truncate file '%s'"),
|
||||
N_("Can't truncate stream"),
|
||||
pool);
|
||||
SVN_ERR(do_io_file_wrapper_cleanup(file, apr_file_trunc(file, offset),
|
||||
N_("Can't truncate file '%s'"),
|
||||
N_("Can't truncate stream"),
|
||||
pool));
|
||||
|
||||
/* Restore original file pointer, if necessary.
|
||||
It's currently at OFFSET. */
|
||||
if (position < offset)
|
||||
SVN_ERR(svn_io_file_seek(file, APR_SET, &position, pool));
|
||||
|
||||
return SVN_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,7 +136,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) 2016 The Apache Software Foundation.\n"
|
||||
(pool, _("Copyright (C) 2017 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 "
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* This file is automatically generated from wc-checks.sql and .dist_sandbox/subversion-1.9.5/subversion/libsvn_wc/token-map.h.
|
||||
/* This file is automatically generated from wc-checks.sql and .dist_sandbox/subversion-1.9.7/subversion/libsvn_wc/token-map.h.
|
||||
* Do not edit this file -- edit the source and rerun gen-make.py */
|
||||
|
||||
#define STMT_VERIFICATION_TRIGGERS 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* This file is automatically generated from wc-metadata.sql and .dist_sandbox/subversion-1.9.5/subversion/libsvn_wc/token-map.h.
|
||||
/* This file is automatically generated from wc-metadata.sql and .dist_sandbox/subversion-1.9.7/subversion/libsvn_wc/token-map.h.
|
||||
* Do not edit this file -- edit the source and rerun gen-make.py */
|
||||
|
||||
#define STMT_CREATE_SCHEMA 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* This file is automatically generated from wc-queries.sql and .dist_sandbox/subversion-1.9.5/subversion/libsvn_wc/token-map.h.
|
||||
/* This file is automatically generated from wc-queries.sql and .dist_sandbox/subversion-1.9.7/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
|
||||
|
@ -396,6 +396,7 @@ static const svn_opt_subcommand_desc2_t cmd_table[] =
|
||||
("usage: 1. svnadmin freeze REPOS_PATH PROGRAM [ARG...]\n"
|
||||
" 2. svnadmin freeze -F FILE PROGRAM [ARG...]\n\n"
|
||||
"1. Run PROGRAM passing ARGS while holding a write-lock on REPOS_PATH.\n"
|
||||
" Allows safe use of third-party backup tools on a live repository.\n"
|
||||
"\n"
|
||||
"2. Like 1 except all repositories listed in FILE are locked. The file\n"
|
||||
" format is repository paths separated by newlines. Repositories are\n"
|
||||
|
@ -24,7 +24,7 @@
|
||||
For a list of options, run this script with the --help option.
|
||||
"""
|
||||
|
||||
# $HeadURL: http://svn.apache.org/repos/asf/subversion/branches/1.9.x/win-tests.py $
|
||||
# $HeadURL: https://svn.apache.org/repos/asf/subversion/branches/1.9.x/win-tests.py $
|
||||
# $LastChangedRevision: 1718291 $
|
||||
|
||||
import os, sys, subprocess
|
||||
|
Loading…
Reference in New Issue
Block a user