Compare commits

...

No commits in common. 'c9' and 'i8c-stream-1.10' have entirely different histories.

2
.gitignore vendored

@ -1 +1 @@
SOURCES/subversion-1.14.1.tar.bz2
SOURCES/subversion-1.10.2.tar.bz2

@ -1 +1 @@
ee4283c21b5925ee499f8cb9cb0ff546ac7b4b9a SOURCES/subversion-1.14.1.tar.bz2
bc52ef2e671f821998ac9a5f7ebecbbcaaef83b8 SOURCES/subversion-1.10.2.tar.bz2

@ -0,0 +1,72 @@
Link executables using -pie, link test executables using -no-install.
diff -uap subversion-1.10.0/build.conf.pie subversion-1.10.0/build.conf
--- subversion-1.10.0/build.conf.pie
+++ subversion-1.10.0/build.conf
@@ -783,6 +783,7 @@
libs = libsvn_repos libsvn_fs libsvn_delta libsvn_subr aprutil apriconv apr
msvc-static = yes
undefined-lib-symbols = yes
+link-cmd = $(LINK_TEST_LIB)
# ----------------------------------------------------------------------------
# Tests for libsvn_fs_base
diff -uap subversion-1.10.0/build/generator/gen_base.py.pie subversion-1.10.0/build/generator/gen_base.py
--- subversion-1.10.0/build/generator/gen_base.py.pie
+++ subversion-1.10.0/build/generator/gen_base.py
@@ -599,7 +599,7 @@
self.install = options.get('install')
self.compile_cmd = options.get('compile-cmd')
self.sources = options.get('sources', '*.c *.cpp')
- self.link_cmd = options.get('link-cmd', '$(LINK)')
+ self.link_cmd = options.get('link-cmd', '$(LINK_LIB)')
self.external_lib = options.get('external-lib')
self.external_project = options.get('external-project')
@@ -659,6 +659,17 @@
self.msvc_force_static = options.get('msvc-force-static') == 'yes'
+ if self.install in ['test', 'bdb-test', 'sub-test', ]:
+ self.link_cmd = '$(LINK_TEST)'
+ elif self.install in ['cxxhl-tests', ]:
+ self.link_cmd = '$(LINK_TEST_CXX)'
+ elif self.link_cmd == '$(LINK_LIB)':
+ # Over-ride the default for TargetLinked.
+ self.link_cmd = '$(LINK_EXE)'
+ else:
+ raise GenError('ERROR: Unknown executable link type for ' + self.name + \
+ ': ' + self.link_cmd + ' (' + self.install + ')')
+
def add_dependencies(self):
TargetLinked.add_dependencies(self)
diff -uap subversion-1.10.0/Makefile.in.pie subversion-1.10.0/Makefile.in
--- subversion-1.10.0/Makefile.in.pie
+++ subversion-1.10.0/Makefile.in
@@ -268,6 +268,11 @@
LINK_LIB = $(LINK) $(LT_SO_VERSION) -rpath $(libdir)
LINK_CXX = $(LIBTOOL) $(LTCXXFLAGS) --mode=link $(CXX) $(LT_LDFLAGS) $(CXXFLAGS) $(LDFLAGS)
LINK_CXX_LIB = $(LINK_CXX) $(LT_SO_VERSION) -rpath $(libdir)
+LINK_TEST = $(LINK) -no-install
+LINK_TEST_LIB = $(LINK) -avoid-version
+LINK_TEST_CXX_LIB = $(LINK_CXX) -avoid-version
+LINK_EXE = $(LINK) -pie
+LINK_CXX_EXE = $(LINK) -pie
# special link rule for mod_dav_svn
LINK_APACHE_MOD = $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LT_LDFLAGS) $(CFLAGS) $(LDFLAGS) -rpath $(APACHE_LIBEXECDIR) -avoid-version -module $(APACHE_LDFLAGS) -shared
@@ -780,10 +785,10 @@
$(PYTHON) $(top_srcdir)/build/transform_sql.py $< $(top_srcdir)/$@
.c.o:
- $(COMPILE) -o $@ -c $<
+ $(COMPILE) -fPIE -o $@ -c $<
.cpp.o:
- $(COMPILE_CXX) -o $@ -c $<
+ $(COMPILE_CXX) -fPIE -o $@ -c $<
.c.lo:
$(LT_COMPILE) -o $@ -c $<

@ -0,0 +1,42 @@
Only link libraries using -rpath, to avoid unnecessary RPATH tags in executables.
diff -uap subversion-1.10.0/build.conf.rpath subversion-1.10.0/build.conf
--- subversion-1.10.0/build.conf.rpath
+++ subversion-1.10.0/build.conf
@@ -568,7 +568,7 @@
path = subversion/bindings/swig/python/libsvn_swig_py
libs = libsvn_client libsvn_wc libsvn_ra libsvn_delta libsvn_subr
apriconv apr python swig
-link-cmd = $(LINK)
+link-cmd = $(LINK_LIB)
install = swig-py-lib
# need special build rule to include -DSWIGPYTHON
compile-cmd = $(COMPILE_SWIG_PY)
@@ -594,7 +594,7 @@
lang = ruby
path = subversion/bindings/swig/ruby/libsvn_swig_ruby
libs = libsvn_client libsvn_wc libsvn_delta libsvn_subr apriconv apr ruby swig
-link-cmd = $(LINK) $(SWIG_RB_LIBS)
+link-cmd = $(LINK_LIB) $(SWIG_RB_LIBS)
install = swig-rb-lib
# need special build rule to include
compile-cmd = $(COMPILE_SWIG_RB)
diff -uap subversion-1.10.0/Makefile.in.rpath subversion-1.10.0/Makefile.in
--- subversion-1.10.0/Makefile.in.rpath
+++ subversion-1.10.0/Makefile.in
@@ -264,10 +264,10 @@
COMPILE_GOOGLEMOCK_CXX = $(LT_COMPILE_CXX_NOWARN) $(GOOGLEMOCK_LIB_INCLUDES) -o $@ -c
COMPILE_CXXHL_GOOGLEMOCK_CXX = $(LT_COMPILE_CXX) $(CXXHL_INCLUDES) $(GOOGLEMOCK_INCLUDES) -o $@ -c
-LINK = $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LT_LDFLAGS) $(CFLAGS) $(LDFLAGS) -rpath $(libdir)
-LINK_LIB = $(LINK) $(LT_SO_VERSION)
-LINK_CXX = $(LIBTOOL) $(LTCXXFLAGS) --mode=link $(CXX) $(LT_LDFLAGS) $(CXXFLAGS) $(LDFLAGS) -rpath $(libdir)
-LINK_CXX_LIB = $(LINK_CXX) $(LT_SO_VERSION)
+LINK = $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LT_LDFLAGS) $(CFLAGS) $(LDFLAGS)
+LINK_LIB = $(LINK) $(LT_SO_VERSION) -rpath $(libdir)
+LINK_CXX = $(LIBTOOL) $(LTCXXFLAGS) --mode=link $(CXX) $(LT_LDFLAGS) $(CXXFLAGS) $(LDFLAGS)
+LINK_CXX_LIB = $(LINK_CXX) $(LT_SO_VERSION) -rpath $(libdir)
# special link rule for mod_dav_svn
LINK_APACHE_MOD = $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LT_LDFLAGS) $(CFLAGS) $(LDFLAGS) -rpath $(APACHE_LIBEXECDIR) -avoid-version -module $(APACHE_LDFLAGS) -shared

