]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-json: json-parser - Fix stream read size calculations in JSON string istream
authorStephan Bosch <stephan.bosch@open-xchange.com>
Tue, 28 Nov 2023 20:54:30 +0000 (21:54 +0100)
committerstephan.bosch <stephan.bosch@open-xchange.com>
Wed, 29 Nov 2023 12:35:46 +0000 (12:35 +0000)
src/lib-json/json-parser.c

index bc19886c2ad674d2eacedbbf4f13601fc4fe4f56..08df2c496e890cb9ca8adfd16f2a749a7b23e2d9 100644 (file)
@@ -2301,7 +2301,7 @@ static ssize_t json_string_istream_read(struct istream_private *stream)
                (struct json_string_istream *)stream;
        struct json_parser *parser = jstream->parser;
        bool stop_loop;
-       size_t old_pos;
+       size_t old_pos, read_size, read_total;
        int ret;
 
        if (jstream->ended) {
@@ -2313,15 +2313,16 @@ static ssize_t json_string_istream_read(struct istream_private *stream)
        i_assert(stream->pos == str_len(parser->buffer));
        i_assert(stream->skip <= stream->pos);
 
+       read_total = 0;
        do {
                if (jstream->buffer_overflowed) {
-                       stream->pos = str_len(parser->buffer);
-                       if (stream->skip == stream->pos)
+                       if (stream->skip == str_len(parser->buffer))
                                str_truncate(parser->buffer, 0);
                        else if (stream->skip > 0)
                                str_delete(parser->buffer, 0, stream->skip);
                        else
                                return -2;
+                       stream->pos = str_len(parser->buffer);
                        stream->skip = 0;
                        jstream->buffer_overflowed = FALSE;
                }
@@ -2329,7 +2330,9 @@ static ssize_t json_string_istream_read(struct istream_private *stream)
                old_pos = str_len(parser->buffer);
                ret = json_parser_continue(parser);
                i_assert(str_len(parser->buffer) >= old_pos);
-               stop_loop = (str_len(parser->buffer) > old_pos);
+               read_size = str_len(parser->buffer) - old_pos;
+               stop_loop = (read_size > 0);
+               read_total += read_size;
                switch (ret) {
                case JSON_PARSE_INTERRUPTED:
                        i_assert(stream->skip == 0 ||
@@ -2345,9 +2348,8 @@ static ssize_t json_string_istream_read(struct istream_private *stream)
                        stop_loop = TRUE;
                        break;
                case JSON_PARSE_NO_DATA:
-                       stream->buffer = str_data(parser->buffer);
-                       stream->pos = str_len(parser->buffer);
-                       return 0;
+                       stop_loop = TRUE;
+                       break;
                case JSON_PARSE_ERROR:
                        io_stream_set_error(&stream->iostream,
                                            "%s", parser->error);
@@ -2365,7 +2367,7 @@ static ssize_t json_string_istream_read(struct istream_private *stream)
 
        stream->pos = str_len(parser->buffer);
        stream->buffer = str_data(parser->buffer);
-       return (ssize_t)(stream->pos - old_pos);
+       return (ssize_t)read_total;
 }
 
 static void