Author: rhuijben
Date: Mon Mar 9 12:41:48 2015
New Revision: 1665213
URL: http://svn.apache.org/r1665213
Log:
In ra-serf: avoid possible segfault when the ra_session is reused after a
failed svn_ra_get_dir2() request without clearing the pool passed to
svn_ra_get_dir2() before the next request.
The segfault is caused by the callback, which uses a stack allocated baton
to collect results.
* subversion/libsvn_ra_serf/stat.c
(svn_ra_serf__get_dir): Properly clear the scratch pool when exiting
early.
Modified:
subversion/trunk/subversion/libsvn_ra_serf/stat.c
Modified: subversion/trunk/subversion/libsvn_ra_serf/stat.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/stat.c?rev=1665213&r1=1665212&r2=1665213&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/stat.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/stat.c Mon Mar 9 12:41:48 2015
@@ -472,6 +472,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
svn_ra_serf__handler_t *props_handler = NULL;
const char *path;
struct get_dir_baton_t gdb;
+ svn_error_t *err = SVN_NO_ERROR;
gdb.result_pool = result_pool;
gdb.is_directory = FALSE;
@@ -542,10 +543,17 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
if (dirent_handler)
{
- SVN_ERR(svn_ra_serf__context_run_wait(&dirent_handler->done,
+ err = svn_error_trace(
+ svn_ra_serf__context_run_wait(&dirent_handler->done,
session,
scratch_pool));
+ if (err)
+ {
+ svn_pool_clear(scratch_pool); /* Unregisters outstanding requests */
+ return err;
+ }
+
if (gdb.supports_deadprop_count == svn_tristate_false
&& session->supports_deadprop_count == svn_tristate_unknown
&& dirent_fields & SVN_DIRENT_HAS_PROPS)
@@ -571,23 +579,27 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
if (props_handler)
{
- SVN_ERR(svn_ra_serf__context_run_wait(&props_handler->done,
+ err = svn_error_trace(
+ svn_ra_serf__context_run_wait(&props_handler->done,
session,
scratch_pool));
}
/* And dirent again for the case when we had to send the request again */
- if (dirent_handler)
+ if (! err && dirent_handler)
{
- SVN_ERR(svn_ra_serf__context_run_wait(&dirent_handler->done,
+ err = svn_error_trace(
+ svn_ra_serf__context_run_wait(&dirent_handler->done,
session,
scratch_pool));
}
- if (gdb.supports_deadprop_count != svn_tristate_unknown)
+ if (!err && gdb.supports_deadprop_count != svn_tristate_unknown)
session->supports_deadprop_count = gdb.supports_deadprop_count;
- svn_pool_destroy(scratch_pool);
+ svn_pool_destroy(scratch_pool); /* Unregisters outstanding requests */
+
+ SVN_ERR(err);
if (!gdb.is_directory)
return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,