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
726 stars 164 forks source link

segfault when inserting a field into pmr::json #482

Closed romange closed 9 months ago

romange commented 10 months ago

Describe the bug

the code below crashes

  pmr::json dest;
  dest["bar"] = "foo";

should not crash

Enumerate the steps to reproduce the bug

Include a small, self-contained example if possible

What compiler, architecture, and operating system?

What jsoncons library version?

romange commented 10 months ago

The workaround is to declare json object like this: pmr::json dest{json_object_arg};

danielaparker commented 9 months ago

pmr::json dest uses the default constructor, which creates an empty object, with no space allocated for members, hence no need yet for an allocator object.

The statement

dest["bar"] = "foo";

attempts to add a member to the empty object. jsoncons now needs to allocate space for the member, but it will only do so if it detects that the allocator type is stateless, e.g. std::allocator or another allocator type that doesn't hold state. std::pmr::polymorphic_allocator is a stateful allocator, jsoncons detects that, and fails. I had intended that to be a compile time error, and so used a static_assert, but in fact it isn't detected until runtime, which is why it crashed so unceremoniously. I've replaced the static_assert with a runtime exception in the main branch.

Normally you would create a pmr::json something like

std::pmr::polymorphic_allocator<char> alloc(&pool);

pmr::json dest(json_object_arg, alloc);

Then

dest["bar"] = "foo";

would use the memory resource pool that you provided.