@ -0,0 +1,221 @@
https://bugzilla.redhat.com/show_bug.cgi?id=17330884
https://subversion.apache.org/security/CVE-2018-11782-advisory.txt
Fixes for CVE-2018-11782, svnserve get-deleted-rev assertion failure.
The svn protocol prototype for get-deleted-rev does not allow for a reply of
SVN_INVALID_REVNUM directly. A query having such an answer previously caused
the server to raise an assertion failure which could crash the whole process
or a thread or child process of it, depending on the build configuration of
the server.
To work around the problem without changing the protocol, we re-purpose the
obsolete error code 'SVN_ERR_ENTRY_MISSING_REVISION' to communicate this
'not deleted' reply to the client.
- With a new client against a new server, such queries are now handled
correctly.
- With an old client against a new server, the client will report a more
informative error message, and the server will not crash.
- With a new client against an old server, the behaviour is the same as
with an old client against an old server.
In addition, this fixes a similar problem whereby any regular error response
to a 'get-deleted-rev' query resulted in the server closing the connection,
process and/or thread (again depending on the build configuration). Now such
errors are correctly passed back to the client.
* subversion/libsvn_ra_svn/client.c
(ra_svn_get_deleted_rev): Detect error SVN_ERR_ENTRY_MISSING_REVISION
and convert it to a response of SVN_INVALID_REVNUM.
* subversion/svnserve/serve.c
(get_deleted_rev): Respond with error SVN_ERR_ENTRY_MISSING_REVISION
instead of an assertion failure if the answer is SVN_INVALID_REVNUM.
If svn_repos_deleted_rev() returns an error, pass that error back to
the client.
* subversion/tests/libsvn_ra/ra-test.c
(commit_two_changes): New.
(test_get_deleted_rev_no_delete,
test_get_deleted_rev_errors): New tests.
(test_funcs): Run them.
--This line, and those below, will be ignored--
Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion-1.10.2/subversion/libsvn_ra_svn/client.c.cve11782
+++ subversion-1.10.2/subversion/libsvn_ra_svn/client.c
@@ -3105,6 +3105,7 @@
{
svn_ra_svn__session_baton_t *sess_baton = session->priv;
svn_ra_svn_conn_t *conn = sess_baton->conn;
+ svn_error_t *err;
path = reparent_path(session, path, pool);
@@ -3116,8 +3117,20 @@
SVN_ERR(handle_unsupported_cmd(handle_auth_request(sess_baton, pool),
N_("'get-deleted-rev' not implemented")));
- return svn_error_trace(svn_ra_svn__read_cmd_response(conn, pool, "r",
- revision_deleted));
+ err = svn_error_trace(svn_ra_svn__read_cmd_response(conn, pool, "r",
+ revision_deleted));
+ /* The protocol does not allow for a reply of SVN_INVALID_REVNUM directly.
+ Instead, a new enough server returns SVN_ERR_ENTRY_MISSING_REVISION to
+ indicate the answer to the query is SVN_INVALID_REVNUM. (An older server
+ closes the connection and returns SVN_ERR_RA_SVN_CONNECTION_CLOSED.) */
+ if (err && err->apr_err == SVN_ERR_ENTRY_MISSING_REVISION)
+ {
+ *revision_deleted = SVN_INVALID_REVNUM;
+ svn_error_clear(err);
+ }
+ else
+ SVN_ERR(err);
+ return SVN_NO_ERROR;
}
static svn_error_t *
--- subversion-1.10.2/subversion/svnserve/serve.c.cve11782
+++ subversion-1.10.2/subversion/svnserve/serve.c
@@ -3505,8 +3505,21 @@
svn_relpath_canonicalize(path, pool), pool);
SVN_ERR(log_command(b, conn, pool, "get-deleted-rev"));
SVN_ERR(trivial_auth_request(conn, pool, b));
- SVN_ERR(svn_repos_deleted_rev(b->repository->fs, full_path, peg_revision,
- end_revision, &revision_deleted, pool));
+ SVN_CMD_ERR(svn_repos_deleted_rev(b->repository->fs, full_path, peg_revision,
+ end_revision, &revision_deleted, pool));
+
+ /* The protocol does not allow for a reply of SVN_INVALID_REVNUM directly.
+ Instead, return SVN_ERR_ENTRY_MISSING_REVISION. A new enough client
+ knows that this means the answer to the query is SVN_INVALID_REVNUM.
+ (An older client reports this as an error.) */
+ if (revision_deleted == SVN_INVALID_REVNUM)
+ SVN_CMD_ERR(svn_error_createf(SVN_ERR_ENTRY_MISSING_REVISION, NULL,
+ "svn protocol command 'get-deleted-rev': "
+ "path '%s' was not deleted in r%ld-%ld; "
+ "NOTE: newer clients handle this case "
+ "and do not report it as an error",
+ full_path, peg_revision, end_revision));
+
SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, "r", revision_deleted));
return SVN_NO_ERROR;
}
--- subversion-1.10.2/subversion/tests/libsvn_ra/ra-test.c.cve11782
+++ subversion-1.10.2/subversion/tests/libsvn_ra/ra-test.c
@@ -94,6 +94,41 @@
return SVN_NO_ERROR;
}
+/* Commit two revisions: add 'B', then delete 'A' */
+static svn_error_t *
+commit_two_changes(svn_ra_session_t *session,
+ apr_pool_t *pool)
+{
+ apr_hash_t *revprop_table = apr_hash_make(pool);
+ const svn_delta_editor_t *editor;
+ void *edit_baton;
+ void *root_baton, *dir_baton;
+
+ /* mkdir B */
+ SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+ revprop_table,
+ NULL, NULL, NULL, TRUE, pool));
+ SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM,
+ pool, &root_baton));
+ SVN_ERR(editor->add_directory("B", root_baton, NULL, SVN_INVALID_REVNUM,
+ pool, &dir_baton));
+ SVN_ERR(editor->close_directory(dir_baton, pool));
+ SVN_ERR(editor->close_directory(root_baton, pool));
+ SVN_ERR(editor->close_edit(edit_baton, pool));
+
+ /* delete A */
+ SVN_ERR(svn_ra_get_commit_editor3(session, &editor, &edit_baton,
+ revprop_table,
+ NULL, NULL, NULL, TRUE, pool));
+ SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM,
+ pool, &root_baton));
+ SVN_ERR(editor->delete_entry("A", SVN_INVALID_REVNUM, root_baton, pool));
+ SVN_ERR(editor->close_directory(root_baton, pool));
+ SVN_ERR(editor->close_edit(edit_baton, pool));
+
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
commit_tree(svn_ra_session_t *session,
apr_pool_t *pool)
@@ -1784,6 +1819,56 @@
return SVN_NO_ERROR;
}
+/* Cases of 'get-deleted-rev' that should return SVN_INVALID_REVNUM. */
+static svn_error_t *
+test_get_deleted_rev_no_delete(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_ra_session_t *ra_session;
+ svn_revnum_t revision_deleted;
+
+ SVN_ERR(make_and_open_repos(&ra_session,
+ "test-repo-get-deleted-rev-no-delete", opts,
+ pool));
+ SVN_ERR(commit_changes(ra_session, pool));
+ SVN_ERR(commit_two_changes(ra_session, pool));
+
+ /* expect 'no deletion' in the range up to r2, when it is deleted in r3 */
+ /* This was failing over RA-SVN where the 'get-deleted-rev' wire command's
+ prototype cannot directly represent that result. A new enough client and
+ server collaborate on a work-around implemented using an error code. */
+ SVN_ERR(svn_ra_get_deleted_rev(ra_session, "A", 1, 2,
+ &revision_deleted, pool));
+ SVN_TEST_INT_ASSERT(revision_deleted, SVN_INVALID_REVNUM);
+
+ /* this connection should still be open: a simple case should still work */
+ SVN_ERR(svn_ra_get_deleted_rev(ra_session, "A", 1, 3,
+ &revision_deleted, pool));
+ SVN_TEST_INT_ASSERT(revision_deleted, 3);
+
+ return SVN_NO_ERROR;
+}
+
+/* Cases of 'get-deleted-rev' that should return an error. */
+static svn_error_t *
+test_get_deleted_rev_errors(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_ra_session_t *ra_session;
+ svn_revnum_t revision_deleted;
+
+ SVN_ERR(make_and_open_repos(&ra_session,
+ "test-repo-get-deleted-rev-errors", opts, pool));
+ SVN_ERR(commit_changes(ra_session, pool));
+
+ /* expect an error when searching up to r3, when repository head is r1 */
+ SVN_TEST_ASSERT_ERROR(svn_ra_get_deleted_rev(ra_session, "A", 1, 3,
+ &revision_deleted, pool),
+ SVN_ERR_FS_NO_SUCH_REVISION);
+
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
@@ -1820,6 +1905,10 @@
"check how last change applies to empty commit"),
SVN_TEST_OPTS_PASS(commit_locked_file,
"check commit editor for a locked file"),
+ SVN_TEST_OPTS_PASS(test_get_deleted_rev_no_delete,
+ "test get-deleted-rev no delete"),
+ SVN_TEST_OPTS_PASS(test_get_deleted_rev_errors,
+ "test get-deleted-rev errors"),
SVN_TEST_NULL
};

