]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: istream: i_stream_unref(): Put stream value in local variable, rather than relyi...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Sun, 15 Oct 2017 20:53:09 +0000 (22:53 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Sat, 18 Nov 2023 18:58:04 +0000 (18:58 +0000)
Problem is that a destroy callback can mess with the pointer, leading to all kinds of trouble.

src/lib/istream.c

index 168456f01f65b4488d8a3bd4f62b612c465b55ef..e76ba49904936bc59c52b68f6247d7d1ae65f1cc 100644 (file)
@@ -49,30 +49,31 @@ void i_stream_ref(struct istream *stream)
        io_stream_ref(&stream->real_stream->iostream);
 }
 
-void i_stream_unref(struct istream **stream)
+void i_stream_unref(struct istream **_stream)
 {
-       struct istream_private *_stream;
+       struct istream *stream = *_stream;
+       struct istream_private *rstream;
 
-       if (*stream == NULL)
+       if (stream == NULL)
                return;
 
-       _stream = (*stream)->real_stream;
+       *_stream = NULL;
+       rstream = stream->real_stream;
 
-       if (_stream->iostream.refcount > 1) {
-               if (!io_stream_unref(&_stream->iostream))
+       if (rstream->iostream.refcount > 1) {
+               if (!io_stream_unref(&rstream->iostream))
                        i_unreached();
        } else {
                /* The snapshot may contain pointers to the parent istreams.
                   Free it before io_stream_unref() frees the parents. */
-               i_stream_snapshot_free(&_stream->prev_snapshot);
+               i_stream_snapshot_free(&rstream->prev_snapshot);
 
-               if (io_stream_unref(&_stream->iostream))
+               if (io_stream_unref(&rstream->iostream))
                        i_unreached();
-               str_free(&_stream->line_str);
-               i_stream_unref(&_stream->parent);
-               io_stream_free(&_stream->iostream);
+               str_free(&rstream->line_str);
+               i_stream_unref(&rstream->parent);
+               io_stream_free(&rstream->iostream);
        }
-       *stream = NULL;
 }
 
 #undef i_stream_add_destroy_callback