]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: connection - Fix changing istream in handshake_line() or input_line()
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 21 Feb 2022 15:01:22 +0000 (16:01 +0100)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 21 Feb 2022 15:14:12 +0000 (16:14 +0100)
If the istream was changed (e.g. istream-multiplex added), the following
line was still read using the previous istream.

Fixes errors caused by recent anvil changes:
anvil: Error: Anvil client sent empty line

src/lib/connection.c

index 0d54af3ee496123e9e78d603a85adef6f8987d28..71ace0171cd70b123baa549c41cbdee346e8a068 100644 (file)
@@ -41,7 +41,7 @@ static void connection_connect_timeout(struct connection *conn)
        connection_closed(conn, CONNECTION_DISCONNECT_CONNECT_TIMEOUT);
 }
 
-static void connection_input_parse_lines(struct connection *conn)
+static int connection_input_parse_lines(struct connection *conn)
 {
        const char *line;
        struct istream *input;
@@ -74,6 +74,11 @@ static void connection_input_parse_lines(struct connection *conn)
                } T_END;
                if (ret <= 0)
                        break;
+               if (conn->input != input) {
+                       /* Input handler changed the istream (and maybe
+                          ostream?) Restart reading using the new streams. */
+                       break;
+               }
        }
        if (output != NULL) {
                o_stream_uncork(output);
@@ -86,7 +91,10 @@ static void connection_input_parse_lines(struct connection *conn)
                        reason = CONNECTION_DISCONNECT_DEINIT;
                connection_closed(conn, reason);
        }
+       if (input->closed)
+               ret = -1;
        i_stream_unref(&input);
+       return ret;
 }
 
 void connection_input_default(struct connection *conn)
@@ -116,7 +124,7 @@ void connection_input_default(struct connection *conn)
                i_unreached();
        }
 
-       connection_input_parse_lines(conn);
+       while (connection_input_parse_lines(conn) > 0) ;
 }
 
 int connection_verify_version(struct connection *conn,