@ -0,0 +1,31 @@
diff --git a/subversion/svnserve/serve.c b/subversion/svnserve/serve.c
index 5192e7c..6159e22 100644
--- a/subversion/svnserve/serve.c
+++ b/subversion/svnserve/serve.c
@@ -4101,7 +4101,7 @@ construct_server_baton(server_baton_t **baton,
serve_params_t *params,
apr_pool_t *scratch_pool)
{
- svn_error_t *err, *io_err;
+ svn_error_t *err;
apr_uint64_t ver;
const char *client_url, *ra_client_string, *client_string;
svn_ra_svn__list_t *caplist;
@@ -4239,11 +4239,12 @@ construct_server_baton(server_baton_t **baton,
}
if (err)
{
- log_error(err, b);
- io_err = svn_ra_svn__write_cmd_failure(conn, scratch_pool, err);
- svn_error_clear(err);
- SVN_ERR(io_err);
- return svn_ra_svn__flush(conn, scratch_pool);
+ /* Report these errors to the client before closing the connection. */
+ err = svn_error_compose_create(err,
+ svn_ra_svn__write_cmd_failure(conn, scratch_pool, err));
+ err = svn_error_compose_create(err,
+ svn_ra_svn__flush(conn, scratch_pool));
+ return err;
}
SVN_ERR(svn_fs_get_uuid(b->repository->fs, &b->repository->uuid,

@ -0,0 +1,17 @@
https://bugzilla.redhat.com/show_bug.cgi?id=1922303
https://github.com/apache/subversion/commit/c83d9e5db564bdbbd91a7eb1c9399f66f481361c
--- a/subversion/libsvn_repos/config_file.c
+++ b/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,

@ -1,5 +1,5 @@
--- subversion-1.14.1/subversion/libsvn_repos/authz.c
+++ subversion-1.14.1/subversion/libsvn_repos/authz.c
--- subversion-1.10.2/subversion/libsvn_repos/authz.c
+++ subversion-1.10.2/subversion/libsvn_repos/authz.c
@@ -130,6 +130,30 @@
static svn_object_pool__t *filtered_pool = NULL;
static svn_atomic_t authz_pool_initialized = FALSE;

@ -1,84 +0,0 @@
Fix the way libtool is used to match standard practice:
a) link ONLY libraries using -rpath $(libdir), not executables
.. this avoids adding an RPATH for $libdir to executables
b) link non-installable test binaries using -no-install
.. only for convenience but should speed up builds slightly(?)
--- subversion-1.12.0/build.conf.linking
+++ subversion-1.12.0/build.conf
@@ -572,7 +572,7 @@
path = subversion/bindings/swig/python/libsvn_swig_py
libs = libsvn_client libsvn_wc libsvn_ra libsvn_delta libsvn_subr
apriconv apr python swig
-link-cmd = $(LINK)
+link-cmd = $(LINK_LIB)
install = swig-py-lib
# need special build rule to include -DSWIGPYTHON
compile-cmd = $(COMPILE_SWIG_PY)
@@ -598,7 +598,7 @@
lang = ruby
path = subversion/bindings/swig/ruby/libsvn_swig_ruby
libs = libsvn_client libsvn_wc libsvn_delta libsvn_subr apriconv apr ruby swig
-link-cmd = $(LINK) $(SWIG_RB_LIBS)
+link-cmd = $(LINK_LIB) $(SWIG_RB_LIBS)
install = swig-rb-lib
# need special build rule to include
compile-cmd = $(COMPILE_SWIG_RB)
@@ -769,6 +769,7 @@
libs = libsvn_repos libsvn_fs libsvn_delta libsvn_subr aprutil apriconv apr
msvc-static = yes
undefined-lib-symbols = yes
+link-cmd = $(LINK_TEST_LIB)
# ----------------------------------------------------------------------------
# Tests for libsvn_fs_base
--- subversion-1.12.0/build/generator/gen_base.py.linking
+++ subversion-1.12.0/build/generator/gen_base.py
@@ -599,7 +599,7 @@
self.install = options.get('install')
self.compile_cmd = options.get('compile-cmd')
self.sources = options.get('sources', '*.c *.cpp')
- self.link_cmd = options.get('link-cmd', '$(LINK)')
+ self.link_cmd = options.get('link-cmd', '$(LINK_LIB)')
self.external_lib = options.get('external-lib')
self.external_project = options.get('external-project')
@@ -659,6 +659,14 @@
self.msvc_force_static = options.get('msvc-force-static') == 'yes'
+ if self.install in ['test', 'bdb-test', 'sub-test', ]:
+ self.link_cmd = '$(LINK_TEST)'
+ elif self.install in ['bin', 'tools']:
+ self.link_cmd = '$(LINK_EXE)'
+ elif self.link_cmd == '$(LINK_LIB)':
+ raise GenError('ERROR: Unknown executable link type for ' + self.name + \
+ ': ' + self.link_cmd + ' (' + self.install + ')')
+
def add_dependencies(self):
TargetLinked.add_dependencies(self)
--- subversion-1.12.0/Makefile.in.linking
+++ subversion-1.12.0/Makefile.in
@@ -268,11 +268,14 @@
COMPILE_SVNXX = $(LT_COMPILE_CXX) $(SVNXX_INCLUDES) -o $@ -c
COMPILE_SVNXX_TEST = $(LT_COMPILE_CXX) $(SVNXX_INCLUDES) $(BOOST_TEST_CPPFLAGS) -o $@ -c
-LINK = $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LT_LDFLAGS) $(CFLAGS) $(LDFLAGS) -rpath $(libdir)
-LINK_LIB = $(LINK) $(LT_SO_VERSION)
-LINK_CXX = $(LIBTOOL) $(LTCXXFLAGS) --mode=link $(CXX) $(LT_LDFLAGS) $(CXXFLAGS) $(LDFLAGS) -rpath $(libdir)
-LINK_CXX_LIB = $(LINK_CXX) $(LT_SO_VERSION)
-LINK_SVNXX_TEST = $(LINK_CXX) $(BOOST_TEST_LDFLAGS)
+LINK = $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LT_LDFLAGS) $(CFLAGS) $(LDFLAGS)
+LINK_LIB = $(LINK) $(LT_SO_VERSION) -rpath $(libdir)
+LINK_CXX = $(LIBTOOL) $(LTCXXFLAGS) --mode=link $(CXX) $(LT_LDFLAGS) $(CXXFLAGS) $(LDFLAGS)
+LINK_CXX_LIB = $(LINK_CXX) $(LT_SO_VERSION) -rpath $(libdir)
+LINK_SVNXX_TEST = $(LINK_CXX) $(BOOST_TEST_LDFLAGS) -no-install
+LINK_TEST = $(LINK) -no-install
+LINK_TEST_LIB = $(LINK_TEST) -avoid-version
+LINK_EXE = $(LINK)
# special link rule for mod_dav_svn
LINK_APACHE_MOD = $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LT_LDFLAGS) $(CFLAGS) $(LDFLAGS) -rpath $(APACHE_LIBEXECDIR) -avoid-version -module $(APACHE_LDFLAGS) -shared

