]> granicus.if.org Git - jq/commitdiff
Fix infinite loop on EOF bug
authorNicolas Williams <nico@cryptonector.com>
Wed, 17 Jun 2015 16:23:58 +0000 (11:23 -0500)
committerNicolas Williams <nico@cryptonector.com>
Wed, 17 Jun 2015 16:23:58 +0000 (11:23 -0500)
jv_parse.c
util.c

index d4a55594ea3c5ed104ed1fcb9faf68495a910ed4..cdffd1c01e42b490442ca948c03ff8aaf0be2462 100644 (file)
@@ -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]
diff --git a/util.c b/util.c
index c85de72e6b6ed55f9d69eddb6bd93a21dedecc26..f7e3f91733c8272fd5b714a1a18830dacf487296 100644 (file)
--- a/util.c
+++ b/util.c
@@ -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);