File subversion-1.8.19-CVE-2018-11782.patch of Package subversion

Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c	(revision 1886022)
+++ subversion/libsvn_ra_svn/client.c	(working copy)
@@ -2709,6 +2709,7 @@ ra_svn_get_deleted_rev(svn_ra_session_t *session,
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
+  svn_error_t *err;
 
   /* Transmit the parameters. */
   SVN_ERR(svn_ra_svn__write_cmd_get_deleted_rev(conn, pool, path,
@@ -2718,7 +2719,19 @@ ra_svn_get_deleted_rev(svn_ra_session_t *session,
   SVN_ERR(handle_unsupported_cmd(handle_auth_request(sess_baton, pool),
                                  N_("'get-deleted-rev' not implemented")));
 
-  return svn_ra_svn__read_cmd_response(conn, pool, "r", revision_deleted);
+  err = 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 *
Index: subversion/svnserve/serve.c
===================================================================
--- subversion/svnserve/serve.c	(revision 1886022)
+++ subversion/svnserve/serve.c	(working copy)
@@ -3096,6 +3096,19 @@ get_deleted_rev(svn_ra_svn_conn_t *conn,
   SVN_ERR(trivial_auth_request(conn, pool, b));
   SVN_ERR(svn_repos_deleted_rev(b->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;
 }
@@ -3521,7 +3534,7 @@ fetch_base_func(const char **filename,
 svn_error_t *serve(svn_ra_svn_conn_t *conn, serve_params_t *params,
                    apr_pool_t *pool)
 {
-  svn_error_t *err, *io_err;
+  svn_error_t *err;
   apr_uint64_t ver;
   const char *uuid, *client_url, *ra_client_string, *client_string;
   apr_array_header_t *caplist, *cap_words;
@@ -3645,12 +3658,12 @@ svn_error_t *serve(svn_ra_svn_conn_t *conn, serve_
     }
   if (err)
     {
-      log_error(err, b.log_file, svn_ra_svn_conn_remote_host(conn),
-                b.user, NULL, pool);
-      io_err = svn_ra_svn__write_cmd_failure(conn, pool, err);
-      svn_error_clear(err);
-      SVN_ERR(io_err);
-      return svn_ra_svn__flush(conn, pool);
+      /* Report these errors to the client before closing the connection. */
+      err = svn_error_compose_create(err,
+              svn_ra_svn__write_cmd_failure(conn, pool, err));
+      err = svn_error_compose_create(err,
+              svn_ra_svn__flush(conn, pool));
+      return err;
     }
 
   /* Log the open. */
openSUSE Build Service is sponsored by