Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect move of wvalue class #953

Open
CraigBorrows opened this issue Nov 28, 2024 · 0 comments
Open

Incorrect move of wvalue class #953

CraigBorrows opened this issue Nov 28, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@CraigBorrows
Copy link

CraigBorrows commented Nov 28, 2024

When moving wvalue objects that contain negative integers, they are incorrectly serialized as large positive numbers. This issue occurs due to an improperly implemented move constructor in the wvalue class, which fails to correctly transfer all member variables, particularly the nt (number type) member and the num union. As a result, the moved wvalue object loses the correct number type information, leading to incorrect serialization of negative integers.

      crow::json::wvalue int_value(-500);
      crow::json::wvalue copy_value(std::move(int_value));
      std::cout << int_value.dump() << " " << copy_value.dump() << std::endl;
      

Output:

  -500 18446744073709551116

OR

    static crow::json::wvalue getValue(int i){
        return crow::json::wvalue(i);
    }
      
      crow::json::wvalue json;
      json["int_value"] = getValue(-500);
      std::cout << json["int_value"].dump();

Output:

  18446744073709551116

Its possible that im using the wvalue incorrecly, please let me know

Solution:

wvalue(wvalue&& r) noexcept
    : returnable(std::move(r)),
      t_(r.t_),
      nt(r.nt),
      num(r.num),
      s(std::move(r.s)),
      l(std::move(r.l)),
      o(std::move(r.o)),
      f(std::move(r.f))
{}

wvalue& operator=(wvalue&& r) noexcept
{
    if (this != &r)
    {
        // Move base class part
        returnable::operator=(std::move(r));

        // Move primitive types
        t_ = r.t_;
        nt = r.nt;
        num = r.num;

        // Move movable members
        s = std::move(r.s);
        l = std::move(r.l);
        o = std::move(r.o);
        f = std::move(r.f);
    }
    return *this;
}
  • Proper Movement of Members: All member variables, including nt and num, are correctly moved from r to *this.
  • Avoiding Undefined Behavior: By directly moving each member, we ensure that no undefined behavior occurs due to missing assignment operators.
  • Preservation of Number Type Information: Ensures that the nt value and num union are correctly preserved during the move, allowing accurate serialization.

Output after move update:

  -500 -500
@gittiver gittiver added the bug Something isn't working label Nov 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

2 participants