Repository: jqlang/jq

Problem statement:
jq: src/jv_parse.c:305: stream_token: Assertion `k == JV_KIND_NULL' failed.
<!--
READ THIS FIRST!

If you have a usage question, please ask us on either Stack Overflow (https://stackoverflow.com/questions/tagged/jq) or in the #jq channel (http://irc.lc/freenode/%23jq/) on Freenode (https://webchat.freenode.net/).

-->

**Describe the bug**
 Reachable Assertion

**To Reproduce**
jq --stream '' input.json, the input.json is as fllow:
   {    "" : null ,-87.0E+008,
 "."
 ""
           null

jq: src/jv_parse.c:305: stream_token: Assertion `k == JV_KIND_NULL' failed.

Program received signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff71bb859 in __GI_abort () at abort.c:79
#2  0x00007ffff71bb729 in __assert_fail_base (fmt=0x7ffff7351588 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x55555569cda0 "k == JV_KIND_NULL", file=0x55555569c140 "src/jv_parse.c", line=305, function=<optimized out>) at assert.c:92
#3  0x00007ffff71ccf36 in __GI___assert_fail (assertion=assertion@entry=0x55555569cda0 "k == JV_KIND_NULL", file=file@entry=0x55555569c140 "src/jv_parse.c", line=line@entry=305, function=function@entry=0x55555569d3c0 <__PRETTY_FUNCTION__.3911> "stream_token") at assert.c:101
#4  0x00005555555dd9c0 in stream_token (ch=<optimized out>, p=<optimized out>) at src/jv_parse.c:305
#5  scan (out=<optimized out>, ch=<optimized out>, p=<optimized out>) at src/jv_parse.c:658
#6  jv_parser_next (p=<optimized out>) at src/jv_parse.c:767
#7  0x00005555555ef52d in jq_util_input_next_input (state=0x621000000100) at src/util.c:434
#8  0x000055555557908f in main (argc=argc@entry=4, argv=argv@entry=0x7fffffffe2d8) at src/main.c:676
#9  0x00007ffff71bd0b3 in __libc_start_main (main=0x555555575ac0 <main>, argc=4, argv=0x7fffffffe2d8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe2c8) at ../csu/libc-start.c:308
#10 0x000055555557d34e in _start () at src/main.c:173


**Expected behavior**
An error, not an assert.

**Environment (please complete the following information):**
 - OS and Version:ubuntu/Linux
 - jq version [jq-stable-773baf93-dirty]

**Additional context**
Found via afl++



Hints:
I wonder if the issue is that https://github.com/jqlang/jq/blob/master/src/jv_parse.c#L302
```c
p->path = jv_array_set(p->path, p->stacklen - 1, jv_true()); // ready for another name:value pair
```
should actually set `jq_null()`? that is at least how the path is setup at the start of an object https://github.com/jqlang/jq/blob/master/src/jv_parse.c#L254-L258
```c
  case '{':
    if (p->last_seen == JV_LAST_VALUE)
      return "Expected a separator between values";
    // Push object key: null, since we don't know it yet
    p->path = jv_array_append(p->path, jv_null()); // push
```
then the assert https://github.com/jqlang/jq/blob/master/src/jv_parse.c#L305 makes more sense
```c
      assert(k == JV_KIND_NULL);
      // this case hits on input like {,}
      // make sure to handle input like {"a", "b"} and {"a":, ...}
      jv_free(last);
      return "Objects must consist of key:value pairs";
```

Patch:
diff --git a/src/jv_parse.c b/src/jv_parse.c
index 9ced9f6d23..e91f65d02b 100644
--- a/src/jv_parse.c
+++ b/src/jv_parse.c
@@ -299,7 +299,7 @@ static pfunc stream_token(struct jv_parser* p, char ch) {
         p->output = JV_ARRAY(jv_copy(p->path), p->next);
         p->next = jv_invalid();
       }
-      p->path = jv_array_set(p->path, p->stacklen - 1, jv_true()); // ready for another name:value pair
+      p->path = jv_array_set(p->path, p->stacklen - 1, jv_null()); // ready for another key:value pair
       p->last_seen = JV_LAST_COMMA;
     } else {
       assert(k == JV_KIND_NULL);


Test patch:
diff --git a/tests/shtest b/tests/shtest
index 4a4f855a64..4cffb1f821 100755
--- a/tests/shtest
+++ b/tests/shtest
@@ -203,6 +203,10 @@ else
     echo "Not doing torture tests"
 fi
 
+## Regression test for issue #2378 assert when stream parse broken object pair
+echo '{"a":1,"b",' | $JQ --stream  > /dev/null 2> $d/err
+grep 'Objects must consist of key:value pairs' $d/err > /dev/null
+
 ## Fuzz parser
 
 ## XXX With a $(urandom) builtin we could move this test into tests/all.test