lib/curl/Adapter: catch and postpone exceptions in WriteFunction()
This fixes a std::terminate() crash in the CURL storage plugin when PropfindOperation::OnHeaders() throws an exception after receiving a non-207 status. Closes https://github.com/MusicPlayerDaemon/MPD/issues/1559
This commit is contained in:
parent
b88d1e6820
commit
5a5655b790
2
NEWS
2
NEWS
|
@ -1,4 +1,6 @@
|
|||
ver 0.23.8 (not yet released)
|
||||
* storage
|
||||
- curl: fix crash if web server does not understand WebDAV
|
||||
|
||||
ver 0.23.7 (2022/05/09)
|
||||
* database
|
||||
|
|
|
@ -85,6 +85,12 @@ CurlResponseHandlerAdapter::FinishBody()
|
|||
void
|
||||
CurlResponseHandlerAdapter::Done(CURLcode result) noexcept
|
||||
{
|
||||
if (postponed_error) {
|
||||
state = State::CLOSED;
|
||||
handler.OnError(std::move(postponed_error));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (result != CURLE_OK) {
|
||||
StripRight(error_buffer);
|
||||
|
@ -172,6 +178,13 @@ CurlResponseHandlerAdapter::DataReceived(const void *ptr,
|
|||
return received_size;
|
||||
} catch (CurlResponseHandler::Pause) {
|
||||
return CURL_WRITEFUNC_PAUSE;
|
||||
} catch (...) {
|
||||
/* from inside this libCURL callback function, we
|
||||
can't do much, so we remember the exception to be
|
||||
handled later by Done(), and return 0, causing the
|
||||
response to be aborted with CURLE_WRITE_ERROR */
|
||||
postponed_error = std::current_exception();
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <curl/curl.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <exception>
|
||||
|
||||
struct StringView;
|
||||
class CurlEasy;
|
||||
|
@ -46,6 +47,12 @@ class CurlResponseHandlerAdapter {
|
|||
|
||||
Curl::Headers headers;
|
||||
|
||||
/**
|
||||
* An exception caught from within the WriteFunction() which
|
||||
* will later be handled by Done().
|
||||
*/
|
||||
std::exception_ptr postponed_error;
|
||||
|
||||
/** error message provided by libcurl */
|
||||
char error_buffer[CURL_ERROR_SIZE];
|
||||
|
||||
|
|
|
@ -50,13 +50,19 @@ public:
|
|||
|
||||
/**
|
||||
* Status line and headers have been received.
|
||||
*
|
||||
* Exceptions thrown by this method will be passed to
|
||||
* OnError(), aborting the request.
|
||||
*/
|
||||
virtual void OnHeaders(unsigned status, Curl::Headers &&headers) = 0;
|
||||
|
||||
/**
|
||||
* Response body data has been received.
|
||||
*
|
||||
* May throw #Pause (but nothing else).
|
||||
* May throw #Pause.
|
||||
*
|
||||
* Other exceptions thrown by this method will be passed to
|
||||
* OnError(), aborting the request.
|
||||
*/
|
||||
virtual void OnData(ConstBuffer<void> data) = 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue