libcpr / cpr

C++ Requests: Curl for People, a spiritual port of Python Requests.
https://docs.libcpr.org/
Other
6.29k stars 904 forks source link

Dangling reference when moving after SetDebugCallback #961

Closed kone-tlammi closed 9 months ago

kone-tlammi commented 9 months ago

Description

Moving cpr::Session after SetDebugCallback is invoked results in a dangling reference: https://github.com/libcpr/cpr/blob/master/cpr/session.cpp#L279

Other callbacks likely also affected.

Example/How to Reproduce

// cprbug.cpp
#include <cpr/cpr.h>

void use_session(cpr::Session s) {
  s.SetUrl("https://github.com/libcpr/cpr");
  s.Get();
}

int main() {
  auto s = cpr::Session();
  s.SetDebugCallback(cpr::DebugCallback([](auto, auto, auto) {}));
  use_session(std::move(s));
}

Compiled with GCC 13.2.1: g++ -g -std=c++20 ./cprbug.cpp -lcpr

If the use_session() is inlined everything works fine.

Possible Fix

A couple of possible ways to fix this:

Where did you get it from?

Other (specify in "Additional Context/Your Environment")

Additional Context/Your Environment

COM8 commented 9 months ago

Whoops, thanks for reporting @kone-tlammi! In my eyes the custom move ctr is the way to go here.

Any chance you want to look into this since I don't have time for it for the next two weeks or so.

kone-tlammi commented 9 months ago

I can if I have a free slot at some point.

I'm thinking something like the snippet below (with a better interface) to avoid missing a move.


template<class T>
struct CurlCallbackData{
    CurlCallbackData(CurlCallbackData&& other) noexcept:
        h{other.h}, curlopt{other.curlopt}, data{std::move(other.data)}{
        curl_easy_setopt(h, curlopt, &data);
    }
    CURL* h{};
    int curlopt;
    T data;
};
kone-tlammi commented 9 months ago

Should be fixed by https://github.com/libcpr/cpr/pull/962