Skip to content

Json should not be constructible with 'json*' #448

Closed

Description

@jaredgrubb

I had something like this:

        json* p;
        json j(p);

This was a bug (I need to dereference the pointer), but json constructor accepts it as a boolean type because it's finding this overload:

template<typename BasicJsonType>
void to_json(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept

The problem with 'bool' is that it captures a lot of things. Classes with 'operator bool()' are also being caught.

I can think of some simple changes (SFINAE something), but I'm not sure how well they work with arbitrary BasicJsonType's.

Activity

  1. jaredgrubb commented on Feb 12, 2017

    @jaredgrubb
    ContributorAuthor

    Maybe the default to_/from_json should be implemented just for the common C++ types (bool, std::string, std::map, std::vector) and not in terms of BasicJson::whatever_t, and if you specialize basic_json then you have to also manually opt-in to the right to_/from_json overloads?

  2. theodelrieu commented on Feb 13, 2017

    @theodelrieu
    Contributor

    If I remember correctly, there was a constructor for each BasicJsonType:: whatever _t prior to 2.1.0.

    So I think we should keep those overloads for now, to keep backward compatibility.

    To avoid this implicit conversion, I guess a simple std::is_same<typename BasicJsonType::boolean_t, T> in the enable_if will do the trick. It would be great to fix similar issues with different parameter types (integers and so on)

    Unfortunately I don't have a laptop at hand until Sunday to test this

  3. nlohmann commented on Feb 13, 2017

    @nlohmann
    Owner

    @theodelrieu I agree in both points, and I think I won't have time to fix this this week either.

  4. jaredgrubb commented on Feb 14, 2017

    @jaredgrubb
    ContributorAuthor

    I have done this and it seems to work:

    -template<typename BasicJsonType>
    -void to_json(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
    +template<typename BasicJsonType, typename T,
    +    enable_if_t<std::is_same<std::decay_t<T>, typename BasicJsonType::boolean_t>::value, int> = 0>
    +void to_json(BasicJsonType& j, T b) noexcept
    

    I'm not 100% that the decay is necessary.

  5. self-assigned this
    on Feb 19, 2017
  6. added this to the Release 2.1.1 milestone on Feb 19, 2017
  7. added a commit that references this issue on Feb 19, 2017
  8. nlohmann commented on Feb 19, 2017

    @nlohmann
    Owner

    Fixed using @jaredgrubb 's proposal.

  9. theodelrieu commented on Feb 20, 2017

    @theodelrieu
    Contributor

    I don't think the decay is useful, but that's a minor thing.

    Thanks for the fix!

  10. nlohmann commented on Feb 20, 2017

    @nlohmann
    Owner

    I shall remove the decay then.

  11. added a commit that references this issue on Feb 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions