You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/11/16 11:15:24 UTC
svn commit: r1714534 - in /subversion/branches/move-tracking-2: ./
subversion/ subversion/include/ subversion/include/private/
subversion/libsvn_delta/ subversion/libsvn_ra_serf/
subversion/libsvn_ra_svn/ subversion/libsvn_subr/ subversion/svnserve/ su...
Author: julianfoad
Date: Mon Nov 16 10:15:23 2015
New Revision: 1714534
URL: http://svn.apache.org/viewvc?rev=1714534&view=rev
Log:
On the 'move-tracking-2' branch: catch up to trunk@1714533.
Modified:
subversion/branches/move-tracking-2/ (props changed)
subversion/branches/move-tracking-2/subversion/ (props changed)
subversion/branches/move-tracking-2/subversion/include/private/svn_sorts_private.h
subversion/branches/move-tracking-2/subversion/include/svn_error_codes.h
subversion/branches/move-tracking-2/subversion/include/svn_ra_svn.h
subversion/branches/move-tracking-2/subversion/libsvn_delta/svndiff.c
subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/eagain_bucket.c
subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/sb_bucket.c
subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c
subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/deprecated.c
subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c
subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/marshal.c
subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h
subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/compress.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/prefix_string.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/skel.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/sorts.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/spillbuf.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c
subversion/branches/move-tracking-2/subversion/libsvn_subr/subst.c
subversion/branches/move-tracking-2/subversion/svnserve/serve.c
subversion/branches/move-tracking-2/subversion/svnserve/server.h
subversion/branches/move-tracking-2/subversion/svnserve/svnserve.c
subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c
subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c
Propchange: subversion/branches/move-tracking-2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Nov 16 10:15:23 2015
@@ -94,4 +94,4 @@
/subversion/branches/verify-at-commit:1462039-1462408
/subversion/branches/verify-keep-going:1439280-1546110
/subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1606692-1713385
+/subversion/trunk:1606692-1714533
Propchange: subversion/branches/move-tracking-2/subversion/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Nov 16 10:15:23 2015
@@ -82,4 +82,4 @@
/subversion/branches/verify-at-commit/subversion:1462039-1462408
/subversion/branches/verify-keep-going/subversion:1439280-1546110
/subversion/branches/wc-collate-path/subversion:1402685-1480384
-/subversion/trunk/subversion:1606692-1713385
+/subversion/trunk/subversion:1606692-1714533
Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_sorts_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_sorts_private.h?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_sorts_private.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_sorts_private.h Mon Nov 16 10:15:23 2015
@@ -53,12 +53,12 @@ struct svn_sort__item_t {
/** Sort @a ht according to its keys, return an @c apr_array_header_t
* containing @c svn_sort__item_t structures holding those keys and values
* (i.e. for each @c svn_sort__item_t @a item in the returned array,
- * @a item->key and @a item->size are the hash key, and @a item->value points to
+ * @a item.key and @a item.size are the hash key, and @a item.value points to
* the hash value).
*
* Storage is shared with the original hash, not copied.
*
- * @a comparison_func should take two @c svn_sort__item_t's and return an
+ * @a comparison_func should take pointers to two items and return an
* integer greater than, equal to, or less than 0, according as the first item
* is greater than, equal to, or less than the second.
*
Modified: subversion/branches/move-tracking-2/subversion/include/svn_error_codes.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_error_codes.h?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_error_codes.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_error_codes.h Mon Nov 16 10:15:23 2015
@@ -1542,6 +1542,16 @@ SVN_ERROR_START
SVN_ERR_RA_SVN_CATEGORY_START + 8,
"Editor drive was aborted")
+ /** @since New in 1.10 */
+ SVN_ERRDEF(SVN_ERR_RA_SVN_REQUEST_SIZE,
+ SVN_ERR_RA_SVN_CATEGORY_START + 9,
+ "Client request too long")
+
+ /** @since New in 1.10 */
+ SVN_ERRDEF(SVN_ERR_RA_SVN_RESPONSE_SIZE,
+ SVN_ERR_RA_SVN_CATEGORY_START + 10,
+ "Server response too long")
+
/* libsvn_auth errors */
/* this error can be used when an auth provider doesn't have
Modified: subversion/branches/move-tracking-2/subversion/include/svn_ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_ra_svn.h?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_ra_svn.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_ra_svn.h Mon Nov 16 10:15:23 2015
@@ -189,13 +189,38 @@ typedef svn_error_t *(*svn_ra_svn_edit_c
* It defines the number of bytes that must have been sent since the last
* check before the next check will be made.
*
+ * If @a max_in is not 0, error out and close the connection whenever more
+ * than @a max_in bytes are received for a command (e.g. a client request).
+ * If @a max_out is not 0, error out and close the connection whenever more
+ * than @a max_out bytes have been send as response to some command.
+ *
+ * @note The limits enforced may vary slightly by +/- the I/O buffer size.
+ *
* @note If @a out_stream is an wrapped apr_file_t* the backing file will be
* used for some operations.
*
* Allocate the result in @a pool.
*
+ * @since New in 1.10
+ */
+svn_ra_svn_conn_t *svn_ra_svn_create_conn5(apr_socket_t *sock,
+ svn_stream_t *in_stream,
+ svn_stream_t *out_stream,
+ int compression_level,
+ apr_size_t zero_copy_limit,
+ apr_size_t error_check_interval,
+ apr_uint64_t max_in,
+ apr_uint64_t max_out,
+ apr_pool_t *result_pool);
+
+
+/** Similar to svn_ra_svn_create_conn5() but with @a max_in and @a max_out
+ * set to 0.
+ *
* @since New in 1.9
+ * @deprecated Provided for backward compatibility with the 1.9 API.
*/
+SVN_DEPRECATED
svn_ra_svn_conn_t *svn_ra_svn_create_conn4(apr_socket_t *sock,
svn_stream_t *in_stream,
svn_stream_t *out_stream,
Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/svndiff.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/svndiff.c Mon Nov 16 10:15:23 2015
@@ -689,8 +689,8 @@ write_handler(void *baton,
/* Check for source windows which slide backwards. */
if (sview_len > 0
&& (sview_offset < db->last_sview_offset
- || (sview_offset + sview_len
- < db->last_sview_offset + db->last_sview_len)))
+ || (sview_offset + sview_len
+ < db->last_sview_offset + db->last_sview_len)))
return svn_error_create(
SVN_ERR_SVNDIFF_BACKWARD_VIEW, NULL,
_("Svndiff has backwards-sliding source views"));
@@ -710,7 +710,7 @@ write_handler(void *baton,
}
/* Wait for more data if we don't have enough bytes for the
- whole window. */
+ whole window. */
if ((apr_size_t) (end - p) < db->inslen + db->newlen)
return SVN_NO_ERROR;
Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/eagain_bucket.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/eagain_bucket.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/eagain_bucket.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/eagain_bucket.c Mon Nov 16 10:15:23 2015
@@ -66,7 +66,7 @@ eagain_bucket_read(serf_bucket_t *bucket
return APR_EAGAIN;
}
-
+#if !SERF_VERSION_AT_LEAST(1, 4, 0)
static apr_status_t
eagain_bucket_readline(serf_bucket_t *bucket,
int acceptable,
@@ -79,6 +79,7 @@ eagain_bucket_readline(serf_bucket_t *bu
"Not implemented."));
return APR_ENOTIMPL;
}
+#endif
static apr_status_t
@@ -98,7 +99,11 @@ eagain_bucket_peek(serf_bucket_t *bucket
static const serf_bucket_type_t delay_bucket_vtable = {
"BUF-EAGAIN",
eagain_bucket_read,
+#if SERF_VERSION_AT_LEAST(1, 4, 0)
+ serf_default_readline,
+#else
eagain_bucket_readline,
+#endif
serf_default_read_iovec,
serf_default_read_for_sendfile,
serf_default_read_bucket,
Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/sb_bucket.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/sb_bucket.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/sb_bucket.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_serf/sb_bucket.c Mon Nov 16 10:15:23 2015
@@ -117,7 +117,7 @@ sb_bucket_read(serf_bucket_t *bucket, ap
return *data == NULL ? APR_EOF : APR_SUCCESS;
}
-
+#if !SERF_VERSION_AT_LEAST(1, 4, 0)
static apr_status_t
sb_bucket_readline(serf_bucket_t *bucket, int acceptable,
int *found,
@@ -128,6 +128,7 @@ sb_bucket_readline(serf_bucket_t *bucket
"Not implemented."));
return APR_ENOTIMPL;
}
+#endif
static apr_status_t
@@ -159,7 +160,11 @@ sb_bucket_peek(serf_bucket_t *bucket,
static const serf_bucket_type_t sb_bucket_vtable = {
"SPILLBUF",
sb_bucket_read,
+#if SERF_VERSION_AT_LEAST(1, 4, 0)
+ serf_default_readline,
+#else
sb_bucket_readline,
+#endif
serf_default_read_iovec,
serf_default_read_for_sendfile,
serf_default_read_bucket,
Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/client.c Mon Nov 16 10:15:23 2015
@@ -471,9 +471,9 @@ static void handle_child_process_error(a
in_stream = svn_stream_from_aprfile2(in_file, FALSE, pool);
out_stream = svn_stream_from_aprfile2(out_file, FALSE, pool);
- conn = svn_ra_svn_create_conn4(NULL, in_stream, out_stream,
+ conn = svn_ra_svn_create_conn5(NULL, in_stream, out_stream,
SVN_DELTA_COMPRESSION_LEVEL_DEFAULT, 0,
- 0, pool);
+ 0, 0, 0, pool);
err = svn_error_wrap_apr(status, _("Error in child process: %s"), desc);
svn_error_clear(svn_ra_svn__write_cmd_failure(conn, pool, err));
svn_error_clear(err);
@@ -542,13 +542,13 @@ static svn_error_t *make_tunnel(const ch
apr_file_inherit_unset(proc->out);
/* Guard against dotfile output to stdout on the server. */
- *conn = svn_ra_svn_create_conn4(NULL,
+ *conn = svn_ra_svn_create_conn5(NULL,
svn_stream_from_aprfile2(proc->out, FALSE,
pool),
svn_stream_from_aprfile2(proc->in, FALSE,
pool),
SVN_DELTA_COMPRESSION_LEVEL_DEFAULT,
- 0, 0, pool);
+ 0, 0, 0, 0, pool);
err = svn_ra_svn__skip_leading_garbage(*conn, pool);
if (err)
return svn_error_quick_wrap(
@@ -674,9 +674,9 @@ static svn_error_t *open_session(svn_ra_
apr_pool_cleanup_register(pool, td, close_tunnel_cleanup,
apr_pool_cleanup_null);
- conn = svn_ra_svn_create_conn4(NULL, td->response, td->request,
+ conn = svn_ra_svn_create_conn5(NULL, td->response, td->request,
SVN_DELTA_COMPRESSION_LEVEL_DEFAULT,
- 0, 0, pool);
+ 0, 0, 0, 0, pool);
SVN_ERR(svn_ra_svn__skip_leading_garbage(conn, pool));
}
}
@@ -688,9 +688,9 @@ static svn_error_t *open_session(svn_ra_
SVN_ERR(make_connection(uri->hostname,
uri->port ? uri->port : SVN_RA_SVN_PORT,
&sock, pool));
- conn = svn_ra_svn_create_conn4(sock, NULL, NULL,
+ conn = svn_ra_svn_create_conn5(sock, NULL, NULL,
SVN_DELTA_COMPRESSION_LEVEL_DEFAULT,
- 0, 0, pool);
+ 0, 0, 0, 0, pool);
}
/* Build the useragent string, querying the client for any
@@ -1956,6 +1956,7 @@ static svn_error_t *ra_svn_get_locations
svn_ra_svn_conn_t *conn = sess_baton->conn;
svn_revnum_t revision;
svn_boolean_t is_done;
+ apr_pool_t *iterpool;
int i;
/* Transmit the parameters. */
@@ -1976,12 +1977,14 @@ static svn_error_t *ra_svn_get_locations
/* Read the hash items. */
is_done = FALSE;
*locations = apr_hash_make(pool);
+ iterpool = svn_pool_create(pool);
while (!is_done)
{
svn_ra_svn__item_t *item;
const char *ret_path;
- SVN_ERR(svn_ra_svn__read_item(conn, pool, &item));
+ svn_pool_clear(iterpool);
+ SVN_ERR(svn_ra_svn__read_item(conn, iterpool, &item));
if (is_done_response(item))
is_done = 1;
else if (item->kind != SVN_RA_SVN_LIST)
@@ -1991,6 +1994,8 @@ static svn_error_t *ra_svn_get_locations
{
SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, "rc",
&revision, &ret_path));
+
+ /* This also makes RET_PATH live in POOL rather than ITERPOOL. */
ret_path = svn_fspath__canonicalize(ret_path, pool);
apr_hash_set(*locations, apr_pmemdup(pool, &revision,
sizeof(revision)),
@@ -1998,6 +2003,8 @@ static svn_error_t *ra_svn_get_locations
}
}
+ svn_pool_destroy(iterpool);
+
/* Read the response. This is so the server would have a chance to
* report an error. */
return svn_error_trace(svn_ra_svn__read_cmd_response(conn, pool, ""));
Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/deprecated.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/deprecated.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/deprecated.c Mon Nov 16 10:15:23 2015
@@ -262,6 +262,20 @@ svn_ra_svn_write_cmd_failure(svn_ra_svn_
/* From marshal.c */
svn_ra_svn_conn_t *
+svn_ra_svn_create_conn4(apr_socket_t *sock,
+ svn_stream_t *in_stream,
+ svn_stream_t *out_stream,
+ int compression_level,
+ apr_size_t zero_copy_limit,
+ apr_size_t error_check_interval,
+ apr_pool_t *pool)
+{
+ return svn_ra_svn_create_conn5(sock, in_stream, out_stream,
+ compression_level, zero_copy_limit,
+ error_check_interval, 0, 0, pool);
+}
+
+svn_ra_svn_conn_t *
svn_ra_svn_create_conn3(apr_socket_t *sock,
apr_file_t *in_file,
apr_file_t *out_file,
@@ -279,7 +293,8 @@ svn_ra_svn_create_conn3(apr_socket_t *so
out_stream = svn_stream_from_aprfile2(out_file, FALSE, pool);
return svn_ra_svn_create_conn4(sock, in_stream, out_stream,
- compression_level, 0, 0, pool);
+ compression_level, zero_copy_limit,
+ error_check_interval, pool);
}
svn_ra_svn_conn_t *
Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/editorp.c Mon Nov 16 10:15:23 2015
@@ -1106,6 +1106,10 @@ svn_error_t *svn_ra_svn_drive_editor2(sv
while (!state.done)
{
svn_pool_clear(subpool);
+
+ /* WRT to applying I/O limits, treat each editor command as a separate
+ * protocol command. */
+ svn_ra_svn__reset_command_io_counters(conn);
if (editor)
{
cmd_handler_t handler;
Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/marshal.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/marshal.c Mon Nov 16 10:15:23 2015
@@ -179,12 +179,14 @@ svn_ra_svn__to_private_array(const apr_a
/* --- CONNECTION INITIALIZATION --- */
-svn_ra_svn_conn_t *svn_ra_svn_create_conn4(apr_socket_t *sock,
+svn_ra_svn_conn_t *svn_ra_svn_create_conn5(apr_socket_t *sock,
svn_stream_t *in_stream,
svn_stream_t *out_stream,
int compression_level,
apr_size_t zero_copy_limit,
apr_size_t error_check_interval,
+ apr_uint64_t max_in,
+ apr_uint64_t max_out,
apr_pool_t *result_pool)
{
svn_ra_svn_conn_t *conn;
@@ -204,6 +206,10 @@ svn_ra_svn_conn_t *svn_ra_svn_create_con
conn->written_since_error_check = 0;
conn->error_check_interval = error_check_interval;
conn->may_check_for_error = error_check_interval == 0;
+ conn->max_in = max_in;
+ conn->current_in = 0;
+ conn->max_out = max_out;
+ conn->current_out = 0;
conn->block_handler = NULL;
conn->block_baton = NULL;
conn->capabilities = apr_hash_make(result_pool);
@@ -312,8 +318,33 @@ svn_error_t *svn_ra_svn__data_available(
return svn_ra_svn__stream_data_available(conn->stream, data_available);
}
+void
+svn_ra_svn__reset_command_io_counters(svn_ra_svn_conn_t *conn)
+{
+ conn->current_in = 0;
+ conn->current_out = 0;
+}
+
+
/* --- WRITE BUFFER MANAGEMENT --- */
+/* Return an error object if CONN exceeded its send or receive limits. */
+static svn_error_t *
+check_io_limits(svn_ra_svn_conn_t *conn)
+{
+ if (conn->max_in && (conn->current_in > conn->max_in))
+ return svn_error_create(SVN_ERR_RA_SVN_REQUEST_SIZE, NULL,
+ "The client request size exceeds the "
+ "configured limit");
+
+ if (conn->max_out && (conn->current_out > conn->max_out))
+ return svn_error_create(SVN_ERR_RA_SVN_RESPONSE_SIZE, NULL,
+ "The server response size exceeds the "
+ "configured limit");
+
+ return SVN_NO_ERROR;
+}
+
/* Write data to socket or output file as appropriate. */
static svn_error_t *writebuf_output(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
const char *data, apr_size_t len)
@@ -323,6 +354,12 @@ static svn_error_t *writebuf_output(svn_
apr_pool_t *subpool = NULL;
svn_ra_svn__session_baton_t *session = conn->session;
+ /* Limit the size of the response, if a limit has been configured.
+ * This is to limit the server load in case users e.g. accidentally ran
+ * an export on the root folder. */
+ conn->current_out += len;
+ SVN_ERR(check_io_limits(conn));
+
while (data < end)
{
count = end - data;
@@ -441,12 +478,19 @@ static svn_error_t *readbuf_input(svn_ra
{
svn_ra_svn__session_baton_t *session = conn->session;
+ /* First, give the user a chance to cancel the request before we do. */
if (session && session->callbacks && session->callbacks->cancel_func)
SVN_ERR((session->callbacks->cancel_func)(session->callbacks_baton));
+ /* Limit our memory usage, if a limit has been configured. Note that
+ * we first read the whole request into memory before process it. */
+ SVN_ERR(check_io_limits(conn));
+
+ /* Actually fill the buffer. */
SVN_ERR(svn_ra_svn__stream_read(conn->stream, data, len));
if (*len == 0)
return svn_error_create(SVN_ERR_RA_SVN_CONNECTION_CLOSED, NULL, NULL);
+ conn->current_in += *len;
if (session)
{
@@ -492,9 +536,13 @@ static svn_error_t *readbuf_fill(svn_ra_
apr_size_t len;
SVN_ERR_ASSERT(conn->read_ptr == conn->read_end);
+
+ /* Make sure we tell the other side everything we have to say before
+ * reading / waiting for an answer. */
if (conn->write_pos)
SVN_ERR(writebuf_flush(conn, pool));
+ /* Fill (some of the) buffer. */
len = sizeof(conn->read_buf);
SVN_ERR(readbuf_input(conn, conn->read_buf, &len, pool));
conn->read_ptr = conn->read_buf;
@@ -1141,7 +1189,7 @@ static svn_error_t *read_string(svn_ra_s
char *dest;
/* We can't store strings longer than the maximum size of apr_size_t,
- * so check for wrapping */
+ * so check before using the truncated value. */
if (len64 > APR_SIZE_MAX)
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
_("String length larger than maximum"));
@@ -1156,6 +1204,16 @@ static svn_error_t *read_string(svn_ra_s
}
else
{
+ svn_stringbuf_t *stringbuf;
+
+ /* Don't even attempt to read anything that exceeds the I/O limit.
+ * So, we can terminate the transfer at an early point, saving
+ * everybody's time and resources. */
+ if (conn->max_in && (conn->max_in < len64))
+ return svn_error_create(SVN_ERR_RA_SVN_REQUEST_SIZE, NULL,
+ "The client request size exceeds the "
+ "configured limit");
+
/* Read the string in chunks. The chunk size is large enough to avoid
* re-allocation in typical cases, and small enough to ensure we do
* not pre-allocate an unreasonable amount of memory if (perhaps due
@@ -1164,7 +1222,7 @@ static svn_error_t *read_string(svn_ra_s
* start small and wait for all that data to actually show up. This
* does not fully prevent DOS attacks but makes them harder (you have
* to actually send gigabytes of data). */
- svn_stringbuf_t *stringbuf = svn_stringbuf_create_empty(pool);
+ stringbuf = svn_stringbuf_create_empty(pool);
/* Read string data directly into the string structure.
* Do it iteratively. */
@@ -1791,7 +1849,12 @@ svn_ra_svn__has_command(svn_boolean_t *h
svn_ra_svn_conn_t *conn,
apr_pool_t *pool)
{
- svn_error_t *err = svn_ra_svn__has_item(has_command, conn, pool);
+ svn_error_t *err;
+
+ /* Don't make whitespace between commands trigger I/O limitiations. */
+ svn_ra_svn__reset_command_io_counters(conn);
+
+ err = svn_ra_svn__has_item(has_command, conn, pool);
if (err && err->apr_err == SVN_ERR_RA_SVN_CONNECTION_CLOSED)
{
*terminated = TRUE;
@@ -1817,6 +1880,10 @@ svn_ra_svn__handle_command(svn_boolean_t
const svn_ra_svn__cmd_entry_t *command;
*terminate = FALSE;
+
+ /* Limit I/O for every command separately. */
+ svn_ra_svn__reset_command_io_counters(conn);
+
err = svn_ra_svn__read_tuple(conn, pool, "wl", &cmdname, ¶ms);
if (err)
{
@@ -1848,6 +1915,13 @@ svn_ra_svn__handle_command(svn_boolean_t
baton);
}
+ /* The command implementation may have swallowed or wrapped the I/O
+ * error not knowing that we may no longer be able to send data.
+ *
+ * So, check again for the limit violations and exit the command
+ * processing quickly if we may have truncated data. */
+ err = svn_error_compose_create(check_io_limits(conn), err);
+
*terminate = command->terminate;
}
else
Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra_svn/ra_svn.h Mon Nov 16 10:15:23 2015
@@ -96,6 +96,12 @@ struct svn_ra_svn_conn_st {
apr_size_t error_check_interval;
svn_boolean_t may_check_for_error;
+ /* I/O limits and tracking */
+ apr_uint64_t max_in;
+ apr_uint64_t current_in;
+ apr_uint64_t max_out;
+ apr_uint64_t current_out;
+
/* repository info */
const char *uuid;
const char *repos_root;
@@ -151,6 +157,12 @@ void svn_ra_svn__set_block_handler(svn_r
svn_error_t *svn_ra_svn__data_available(svn_ra_svn_conn_t *conn,
svn_boolean_t *data_available);
+/* Signal a new request / response pair on CONN. That resets the I/O
+ * counters we use to limit the size of individual requests / response pairs.
+ */
+void
+svn_ra_svn__reset_command_io_counters(svn_ra_svn_conn_t *conn);
+
/* CRAM-MD5 client implementation. */
svn_error_t *svn_ra_svn__cram_client(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
const char *user, const char *password,
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c Mon Nov 16 10:15:23 2015
@@ -353,7 +353,8 @@ prefix_pool_get_internal(apr_uint32_t *p
}
bytes_needed = prefix_len + 1 + OVERHEAD;
- if (prefix_pool->bytes_used + bytes_needed > prefix_pool->values_max)
+ assert(prefix_pool->bytes_max >= prefix_pool->bytes_used);
+ if (prefix_pool->bytes_max - prefix_pool->bytes_used > bytes_needed)
{
*prefix_idx = NO_INDEX;
return SVN_NO_ERROR;
@@ -1664,12 +1665,12 @@ ensure_data_insertable_l2(svn_membuffer_
/* leave function as soon as the insertion window is large enough
*/
- if (end >= to_fit_in->size + cache->l2.current_data)
+ if (end - cache->l2.current_data >= to_fit_in->size)
return TRUE;
/* Don't be too eager to cache data. If a lot of data has been moved
* around, the current item has probably a relatively low priority.
- * We must also limit the effort spent here (if even in case of faulty
+ * We must also limit the effort spent here (even in case of faulty
* heuristics). Therefore, give up after some time.
*/
if (moved_size > 4 * to_fit_in->size && moved_count > 7)
@@ -1789,7 +1790,7 @@ ensure_data_insertable_l1(svn_membuffer_
/* leave function as soon as the insertion window is large enough
*/
- if (end >= size + cache->l1.current_data)
+ if (end - cache->l1.current_data >= size)
return TRUE;
/* Enlarge the insertion window
@@ -2678,9 +2679,11 @@ membuffer_cache_set_partial_internal(svn
if (item_data != orig_data)
{
/* Remove the old entry and try to make space for the new one.
+ * Note that the key has already been stored in the past, i.e.
+ * it is shorter than the MAX_ENTRY_SIZE.
*/
drop_entry(cache, entry);
- if ( (cache->max_entry_size >= item_size + key_len)
+ if ( (cache->max_entry_size - key_len >= item_size)
&& ensure_data_insertable_l1(cache, item_size + key_len))
{
/* Write the new entry.
@@ -3371,6 +3374,11 @@ svn_cache__create_membuffer_cache(svn_ca
prefix_orig_len = strlen(prefix) + 1;
prefix_len = ALIGN_VALUE(prefix_orig_len);
+ /* Paranoia check to ensure pointer arithmetics work as expected. */
+ if (prefix_orig_len >= SVN_MAX_OBJECT_SIZE)
+ return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+ _("Prefix too long"));
+
/* Construct the folded prefix key. */
SVN_ERR(svn_checksum(&checksum,
svn_checksum_md5,
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/compress.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/compress.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/compress.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/compress.c Mon Nov 16 10:15:23 2015
@@ -100,7 +100,7 @@ svn__decode_uint(apr_uint64_t *val,
{
apr_uint64_t temp = 0;
- if (p + SVN__MAX_ENCODED_UINT_LEN < end)
+ if (end - p > SVN__MAX_ENCODED_UINT_LEN)
end = p + SVN__MAX_ENCODED_UINT_LEN;
/* Decode bytes until we're done. */
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/prefix_string.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/prefix_string.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/prefix_string.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/prefix_string.c Mon Nov 16 10:15:23 2015
@@ -228,7 +228,7 @@ svn_prefix_string__create(svn_prefix_tre
}
/* add sub-node(s) and final string */
- while (node->length + 7 < len)
+ while (len - node->length > 7)
{
new_node = apr_pcalloc(tree->pool, sizeof(*new_node));
new_node->key.prefix = node;
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/skel.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/skel.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/skel.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/skel.c Mon Nov 16 10:15:23 2015
@@ -380,7 +380,7 @@ explicit_atom(const char *data,
data++;
/* Check the length. */
- if (data + size > end)
+ if (end - data < size)
return NULL;
/* Allocate the skel representing this string. */
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/sorts.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/sorts.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/sorts.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/sorts.c Mon Nov 16 10:15:23 2015
@@ -333,7 +333,7 @@ svn_sort__array_delete(apr_array_header_
if (delete_index >= 0
&& delete_index < arr->nelts
&& elements_to_delete > 0
- && (elements_to_delete + delete_index) <= arr->nelts)
+ && (arr->nelts - delete_index) >= elements_to_delete)
{
/* If we are not deleting a block of elements that extends to the end
of the array, then we need to move the remaining elements to keep
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/spillbuf.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/spillbuf.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/spillbuf.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/spillbuf.c Mon Nov 16 10:15:23 2015
@@ -242,7 +242,7 @@ svn_spillbuf__write(svn_spillbuf_t *buf,
will grow too large. Create the file and place the pending data into
the temporary file. */
if (buf->spill == NULL
- && (buf->memory_size + len) > buf->maxsize)
+ && ((buf->maxsize - buf->memory_size) < len))
{
SVN_ERR(svn_io_open_unique_file3(&buf->spill,
&buf->filename,
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c Mon Nov 16 10:15:23 2015
@@ -677,7 +677,7 @@ svn_stringbuf_remove(svn_stringbuf_t *st
{
if (pos > str->len)
pos = str->len;
- if (pos + count > str->len)
+ if (count > str->len - pos)
count = str->len - pos;
memmove(str->data + pos, str->data + pos + count, str->len - pos - count + 1);
@@ -705,7 +705,7 @@ svn_stringbuf_replace(svn_stringbuf_t *s
if (pos > str->len)
pos = str->len;
- if (pos + old_count > str->len)
+ if (old_count > str->len - pos)
old_count = str->len - pos;
if (old_count < new_count)
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/subst.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/subst.c Mon Nov 16 10:15:23 2015
@@ -1127,7 +1127,7 @@ translate_chunk(svn_stream_t *dst,
{
/* Check 4 bytes at once to allow for efficient pipelining
and to reduce loop condition overhead. */
- while ((p + len + 4) <= end)
+ while ((end - p) >= (len + 4))
{
if (interesting[(unsigned char)p[len]]
|| interesting[(unsigned char)p[len+1]]
@@ -1157,7 +1157,7 @@ translate_chunk(svn_stream_t *dst,
}
while (b->nl_translation_skippable ==
svn_tristate_true && /* can potentially skip EOLs */
- p + len + 2 < end && /* not too close to EOF */
+ (end - p) > (len + 2) && /* not too close to EOF */
eol_unchanged(b, p + len)); /* EOL format already ok */
while ((p + len) < end && !interesting[(unsigned char)p[len]])
Modified: subversion/branches/move-tracking-2/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnserve/serve.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnserve/serve.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnserve/serve.c Mon Nov 16 10:15:23 2015
@@ -627,11 +627,12 @@ create_fs_access(server_baton_t *b, apr_
* On authentication failure, report failure to the client and set
* *success to FALSE. On communications failure, return an error.
* If NEEDS_USERNAME is TRUE, don't allow anonymous authentication. */
-static svn_error_t *auth(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
+static svn_error_t *auth(svn_boolean_t *success,
+ svn_ra_svn_conn_t *conn,
const char *mech, const char *mecharg,
server_baton_t *b, enum access_type required,
svn_boolean_t needs_username,
- svn_boolean_t *success)
+ apr_pool_t *scratch_pool)
{
const char *user;
*success = FALSE;
@@ -640,10 +641,10 @@ static svn_error_t *auth(svn_ra_svn_conn
&& b->client_info->tunnel_user && strcmp(mech, "EXTERNAL") == 0)
{
if (*mecharg && strcmp(mecharg, b->client_info->tunnel_user) != 0)
- return svn_ra_svn__write_tuple(conn, pool, "w(c)", "failure",
+ return svn_ra_svn__write_tuple(conn, scratch_pool, "w(c)", "failure",
"Requested username does not match");
b->client_info->user = b->client_info->tunnel_user;
- SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w()", "success"));
+ SVN_ERR(svn_ra_svn__write_tuple(conn, scratch_pool, "w()", "success"));
*success = TRUE;
return SVN_NO_ERROR;
}
@@ -651,7 +652,7 @@ static svn_error_t *auth(svn_ra_svn_conn
if (b->repository->anon_access >= required
&& strcmp(mech, "ANONYMOUS") == 0 && ! needs_username)
{
- SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w()", "success"));
+ SVN_ERR(svn_ra_svn__write_tuple(conn, scratch_pool, "w()", "success"));
*success = TRUE;
return SVN_NO_ERROR;
}
@@ -659,13 +660,13 @@ static svn_error_t *auth(svn_ra_svn_conn
if (b->repository->auth_access >= required
&& b->repository->pwdb && strcmp(mech, "CRAM-MD5") == 0)
{
- SVN_ERR(svn_ra_svn_cram_server(conn, pool, b->repository->pwdb,
+ SVN_ERR(svn_ra_svn_cram_server(conn, scratch_pool, b->repository->pwdb,
&user, success));
b->client_info->user = apr_pstrdup(b->pool, user);
return SVN_NO_ERROR;
}
- return svn_ra_svn__write_tuple(conn, pool, "w(c)", "failure",
+ return svn_ra_svn__write_tuple(conn, scratch_pool, "w(c)", "failure",
"Must authenticate with listed mechanism");
}
@@ -677,19 +678,26 @@ internal_auth_request(svn_ra_svn_conn_t
{
svn_boolean_t success;
const char *mech, *mecharg;
+ apr_pool_t *iterpool;
SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "success"));
SVN_ERR(send_mechs(conn, pool, b, required, needs_username));
SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)c)", b->repository->realm));
+
+ iterpool = svn_pool_create(pool);
do
{
+ svn_pool_clear(iterpool);
+
SVN_ERR(svn_ra_svn__read_tuple(conn, pool, "w(?c)", &mech, &mecharg));
if (!*mech)
break;
- SVN_ERR(auth(conn, pool, mech, mecharg, b, required, needs_username,
- &success));
+ SVN_ERR(auth(&success, conn, mech, mecharg, b, required,
+ needs_username, iterpool));
}
while (!success);
+ svn_pool_destroy(iterpool);
+
return SVN_NO_ERROR;
}
@@ -4115,10 +4123,12 @@ serve_interruptable(svn_boolean_t *termi
/* create the connection, configure ports etc. */
connection->conn
- = svn_ra_svn_create_conn4(connection->usock, NULL, NULL,
+ = svn_ra_svn_create_conn5(connection->usock, NULL, NULL,
connection->params->compression_level,
connection->params->zero_copy_limit,
connection->params->error_check_interval,
+ connection->params->max_request_size,
+ connection->params->max_response_size,
connection->pool);
/* Construct server baton and open the repository for the first time. */
Modified: subversion/branches/move-tracking-2/subversion/svnserve/server.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnserve/server.h?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnserve/server.h (original)
+++ subversion/branches/move-tracking-2/subversion/svnserve/server.h Mon Nov 16 10:15:23 2015
@@ -152,6 +152,12 @@ typedef struct serve_params_t {
coming in from the client. */
apr_size_t error_check_interval;
+ /* If not 0, error out on requests exceeding this value. */
+ apr_uint64_t max_request_size;
+
+ /* If not 0, stop sending a response once it exceeds this value. */
+ apr_uint64_t max_response_size;
+
/* Use virtual-host-based path to repo. */
svn_boolean_t vhost;
} serve_params_t;
Modified: subversion/branches/move-tracking-2/subversion/svnserve/svnserve.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnserve/svnserve.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnserve/svnserve.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnserve/svnserve.c Mon Nov 16 10:15:23 2015
@@ -155,6 +155,15 @@ enum run_mode {
*/
#define ACCEPT_BACKLOG 128
+/* Default limit to the client request size in MBytes. This effectively
+ * limits the size of a paths and individual property values to about
+ * this value.
+ *
+ * Note that (MAX_REQUEST_SIZE + 4M) * THREADPOOL_MAX_SIZE is roughly
+ * the peak memory usage of the RA layer.
+ */
+#define MAX_REQUEST_SIZE 16
+
#ifdef WIN32
static apr_os_sock_t winservice_svnserve_accept_socket = INVALID_SOCKET;
@@ -210,6 +219,8 @@ void winservice_notify_stop(void)
#define SVNSERVE_OPT_MIN_THREADS 271
#define SVNSERVE_OPT_MAX_THREADS 272
#define SVNSERVE_OPT_BLOCK_READ 273
+#define SVNSERVE_OPT_MAX_REQUEST 274
+#define SVNSERVE_OPT_MAX_RESPONSE 275
/* Text macro because we can't use #ifdef sections inside a N_("...")
macro expansion. */
@@ -345,6 +356,29 @@ static const apr_getopt_option_t svnserv
"Default is " APR_STRINGIFY(THREADPOOL_MAX_SIZE) "."
ONLY_AVAILABLE_WITH_THEADS)},
#endif
+ {"max-request-size", SVNSERVE_OPT_MAX_REQUEST, 1,
+ N_("Maximum acceptable size of a client request in MB.\n"
+ " "
+ "This implicitly limits the length of paths and\n"
+ " "
+ "property values that can be sent to the server.\n"
+ " "
+ "Also the peak memory usage for protocol handling\n"
+ " "
+ "per server thread or sub-process.\n"
+ " "
+ "0 disables the size check; default is "
+ APR_STRINGIFY(MAX_REQUEST_SIZE) ".")},
+ {"max-response-size", SVNSERVE_OPT_MAX_RESPONSE, 1,
+ N_("Maximum acceptable server response size in MB.\n"
+ " "
+ "Longer responses get truncated and return an\n"
+ " "
+ "error. This limits the server load e.g. when\n"
+ " "
+ "checking out at the wrong path level.\n"
+ " "
+ "Default is 0 (disabled).")},
{"foreground", SVNSERVE_OPT_FOREGROUND, 0,
N_("run in foreground (useful for debugging)\n"
" "
@@ -728,6 +762,8 @@ sub_main(int *exit_code, int argc, const
params.memory_cache_size = (apr_uint64_t)-1;
params.zero_copy_limit = 0;
params.error_check_interval = 4096;
+ params.max_request_size = MAX_REQUEST_SIZE * 0x100000;
+ params.max_response_size = 0;
while (1)
{
@@ -891,6 +927,14 @@ sub_main(int *exit_code, int argc, const
}
break;
+ case SVNSERVE_OPT_MAX_REQUEST:
+ params.max_request_size = 0x100000 * apr_strtoi64(arg, NULL, 0);
+ break;
+
+ case SVNSERVE_OPT_MAX_RESPONSE:
+ params.max_response_size = 0x100000 * apr_strtoi64(arg, NULL, 0);
+ break;
+
case SVNSERVE_OPT_MIN_THREADS:
min_thread_count = (apr_size_t)apr_strtoi64(arg, NULL, 0);
break;
@@ -1039,10 +1083,12 @@ sub_main(int *exit_code, int argc, const
* the pool cleanup handlers that call sasl_dispose() (connection_pool)
* and sasl_done() (pool) are run in the right order. See issue #3664. */
connection_pool = svn_pool_create(pool);
- conn = svn_ra_svn_create_conn4(NULL, stdin_stream, stdout_stream,
+ conn = svn_ra_svn_create_conn5(NULL, stdin_stream, stdout_stream,
params.compression_level,
params.zero_copy_limit,
params.error_check_interval,
+ params.max_request_size,
+ params.max_response_size,
connection_pool);
err = serve(conn, ¶ms, connection_pool);
svn_pool_destroy(connection_pool);
Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c Mon Nov 16 10:15:23 2015
@@ -5960,6 +5960,9 @@ purge_txn_test(const svn_test_opts_t *op
return SVN_NO_ERROR;
}
+/* Test svn_fs_{contents,props}_{different,changed}().
+ * ### This currently only tests them on revision roots, not on txn roots.
+ */
static svn_error_t *
compare_contents(const svn_test_opts_t *opts,
apr_pool_t *pool)
Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c?rev=1714534&r1=1714533&r2=1714534&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c Mon Nov 16 10:15:23 2015
@@ -634,7 +634,15 @@ test_stringbuf_remove(apr_pool_t *pool)
SVN_TEST_STRING_ASSERT(a->data, "stell");
svn_stringbuf_remove(a, 1200, 393);
- return expect_stringbuf_equal(a, "stell", pool);
+ SVN_ERR(expect_stringbuf_equal(a, "stell", pool));
+
+ svn_stringbuf_remove(a, APR_SIZE_MAX, 2);
+ SVN_ERR(expect_stringbuf_equal(a, "stell", pool));
+
+ svn_stringbuf_remove(a, 1, APR_SIZE_MAX);
+ SVN_ERR(expect_stringbuf_equal(a, "s", pool));
+
+ return SVN_NO_ERROR;
}
static svn_error_t *
@@ -672,6 +680,12 @@ test_stringbuf_replace(apr_pool_t *pool)
svn_stringbuf_ncreate("test hello\0-\0world!\0-\0!",
23, pool)));
+ svn_stringbuf_replace(a, 1, APR_SIZE_MAX, "x", 1);
+ SVN_ERR(expect_stringbuf_equal(a, "tx", pool));
+
+ svn_stringbuf_replace(a, APR_SIZE_MAX, APR_SIZE_MAX, "y", 1);
+ SVN_ERR(expect_stringbuf_equal(a, "txy", pool));
+
return SVN_NO_ERROR;
}