boostorg / json

A C++11 library for parsing and serializing JSON to and from a DOM container in memory.
https://boost.org/libs/json
Boost Software License 1.0
424 stars 94 forks source link

Stack exaustion while value_from(std::filesystem::path) #975

Closed RoyBellingan closed 5 months ago

RoyBellingan commented 5 months ago

PLEASE DON'T FORGET TO "STAR" THIS REPOSITORY :)

Are you inviting me to have multiple account or more friend ?

Version of Boost

1.84

Steps necessary to reproduce the problem

#include <boost/json/src.hpp>
#include <filesystem>
#include <iostream>

namespace bj = boost::json;

int main() {
    std::filesystem::path p = "/cry";

    auto ref = bj::value_from(p);
    auto ser = bj::serialize(ref);
    std::cout << ser;
}

if the path is EMPTY it works fine, but if there is something it leads to a stack exausting crash, remaining struct inside those 2

loop (first one is gcc the other clang, quite similar but a bit different)

image(8)

image(9)

Also using

void tag_invoke(const bj::value_from_tag&, bj::value& jv, const std::filesystem::path& t) {
    jv = t.string();
}

std::filesystem::path tag_invoke(const bj::value_to_tag<std::filesystem::path>&, const boost::json::value& jv) {
    std::filesystem::path path = std::string_view(jv.as_string());
    return path;
}

or

void tag_invoke(const bj::value_from_tag&, bj::value& jv, const std::filesystem::__cxx11::path& t) {
    jv = t.string();
}

std::filesystem::path tag_invoke(const bj::value_to_tag<std::filesystem::__cxx11::path>&, const boost::json::value& jv) {
    std::filesystem::path path = std::string_view(jv.as_string());
    return path;
}

Does not help (in fact looks like they are not even used...)

RoyBellingan commented 5 months ago

The solution is to put the tag_invoke INSIDE the boost::json namespace...

This already happened in another case, for std::chrono,

I think it should be worth to add a note into this page

https://www.boost.org/doc/libs/1_84_0/libs/json/doc/html/json/conversion/custom_conversions.html

To express that, sometimes... you have to put in namespace to help it!

grisumbras commented 5 months ago

The solution (to the error) is to not treat path as a sequence. It's not what users want anyway (everyone would prefer conversion to a string). This will result in value_to<path> being a compilation error.

The next step will be to add a conversion category for paths.

grisumbras commented 5 months ago

The solution is to put the tag_invoke INSIDE the boost::json namespace... I think it should be worth to add a note into this page

From that page:

embed the user-defined type into the arguments list (e.g. by using a tag type template such as value_to_tag) so that its associated namespaces and entities are examined when name lookup is performed.

Maybe we should be less cryptic.

RoyBellingan commented 5 months ago

Yes maybe just drop a few lines about that specific example ? Is ok if I do a pull request for https://github.com/boostorg/json/blob/db92f8c22360990f450fe27b86ea1a5830b5cf05/doc/qbk/conversion/custom.qbk#L54 ?

grisumbras commented 5 months ago

You can create a PR, but before please look for a good place to put the note.