]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Fixed json-parser to correctly parse numbers at EOF.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 1 Feb 2016 15:30:23 +0000 (17:30 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 1 Feb 2016 15:45:48 +0000 (17:45 +0200)
Numbers are a bit special compared to others, because they don't have any
clear character indicating that the number ends. So we can only assume that
the number is finished when EOF is reached, although even that isn't
necessarily correct in case the stream is terminated unexpectedly.

This change is in prepartion for the next change. With current JSON parser
this issue could never happen because "}" was expected just before EOF.

src/lib/json-parser.c

index 45f888dfef222f347f101c004ae10771ac8fda9c..09be703b0604efc77a0c605f54cd43939533f33e 100644 (file)
@@ -37,6 +37,7 @@ struct json_parser {
        ARRAY(enum json_state) nesting;
        unsigned int nested_skip_count;
        bool skipping;
+       bool seen_eof;
 };
 
 static int json_parser_read_more(struct json_parser *parser)
@@ -57,13 +58,19 @@ static int json_parser_read_more(struct json_parser *parser)
                        parser->error = "Token too large";
                        return -1;
                }
-               if (ret <= 0)
+               if (ret < 0 && !parser->seen_eof &&
+                   i_stream_get_data_size(parser->input) > 0 &&
+                   parser->input->stream_errno == 0) {
+                       /* call it once more to finish any pending number */
+                       parser->seen_eof = TRUE;
+               } else if (ret <= 0) {
                        return ret;
-
-               cur_highwater = parser->input->v_offset +
-                       i_stream_get_data_size(parser->input);
-               i_assert(parser->highwater_offset < cur_highwater);
-               parser->highwater_offset = cur_highwater;
+               } else {
+                       cur_highwater = parser->input->v_offset +
+                               i_stream_get_data_size(parser->input);
+                       i_assert(parser->highwater_offset < cur_highwater);
+                       parser->highwater_offset = cur_highwater;
+               }
        }
 
        parser->start = parser->data = i_stream_get_data(parser->input, &size);