zpl-c / zpl

📐 Pushing the boundaries of simplicity

Home Page:https://blog.zpl.pw

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`name` and `string` fields of `zpl_json_object` have garbage values for `$schema` key

restitux opened this issue · comments

commented

I am parsing the following json5 file.

$schema: 'http://json5.org'

KEY1:      'VAL1'
KEY2:      'VAL2'
KEY3:      'VAL3'

I am parsing it as follows

zpl_json_object root = {0};
zpl_json_parse(root, (char *)fc.data, zpl_heap_allocator());

ssize_t keybinds_len = ZPL_ARRAY_HEADER(root.nodes)->count;
printf("keybinds_len: %ld\n", keybinds_len);
for (ssize_t i = 0; i < keybinds_len; i++) {
    printf("%d\n", root.nodes[i].type);
    printf("name: %s\n", root.nodes[i].name);
    printf("string: %s\n", root.nodes[i].string);

I get the following output

keybinds_len: 4
3
name: ř[
string: G/json5.org
3
name: KEY1
string: VAL1
3
name: KEY2
string: VAL2
3
name: KEY3
string: VAL3

Parsing the $schema key is not working correctly and giving seemingly garbage data for .name, and partially garbage data for string.

commented

Hmm, actually I just tried removing the $schema key and I'm now getting garbage data for KEY1: VAL1

Thanks for the report, I will have a look at it.

Could you share your compile flags and toolchain used? So far I am not able to reproduce this issue on my end.

I have integrated the following new test cases in our suite:

    IT("parses keyval sample in standard JSON5 format", {
        zpl_string t = zpl_string_make(mem_alloc, ""
            "{\n"
                "\"$schema\": 'http://json5.org',\n"
                "\n"
                "\"KEY1\":      'VAL1',\n"
                "\"KEY2\":      'VAL2',\n"
                "\"KEY3\":      'VAL3'\n"
            "}\n"
        );

        __PARSE();

        EQUALS(err, ZPL_JSON_ERROR_NONE);
        EQUALS(zpl_array_count(r.nodes), 4);
        STREQUALS(r.nodes[0].name, "$schema");
        STREQUALS(r.nodes[0].string, "http://json5.org");
        STREQUALS(r.nodes[1].name, "KEY1");
        STREQUALS(r.nodes[1].string, "VAL1");
        STREQUALS(r.nodes[2].name, "KEY2");
        STREQUALS(r.nodes[2].string, "VAL2");
        STREQUALS(r.nodes[3].name, "KEY3");
        STREQUALS(r.nodes[3].string, "VAL3");
    });

    IT("parses keyval sample in SJSON format", {
        zpl_string t = zpl_string_make(mem_alloc, ""
            "$schema: 'http://json5.org'\n"
            "\n"
            "KEY1:      'VAL1'\n"
            "KEY2:      'VAL2'\n"
            "KEY3:      'VAL3'\n"
        );

        __PARSE();

        EQUALS(err, ZPL_JSON_ERROR_NONE);
        EQUALS(zpl_array_count(r.nodes), 4);
        STREQUALS(r.nodes[0].name, "$schema");
        STREQUALS(r.nodes[0].string, "http://json5.org");
        STREQUALS(r.nodes[1].name, "KEY1");
        STREQUALS(r.nodes[1].string, "VAL1");
        STREQUALS(r.nodes[2].name, "KEY2");
        STREQUALS(r.nodes[2].string, "VAL2");
        STREQUALS(r.nodes[3].name, "KEY3");
        STREQUALS(r.nodes[3].string, "VAL3");
    });
commented

Apologies, my example wasn't complete. In my actual code, I was calling zpl_file_free_contents(&fc); between calling zpl_parse_json and iterating root.nodes. Removing this call fixed my problem.

Is there any documentation on this dependency that I missed? I figured the file contents would be fully copied into data store pointed to by zpl_json_object.

Unfortunately, this bit is unclear on our side, parsing happens in place straight on data provided to ensure the lowest amount of friction created by allocations. I'll try to see how to improve the message on this one. Are we good to close this issue?

commented

Yeah that make sense. Generally I've been looking at the .c files in this repo. Maybe adding a comment there (as well as in the header) noting that the underlying object must stay allocated would help expose this behavior.

Thanks!