Author: brane
Date: Sun May 18 11:36:06 2025
New Revision: 1925664
URL: http://svn.apache.org/viewvc?rev=1925664&view=rev
Log:
When wrapping streams, set only those handlers on the wrapper that are
supported by the source stream, otherwise the svn_stream_supports_*()
predicates do not work as expected. And for consistency, expose the "stream
supports seek" predicate explicitly in the streams API instead of hiding it
behind "supports reset".
* subversion/include/svn_io.h
(svn_stream_supports_seek): New function.
* subversion/libsvn_subr/stream.c
(svn_stream_supports_seek): Implemented here.
(svn_stream_supports_reset): This is now just a wrapper for the above.
(svn_stream_disown): Add the partial read, mark and seek handlers only
if the original wrapped stream supports them.
(svn_stream_checksummed2): Likewise.
* subversion/libsvn_subr/subst.c
(stream_translated): Use separate checks to decide when to add the
mark and seek stream handlers.
* subversion/libsvn_client/blame.c
(file_rev_handler): Let's just agree to not disown NULL streams, shall we?
We have a perfectly good empty stream that can be disowned without
dereferencing a null pointer.
Modified:
subversion/trunk/subversion/include/svn_io.h
subversion/trunk/subversion/libsvn_client/blame.c
subversion/trunk/subversion/libsvn_subr/stream.c
subversion/trunk/subversion/libsvn_subr/subst.c
Modified: subversion/trunk/subversion/include/svn_io.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_io.h?rev=1925664&r1=1925663&r2=1925664&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_io.h (original)
+++ subversion/trunk/subversion/include/svn_io.h Sun May 18 11:36:06 2025
@@ -1385,6 +1385,14 @@ svn_stream_reset(svn_stream_t *stream);
svn_boolean_t
svn_stream_supports_mark(svn_stream_t *stream);
+/** Returns @c TRUE if the generic @a stream supports svn_stream_seek().
+ *
+ * @see svn_stream_seek()
+ * @since New in 1.15.
+ */
+svn_boolean_t
+svn_stream_supports_seek(svn_stream_t *stream);
+
/** Returns @c TRUE if the generic @a stream supports svn_stream_reset().
*
* @see svn_stream_reset()
Modified: subversion/trunk/subversion/libsvn_client/blame.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/blame.c?rev=1925664&r1=1925663&r2=1925664&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/blame.c (original)
+++ subversion/trunk/subversion/libsvn_client/blame.c Sun May 18 11:36:06 2025
@@ -499,8 +499,7 @@ file_rev_handler(void *baton, const char
SVN_ERR(svn_stream_open_readonly(&delta_baton->source_stream,
frb->last_filename,
frb->currpool, pool));
else
- /* Means empty stream below. */
- delta_baton->source_stream = NULL;
+ delta_baton->source_stream = svn_stream_empty(pool);
last_stream = svn_stream_disown(delta_baton->source_stream, pool);
if (frb->include_merged_revisions && !merged_revision)
Modified: subversion/trunk/subversion/libsvn_subr/stream.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/stream.c?rev=1925664&r1=1925663&r2=1925664&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/stream.c (original)
+++ subversion/trunk/subversion/libsvn_subr/stream.c Sun May 18 11:36:06 2025
@@ -236,11 +236,17 @@ svn_stream_supports_mark(svn_stream_t *s
}
svn_boolean_t
-svn_stream_supports_reset(svn_stream_t *stream)
+svn_stream_supports_seek(svn_stream_t *stream)
{
return stream->seek_fn != NULL;
}
+svn_boolean_t
+svn_stream_supports_reset(svn_stream_t *stream)
+{
+ return svn_stream_supports_seek(stream);
+}
+
svn_error_t *
svn_stream_mark(svn_stream_t *stream, svn_stream_mark_t **mark,
apr_pool_t *pool)
@@ -658,12 +664,16 @@ svn_stream_t *
svn_stream_disown(svn_stream_t *stream, apr_pool_t *pool)
{
svn_stream_t *s = svn_stream_create(stream, pool);
+ const svn_read_fn_t read_handler =
+ svn_stream_supports_partial_read(stream) ? read_handler_disown : NULL;
- svn_stream_set_read2(s, read_handler_disown, read_full_handler_disown);
+ svn_stream_set_read2(s, read_handler, read_full_handler_disown);
svn_stream_set_skip(s, skip_handler_disown);
svn_stream_set_write(s, write_handler_disown);
- svn_stream_set_mark(s, mark_handler_disown);
- svn_stream_set_seek(s, seek_handler_disown);
+ if (svn_stream_supports_mark(stream))
+ svn_stream_set_mark(s, mark_handler_disown);
+ if (svn_stream_supports_seek(stream))
+ svn_stream_set_seek(s, seek_handler_disown);
svn_stream_set_data_available(s, data_available_disown);
svn_stream_set_readline(s, readline_handler_disown);
@@ -1490,6 +1500,8 @@ svn_stream_checksummed2(svn_stream_t *st
{
svn_stream_t *s;
struct checksum_stream_baton *baton;
+ const svn_read_fn_t read_handler =
+ svn_stream_supports_partial_read(stream) ? read_handler_checksum : NULL;
if (read_checksum == NULL && write_checksum == NULL)
return stream;
@@ -1512,7 +1524,7 @@ svn_stream_checksummed2(svn_stream_t *st
baton->pool = pool;
s = svn_stream_create(baton, pool);
- svn_stream_set_read2(s, read_handler_checksum, read_full_handler_checksum);
+ svn_stream_set_read2(s, read_handler, read_full_handler_checksum);
svn_stream_set_write(s, write_handler_checksum);
svn_stream_set_data_available(s, data_available_handler_checksum);
svn_stream_set_close(s, close_handler_checksum);
Modified: subversion/trunk/subversion/libsvn_subr/subst.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/subst.c?rev=1925664&r1=1925663&r2=1925664&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/subst.c (original)
+++ subversion/trunk/subversion/libsvn_subr/subst.c Sun May 18 11:36:06 2025
@@ -1542,10 +1542,9 @@ stream_translated(svn_stream_t *stream,
svn_stream_set_write(s, translated_stream_write);
svn_stream_set_close(s, translated_stream_close);
if (svn_stream_supports_mark(stream))
- {
- svn_stream_set_mark(s, translated_stream_mark);
- svn_stream_set_seek(s, translated_stream_seek);
- }
+ svn_stream_set_mark(s, translated_stream_mark);
+ if (svn_stream_supports_seek(stream))
+ svn_stream_set_seek(s, translated_stream_seek);
return s;
}