@ -1,19 +0,0 @@
Use the minor version as the revision in the libtool version, so the library
soversion is not always 0.0.0. (Does not influence the soname)
--- subversion-1.14.0/configure.ac.soversion
+++ subversion-1.14.0/configure.ac
@@ -112,7 +112,11 @@
SVN_APR_MAJOR_VERSION=1
fi
AC_SUBST(SVN_APR_MAJOR_VERSION)
-SVN_LT_SOVERSION="-version-info $svn_lib_ver"
+
+m4_define([svn_ver_minor], m4_bpatsubst(AC_PACKAGE_VERSION, [[0-9]*\.\([0-9]*\)\.[0-9]*], [\1]))
+
+SVN_LT_SOVERSION="-version-info $svn_lib_ver:svn_ver_minor"
+AC_MSG_NOTICE([SVN_LT_SOVERSION $SVN_LT_SOVERSION])
AC_SUBST(SVN_LT_SOVERSION)
AC_DEFINE_UNQUOTED(SVN_SOVERSION, $svn_lib_ver,
[Subversion library major verson])

@ -1,14 +0,0 @@
Suppress gcc 10 warning.
--- subversion-1.14.0/subversion/tests/svn_test.h.testwarn
+++ subversion-1.14.0/subversion/tests/svn_test.h
@@ -128,7 +128,7 @@
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, \
"Strings not equal\n Expected: '%s'\n Found: '%s'" \
"\n at %s:%d", \
- tst_str2, tst_str1, __FILE__, __LINE__); \
+ tst_str2 ? tst_str2 : "(NULL)", tst_str1 ? tst_str1 : "(NULL)", __FILE__, __LINE__); \
} while(0)
/** Handy macro for testing integer equality.

@ -1,30 +0,0 @@
See upstream dev@subversion thread. Fixes intermittent failure of
javahl tests, particularly reproducible on aarch64.
Message-ID: <11de5f5c-5059-b973-95a1-385e7913a63a@syntevo.com>
From: Alexandr Miloslavskiy
--- subversion-1.14.1/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java.fixjavatests
+++ subversion-1.14.1/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
@@ -4676,7 +4676,19 @@
// RuntimeException("Test exception") is expected here
}
- tunnelAgent.joinAndTest();
+ // In this test, there is a race condition that sometimes results in
+ // IOException when 'WAIT_TUNNEL' tries to read from a pipe that
+ // already has its read end closed. This is not an error, but
+ // it's hard to distinguish this case from other IOException which
+ // indicate a problem. To reproduce, simply wrap this test's body in
+ // a loop. The workaround is to ignore any detected IOException.
+ //
+ // tunnelAgent.joinAndTest();
+ try {
+ tunnelAgent.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace ();
+ }
}
/**

@ -1,14 +0,0 @@
Fix intermittent failures when "svn add" guesses a near-empty file is binary and hence
the output is different.
--- subversion-1.14.1/subversion/tests/cmdline/svntest/main.py.testnoautoprops
+++ subversion-1.14.1/subversion/tests/cmdline/svntest/main.py
@@ -691,6 +691,7 @@
[miscellany]
interactive-conflicts = false
+enable-auto-props = no
"""
if exclusive_wc_locks:
config_contents += """

@ -1,30 +1,11 @@
# set to zero to avoid running test suite
%bcond_without tests
%if 0%{?rhel} || 0%{?eln}
%bcond_with kwallet
%else
%bcond_without kwallet
%endif
%if 0%{?fedora} > 32 || 0%{?rhel} > 8
%bcond_with bdb
%else
%bcond_without bdb
%endif
# Python 2 for F<32, Python 3 for F>=32 and RHEL>=9
%if 0%{?fedora} < 32 && 0%{?rhel} < 9
%bcond_without python2
%bcond_with python3
%bcond_without bdb
%bcond_without tests
%bcond_without pyswig
%bcond_without ruby
%else
%bcond_with python2
%bcond_without python3
%bcond_without pyswig
%bcond_without ruby
%endif
%ifarch %{power64} s390x
%global with_java 0
@ -55,11 +36,13 @@
Summary: A Modern Concurrent Version Control System
Name: subversion
Version: 1.14.1
Version: 1.10.2
Release: 5%{?dist}
License: ASL 2.0
Group: Development/Tools
URL: https://subversion.apache.org/
Source0: https://downloads.apache.org/subversion/subversion-%{version}.tar.bz2
Source0: https://www.apache.org/dist/subversion/subversion-%{version}.tar.bz2
Source1: subversion.conf
Source3: filter-requires.sh
Source4: http://www.xsteve.at/prg/emacs/psvn.el
@ -67,24 +50,22 @@ Source5: psvn-init.el
Source6: svnserve.service
Source7: svnserve.tmpfiles
Source8: svnserve.sysconf
Patch1: subversion-1.12.0-linking.patch
Patch2: subversion-1.14.0-testwarn.patch
Patch3: subversion-1.14.0-soversion.patch
Patch1: subversion-1.10.0-rpath.patch
Patch2: subversion-1.10.0-pie.patch
Patch4: subversion-1.8.0-rubybind.patch
Patch5: subversion-1.8.5-swigplWall.patch
Patch6: subversion-1.14.1-testnoautoprops.patch
Patch7: subversion-1.14.1-fixjavatests.patch
Patch8: subversion-1.14.1-CVE-2022-24070.patch
Patch6: subversion-1.10.2-CVE-2019-0203.patch
Patch7: subversion-1.10.2-CVE-2018-11782.patch
Patch8: subversion-1.10.2-CVE-2020-17525.patch
Patch9: subversion-1.10.2-CVE-2022-24070.patch
BuildRequires: make
BuildRequires: autoconf, libtool, texinfo, which, gcc, gcc-c++
BuildRequires: autoconf, libtool, texinfo, which
BuildRequires: swig >= 1.3.24, gettext
%if %{with bdb}
BuildRequires: libdb-devel >= 4.1.25
%endif
BuildRequires: %{svn_python_br}
BuildRequires: apr-devel >= 1.5.0, apr-util-devel >= 1.3.0
BuildRequires: apr-devel >= 1.3.0, apr-util-devel >= 1.3.0
BuildRequires: libserf-devel >= 1.3.0, cyrus-sasl-devel
BuildRequires: sqlite-devel >= 3.4.0, file-devel, systemd-units
BuildRequires: utf8proc-devel, lz4-devel
@ -111,9 +92,10 @@ instead of every complete file. Subversion is intended to be a
compelling replacement for CVS.
%package libs
Group: Development/Tools
Summary: Libraries for Subversion Version Control system
# APR 1.3.x interfaces are required
Conflicts: apr%{?_isa} < 1.5.0
Conflicts: apr%{?_isa} < 1.3.0
# Enforced at run-time by ra_serf
Conflicts: libserf%{?_isa} < 1.3.0
@ -129,6 +111,7 @@ Provides: %{name}-python = %{version}-%{release}
Provides: %{name}-python%{?_isa} = %{version}-%{release}
Obsoletes: %{name}-python < %{version}-%{release}
BuildRequires: python2-devel
Group: Development/Libraries
Summary: Python bindings for Subversion Version Control system
%description -n python2-subversion
@ -138,9 +121,9 @@ Subversion libraries.
%if %{with python3} && %{with pyswig}
%package -n python3-subversion
%{?python_provide:%python_provide python3-subversion}
Group: Development/Libraries
Summary: Python bindings for Subversion Version Control system
BuildRequires: python3-devel py3c-devel
Requires: subversion-libs%{?_isa} = %{version}-%{release}
BuildRequires: python3-devel
%description -n python3-subversion
The python3-subversion package includes the Python 3.x bindings to the
@ -148,8 +131,9 @@ Subversion libraries.
%endif
%package devel
Group: Development/Tools
Summary: Development package for the Subversion libraries
Requires: subversion-libs%{?_isa} = %{version}-%{release}
Requires: subversion%{?_isa} = %{version}-%{release}
Requires: apr-devel%{?_isa}, apr-util-devel%{?_isa}
%description devel
@ -157,8 +141,9 @@ The subversion-devel package includes the libraries and include files
for developers interacting with the subversion package.
%package gnome
Group: Development/Tools
Summary: GNOME Keyring support for Subversion
Requires: subversion-libs%{?_isa} = %{version}-%{release}
Requires: subversion%{?_isa} = %{version}-%{release}
BuildRequires: dbus-devel, libsecret-devel
%description gnome
@ -167,10 +152,10 @@ passwords in the GNOME Keyring.
%if %{with kwallet}
%package kde
Group: Development/Tools
Summary: KDE Wallet support for Subversion
Requires: subversion-libs%{?_isa} = %{version}-%{release}
BuildRequires: qt5-qtbase-devel >= 5.0.0, kf5-kwallet-devel, kf5-ki18n-devel
BuildRequires: kf5-kcoreaddons-devel
Requires: subversion%{?_isa} = %{version}-%{release}
BuildRequires: kdelibs-devel >= 4.0.0
%description kde
The subversion-kde package adds support for storing Subversion
@ -178,6 +163,7 @@ passwords in the KDE Wallet.
%endif
%package -n mod_dav_svn
Group: System Environment/Daemons
Summary: Apache httpd module for Subversion server
Requires: httpd-mmn = %{_httpd_mmn}
Requires: subversion-libs%{?_isa} = %{version}-%{release}
@ -188,20 +174,22 @@ The mod_dav_svn package allows access to a Subversion repository
using HTTP, via the Apache httpd server.
%package perl
Group: Development/Libraries
Summary: Perl bindings to the Subversion libraries
BuildRequires: perl-devel >= 2:5.8.0, perl-generators, perl(ExtUtils::MakeMaker)
BuildRequires: perl(Test::More), perl(ExtUtils::Embed)
Requires: %(eval `perl -V:version`; echo "perl(:MODULE_COMPAT_$version)")
Requires: subversion-libs%{?_isa} = %{version}-%{release}
Requires: subversion%{?_isa} = %{version}-%{release}
%description perl
This package includes the Perl bindings to the Subversion libraries.
%if %{with_java}
%package javahl
Group: Development/Libraries
Summary: JNI bindings to the Subversion libraries
Requires: subversion = %{version}-%{release}
BuildRequires: java-11-openjdk-devel
BuildRequires: java-devel-openjdk
# JAR repacking requires both zip and unzip in the buildroot
BuildRequires: zip, unzip
# For the tests
@ -212,57 +200,46 @@ BuildArch: noarch
This package includes the JNI bindings to the Subversion libraries.
%endif
%if %{with ruby}
%package ruby
Group: Development/Libraries
Summary: Ruby bindings to the Subversion libraries
BuildRequires: ruby-devel >= 1.9.1, ruby >= 1.9.1
BuildRequires: rubygem(test-unit)
Requires: subversion-libs%{?_isa} = %{version}-%{release}
Requires: subversion%{?_isa} = %{version}-%{release}
Conflicts: ruby-libs%{?_isa} < 1.8.2
%description ruby
This package includes the Ruby bindings to the Subversion libraries.
%endif
%package tools
Group: Development/Tools
Summary: Supplementary tools for Subversion
Requires: subversion-libs%{?_isa} = %{version}-%{release}
Requires: subversion%{?_isa} = %{version}-%{release}
%description tools
This package includes supplementary tools for use with Subversion.
%prep
%setup -q
%patch1 -p1 -b .linking
%patch2 -p1 -b .testwarn
%patch3 -p1 -b .soversion
%patch1 -p1 -b .rpath
%patch2 -p1 -b .pie
%patch4 -p1 -b .rubybind
%patch5 -p1 -b .swigplWall
%patch6 -p1 -b .testnoautoprops
%patch7 -p1 -b .fixjavatests
%patch8 -p1 -b .cve24070
:
: === Building:
: === Python3=%{with python3} Python2=%{with python2} PySwig=%{with pyswig}
: === Java=%{with_java} Ruby=%{with ruby}
: === BDB=%{with bdb} Tests=%{with tests} KWallet=%{with kwallet}
:
%patch6 -p1 -b .cve0203
%patch7 -p1 -b .cve11782
%patch8 -p1 -b .cve17525
%patch9 -p1 -b .cve24070
%build
# Regenerate the buildsystem, so that any patches applied to
# configure, swig bindings etc take effect.
# Regenerate the buildsystem, so that:
# 1) patches applied to configure.in take effect
# 2) the swig bindings are regenerated using the system swig
# (2) is not ideal since typically upstream test with a different
# swig version
# This PATH order makes the fugly test for libtoolize work...
mv build-outputs.mk build-outputs.mk.old
export PYTHON=%{svn_python}
### Force regeneration of swig bindings with the buildroot's SWIG.
# Generated files depend on the build/generator/swig/*.py which
# generates them, so when autogen-standalone.mk's autogen-swig target
# is run by autogen.sh it will regenerate them:
touch build/generator/swig/*.py
### Regenerate everything:
# This PATH order makes the fugly test for libtoolize work...
PATH=/usr/bin:$PATH ./autogen.sh --release
# fix shebang lines, #111498
@ -274,10 +251,6 @@ perl -pi -e 's|/usr/bin/env python.*|%{svn_python}|' subversion/tests/cmdline/sv
export svn_cv_ruby_link="%{__cc} -shared"
export svn_cv_ruby_sitedir_libsuffix=""
export svn_cv_ruby_sitedir_archsuffix=""
%if 0%{?fedora} >= 32 || 0%{?rhel} >= 9
# Fix include path for ruby2.7
export svn_cv_ruby_includes="-I%{_includedir}"
%endif
#export EXTRA_CFLAGS="$RPM_OPT_FLAGS -DSVN_SQLITE_MIN_VERSION_NUMBER=3007012 \
# -DSVN_SQLITE_MIN_VERSION=\\\"3.7.12\\\""
@ -286,7 +259,6 @@ export CC=gcc CXX=g++ JAVA_HOME=%{jdk_path}
%configure --with-apr=%{_prefix} --with-apr-util=%{_prefix} \
--disable-debug \
--enable-plaintext-password-storage \
--with-swig --with-serf=%{_prefix} \
--with-ruby-sitedir=%{ruby_vendorarchdir} \
--with-ruby-test-verbose=verbose \
@ -300,7 +272,7 @@ export CC=gcc CXX=g++ JAVA_HOME=%{jdk_path}
--with-junit=%{_prefix}/share/java/junit.jar \
%endif
%if %{with kwallet}
--with-kwallet=%{_includedir}:%{_libdir} \
--with-kwallet=%{_includedir}/kde4:%{_libdir}/kde4/devel \
%endif
%if %{with bdb}
--with-berkeley-db \
@ -312,10 +284,7 @@ make %{?_smp_mflags} all tools
%if %{with pyswig}
make swig-py swig-py-lib %{swigdirs}
%endif
make swig-pl swig-pl-lib
%if %{with ruby}
make swig-rb swig-rb-lib
%endif
make swig-pl swig-pl-lib swig-rb swig-rb-lib
%if %{with_java}
# javahl-javah does not parallel-make with javahl
#make javahl-java javahl-javah
@ -396,9 +365,6 @@ sed -i "/^dependency_libs/{
s,%{_libdir}/lib[^a][^p][^r][^ ']*.la, ,g;
}" $RPM_BUILD_ROOT%{_libdir}/*.la
# Trim libdir in pkgconfig files to avoid multilib conflicts
sed -i '/^libdir=/d' $RPM_BUILD_ROOT%{_datadir}/pkgconfig/libsvn*.pc
# Install bash completion
install -Dpm 644 tools/client-side/bash_completion \
$RPM_BUILD_ROOT%{_datadir}/bash-completion/completions/svn
@ -469,13 +435,9 @@ fi
%endif
# check-swig-rb omitted: it runs svnserve
%if %{with_java}
%ifnarch aarch64
# Breaks reliably on aarch64, timing issue?
# Upstream discussion: https://lists.apache.org/x/thread.html/rff2b0ab98a30c5fc83ca5ab21bf3862036d3a5ac2fc768d027bb6fe4@%3Cdev.subversion.apache.org%3E
make check-javahl
%endif
%endif
%endif
%post
%systemd_post svnserve.service
@ -486,14 +448,22 @@ make check-javahl
%postun
%systemd_postun_with_restart svnserve.service
%ldconfig_scriptlets libs
%post libs -p /sbin/ldconfig
%ldconfig_scriptlets perl
%postun libs -p /sbin/ldconfig
%ldconfig_scriptlets ruby
%post perl -p /sbin/ldconfig
%postun perl -p /sbin/ldconfig
%post ruby -p /sbin/ldconfig
%postun ruby -p /sbin/ldconfig
%if %{with_java}
%ldconfig_scriptlets javahl
%post javahl -p /sbin/ldconfig
%postun javahl -p /sbin/ldconfig
%endif
%files -f %{name}.files
@ -514,10 +484,7 @@ make check-javahl
%{_prefix}/lib/tmpfiles.d/svnserve.conf
%files tools -f tools.files
%doc tools/hook-scripts tools/backup tools/examples tools/xslt
%if %{with bdb}
%doc tools/bdb
%endif
%doc tools/hook-scripts tools/backup tools/bdb tools/examples tools/xslt
%files libs
%{!?_licensedir:%global license %%doc}
@ -574,11 +541,9 @@ make check-javahl
%{_libdir}/libsvn_swig_perl*
%{_mandir}/man*/*::*
%if %{with ruby}
%files ruby
%{_libdir}/libsvn_swig_ruby*
%{ruby_vendorarchdir}/svn
%endif
%if %{with_java}
%files javahl
@ -586,123 +551,21 @@ make check-javahl
%endif
%changelog
* Tue Apr 26 2022 Richard Lescak <rlescak@redhat.com> - 1.14.1-5
- Fix for CVE-2022-24070 (#2076565)
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 1.14.1-4.1
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Tue Jun 22 2021 Mohan Boddu <mboddu@redhat.com> - 1.14.1-3.1
- Rebuilt for RHEL 9 BETA for openssl 3.0
Related: rhbz#1971065
* Wed Apr 28 2021 Joe Orton <jorton@redhat.com> - 1.14.1-2.1
- enable plaintext password storage (#1951484)
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.14.1-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Wed Feb 10 2021 Joe Orton <jorton@redhat.com> - 1.14.1-1
- update to 1.14.1 (#1927265, #1768698)
* Wed Jan 27 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.14.0-12
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Wed Jan 06 2021 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.14.0-11
- F-34: rebuild against ruby 3.0
* Fri Dec 11 2020 Joe Orton <jorton@redhat.com> - 1.14.0-10
- strip libdir from pkgconfig files
- add missing -libs dep from python3-subversion
* Thu Dec 3 2020 Joe Orton <jorton@redhat.com> - 1.14.0-9
- fix KWallet conditional (#1902598)
* Mon Nov 30 2020 Jan Grulich <jgrulich@redhat.com> - 1.14.0-8
- Disable KWallet for RHEL and ELN
Resolves: bz#1902598
* Tue Sep 29 2020 Joe Orton <jorton@redhat.com> - 1.14.0-7
- bump required apr-devel
- BR gcc, gcc-c++
* Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.14.0-6
- Second attempt - Rebuilt for
https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.14.0-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue Jun 23 2020 Jitka Plesnikova <jplesnik@redhat.com> - 1.14.0-4
- Perl 5.32 rebuild
* Wed Jun 3 2020 Merlin Mathesius <mmathesi@redhat.com> - 1.14.0-3
- Minor conditional fixes for ELN
* Wed Jun 3 2020 Joe Orton <jorton@redhat.com> - 1.14.0-2
- use minor version as libtool library revision number
* Mon Jun 1 2020 Joe Orton <jorton@redhat.com> - 1.14.0-1
- update to 1.14.0 (#1840565, #1812195)
* Tue May 19 2020 Joe Orton <jorton@redhat.com> - 1.14.0~rc2-2
- switch subpackages to lock-step requires on -libs rather than subversion
- fixed the build-requires (Jitka Plesnikova)
* Thu Apr 30 2020 Joe Orton <jorton@redhat.com> - 1.14.0~rc2-1
- drop Berkeley DB support for Fedora > 32
- BR java-11-openjdk-devel
* Thu Apr 23 2020 Joe Orton <jorton@redhat.com> - 1.14.0~rc2-0
- update to 1.14.0-rc2
* Wed Feb 12 2020 Joe Orton <jorton@redhat.com> - 1.13.0-4
- fix FTBFS on 32-bit arches (#1800120)
- conditionally package bdb tools in -tools
* Fri Jan 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.12.2-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Tue Jan 21 2020 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.12.2-4
- F-32: fix include path for ruby 2.7
- Rebuild for ruby 2.7
* Mon Jan 6 2020 Joe Orton <jorton@redhat.com> - 1.12.2-3
- update for KDE 5 (Phil O, #1768693)
* Fri Aug 30 2019 Joe Orton <jorton@redhat.com> - 1.12.2-2
- switch to Python 3 for F32+ (#1737928)
* Thu Jul 25 2019 Joe Orton <jorton@redhat.com> - 1.12.2-1
- update to 1.12.2
* Sat Jun 01 2019 Jitka Plesnikova <jplesnik@redhat.com> - 1.12.0-2
- Perl 5.30 rebuild
* Wed May 1 2019 Joe Orton <jorton@redhat.com> - 1.12.0-1
- update to 1.12.0 (#1702471)
* Wed Apr 17 2019 Joe Orton <jorton@redhat.com> - 1.11.1-5
- fix build with APR 1.7.0 (upstream r1857391)
* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.11.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Mon Jan 21 2019 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.11.1-3
- F-30: rebuild against ruby26
* Tue Dec 12 2023 MSVSphere Packaging Team <packager@msvsphere-os.ru> - 1.10.2-5
- Rebuilt for MSVSphere 8.8
* Mon Jan 14 2019 Björn Esser <besser82@fedoraproject.org> - 1.11.1-2
- Rebuilt for libcrypt.so.2 (#1666033)
* Wed May 04 2022 Richard Lescak <rlescak@gmail.com> - 1.10.2-5
- add security fix for CVE-2022-24070
* Fri Jan 11 2019 Joe Orton <jorton@redhat.com> - 1.11.1-1
- update to 1.11.1
* Wed Feb 10 2021 Joe Orton <jorton@redhat.com> - 1.10.2-4
- add security fix for CVE-2020-17525
* Wed Oct 31 2018 Joe Orton <jorton@redhat.com> - 1.11.0-1
- update to 1.11.0
* Mon May 18 2020 Joe Orton <jorton@redhat.com> - 1.10.2-3
- add security fix for CVE-2018-11782
* Thu Oct 11 2018 Joe Orton <jorton@redhat.com> - 1.10.3-1
- update to 1.10.3
* Thu Aug 01 2019 Lubos Uhliarik <luhliari@redhat.com> - 1.10.2-2
- Resolves: #1733443 - CVE-2019-0203 subversion:1.10/subversion: remote
unauthenticated denial-of-service in subversion svnserve
* Fri Jul 20 2018 Joe Orton <jorton@redhat.com> - 1.10.2-1
- update to 1.10.2 (#1603197)

Loading…
Cancel
Save