xexyl / jparse

jparse - a JSON parser
2 stars 2 forks source link

Bug: `jparse -J json_debug_level` in some cases (JTYPE_STRINGS) segfaults #27

Closed xexyl closed 2 hours ago

xexyl commented 3 hours ago

Is there an existing issue for this?

Describe the bug

An interesting problem is that when using -J level with jparse is it segfaults when printing strings. I guess a NULL pointer but I can barely see right now which is why I'm opening this instead - to remind me. Examples below of where it works fine and where it does not work fine.

What you expect

That jparse -J 3 should work fine.

Environment

jparse_bug_report.sh output

n/a as the tool does not even use the -J option.

Anything else?

This works fine:

$ jparse -J 3 -s '""'
JSON tree[3]:   lvl: 0  type: JTYPE_STRING  len{p,c:q(null)}: 4271894   value:  ""
in parse_json(): JSON debug[1]: valid JSON

as does this:

$ jparse -J 3 -s 5
JSON tree[3]:   lvl: 0  type: JTYPE_NUMBER  {p,c:FI8SSomfi}: value: 5
in parse_json(): JSON debug[1]: valid JSON

But this does not:

$ ./jparse -J 3 -s '"foo"'
JSON tree[3]:   lvl: 0  type: JTYPE_STRINGSegmentation fault (core dumped)

Stack trace:

Reading symbols from ./jparse...
[New LWP 2724055]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `./jparse -J 3 -s "foo"'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007fb84055d0fd in __strlen_avx2 () from /lib64/libc.so.6
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.34-100.el9_4.4.x86_64
(gdb) bt
#0  0x00007fb84055d0fd in __strlen_avx2 () from /lib64/libc.so.6
#1  0x00007fb84046e6b8 in __vfprintf_internal () from /lib64/libc.so.6
#2  0x00007fb84046ee7f in buffered_vfprintf () from /lib64/libc.so.6
#3  0x00000000004175ce in vfpr (stream@entry=<optimized out>, name@entry=<optimized out>, fmt@entry=<optimized out>, ap@entry=<optimized out>)
    at util.c:1845
#4  0x00000000004177c7 in fpr (stream@entry=<optimized out>, name@entry=<optimized out>, fmt@entry=<optimized out>) at util.c:1909
#5  0x000000000041319e in vjson_fprint (node@entry=<optimized out>, depth@entry=<optimized out>, ap@entry=<optimized out>) at json_util.c:1665
#6  0x0000000000414370 in vjson_tree_walk (node@entry=<optimized out>, max_depth@entry=<optimized out>, depth@entry=<optimized out>, 
    post_order@entry=<optimized out>, vcallback@entry=<optimized out>, ap@entry=<optimized out>) at json_util.c:2280
#7  0x00000000004140f6 in json_tree_print (node@entry=<optimized out>, max_depth@entry=<optimized out>) at json_util.c:2035
#8  0x000000000041419e in json_dbg_tree_print (json_dbg_lvl@entry=<optimized out>, name@entry=<optimized out>, tree@entry=<optimized out>, 
    max_depth@entry=<optimized out>) at json_util.c:2118
#9  0x0000000000407f80 in jparse_parse (tree@entry=<optimized out>, scanner@entry=<optimized out>) at ./jparse.y:252
#10 0x0000000000406ccc in parse_json (ptr@entry=<optimized out>, len@entry=<optimized out>, filename@entry=<optimized out>, 
    is_valid@entry=<optimized out>) at ./jparse.l:596
#11 0x0000000000402737 in main (argc@entry=<optimized out>, argv@entry=<optimized out>) at jparse_main.c:149

Unfortunately it's optimising it out even though -O0.

This should obviously not happen. It even happens with version:

jparse version: 1.2.0 2024-10-09
jparse UTF-8 version: 1.2.2 2024-10-13
jparse library version: 1.2.1 2024-10-22

The output should be:

JSON tree[3]:   lvl: 0  type: JTYPE_STRING  len{p,c:qPa}: 3 value:  "foo"
in parse_json(): JSON debug[1]: valid JSON

which is from:

1.1.6 2024-09-07

... which is some time ago, though it probably was not the last one that that worked in. Nonetheless it might help isolate the problem when I am more alert.

xexyl commented 3 hours ago

It is this code:

 if (CONVERTED_PARSED_JSON_NODE(item)) {

                /*
                 * print string preamble
                 */
                fprint(stream, "\tlen{%s%s%s%s%s%s%s%s%s%s}: %ju\tvalue:\t",
                                PARSED_JSON_NODE(item)?"p":"",
                                CONVERTED_PARSED_JSON_NODE(item)?",":":",
                                CONVERTED_PARSED_JSON_NODE(item)?"c:":"",
                                item->quote ? "q" : "",
                                item->same ? "=" : "",
                                item->slash ? "/" : "",
                                item->posix_safe ? "P" : "",
                                item->first_alphanum ? "a" : "",
                                item->upper ? "U" : "",
                                (uintmax_t)item->str_len);
                (void) fprint_line_buf(stream, item->str, item->str_len, '"', '"');

and in particular fprint().

xexyl commented 3 hours ago

I've isolated the problem. It was the removal of has_nul.

xexyl commented 3 hours ago

Oh how simple! I forgot to update the format string ...

xexyl commented 2 hours ago

This has been fixed. It means too that the mkiocccentry needs that fix, maybe, though that means the major changes of today.