diff options
author | Nicolas Williams <nico@cryptonector.com> | 2015-06-17 11:23:58 -0500 |
---|---|---|
committer | Nicolas Williams <nico@cryptonector.com> | 2015-06-17 11:23:58 -0500 |
commit | 0f5345e515e269470f50a584ad3a6c63213d4d38 (patch) | |
tree | 24d80e1e6da4fdce900f26ebb497e624681d808b | |
parent | c95b4a8ab4ace9389788bd26a181d1b7448600ec (diff) |
Fix infinite loop on EOF bug
-rw-r--r-- | jv_parse.c | 7 | ||||
-rw-r--r-- | util.c | 4 |
2 files changed, 10 insertions, 1 deletions
@@ -31,6 +31,7 @@ struct jv_parser { int curr_buf_length; int curr_buf_pos; int curr_buf_is_partial; + int eof; unsigned bom_strip_position; int flags; @@ -77,6 +78,7 @@ static void parser_init(struct jv_parser* p, int flags) { p->tokenbuf = 0; p->tokenlen = p->tokenpos = 0; p->st = JV_PARSER_NORMAL; + p->eof = 0; p->curr_buf = 0; p->curr_buf_length = p->curr_buf_pos = p->curr_buf_is_partial = 0; p->bom_strip_position = 0; @@ -706,6 +708,8 @@ static jv make_error(struct jv_parser* p, const char *fmt, ...) { } jv jv_parser_next(struct jv_parser* p) { + if (p->eof) + return jv_invalid(); if (!p->curr_buf) return jv_invalid(); // Need a buffer if (p->bom_strip_position == 0xff) return jv_invalid_with_msg(jv_string("Malformed BOM")); @@ -745,6 +749,7 @@ jv jv_parser_next(struct jv_parser* p) { return jv_invalid(); } else { // at EOF + p->eof = 1; assert(p->curr_buf_pos == p->curr_buf_length); jv_free(value); if (p->st != JV_PARSER_WAITING_FOR_RS) { @@ -768,7 +773,7 @@ jv jv_parser_next(struct jv_parser* p) { return value; } } - // p->next is either invalid (nothing here but no syntax error) + // p->next is either invalid (nothing here, but no syntax error) // or valid (this is the value). either way it's the thing to return if ((p->flags & JV_PARSE_STREAMING) && jv_is_valid(p->next)) { value = JV_ARRAY(jv_copy(p->path), p->next); // except in streaming mode we've got to make it [path,value] @@ -393,6 +393,10 @@ jv jq_util_input_next_input(jq_util_input_state state) { } else { if (jv_parser_remaining(state->parser) == 0) { is_last = jq_util_input_read_more(state); + if (is_last && state->buf_valid_len == 0) { + value = jv_invalid(); + break; + } jv_parser_set_buf(state->parser, state->buf, state->buf_valid_len, !is_last); } value = jv_parser_next(state->parser); |