danielaparker / jsoncons

A C++, header-only library for constructing JSON and JSON-like data formats, with JSON Pointer, JSON Patch, JSON Schema, JSONPath, JMESPath, CSV, MessagePack, CBOR, BSON, UBJSON
https://danielaparker.github.io/jsoncons
Other
700 stars 158 forks source link

Character escapes in jsonpath::json_location::to_string #410

Closed gerdy-d closed 1 year ago

gerdy-d commented 1 year ago

Describe the bug

It seems that json_location::to_string (jsonpath) only escapes single quotes (and no other characters) within a json_location_node_kind::name.

Enumerate the steps to reproduce the bug

Please see the example below.

Include a small, self-contained example if possible

Consider the following example program (#includes omitted):

    const json j = json::parse(LR"({"\\":0})");
    const std::wstring p = LR"($['\\'])";
    jsonpath::json_query(j,
                         p,
                         [](const json::string_view_type& normalized_path, const json&) {
                             std::wcout << normalized_path;
                         },
                         jsonpath::result_options::path);

This prints: $['']

I'm not entirely sure, but I would expect the program to print $['\\']

Using jsoncons::jsonpath::escape_string(node->name().c_str(), node->name().length(), buffer); at lines 331-342 seems to result in the output $['\\'], but I'm uncertain if this modification in the code would be correct.

Thanks in advance for looking into this.

What compiler, architecture, and operating system?

What jsoncons library version?

danielaparker commented 1 year ago

Regarding your example, I'm pretty sure we don't support that combination of narrow characters and wide characters!

But yes, you're right, we should be using jsoncons::jsonpath::escape string to escape the node names. This will be fixed in the next release.

danielaparker commented 1 year ago

Fix is on master. This code

std::string json_string = R"({"\\":0})";
std::cout << "json string: " << json_string << "\n\n";

const json j = json::parse(json_string);

const std::string p = R"($['\\'])";
jsonpath::json_query(j,
    p,
    [j](const json::string_view_type& normalized_path, const json&) {
        auto result = jsonpath::json_query(j, normalized_path);
        std::cout << "normalized_path: " << normalized_path << ", result: " << result << "\n";
    },
    jsonpath::result_options::path);

now produces

json string: {"\\":0}

normalized_path: $['\\'], result: [0]
gerdy-d commented 1 year ago

Sorry for the confusion regarding narrow and wide characters, I forgot to paste this line in my example: using json = jsoncons::wojson;

Thanks for the fix!

danielaparker commented 1 year ago

Fix is in 0.170.0