From 34558825a27f4d74dcfd7a91bfde4464baa2a30a Mon Sep 17 00:00:00 2001 From: "Alessandro de Oliveira Faria (A.K.A.CABELO)" Date: Sun, 12 Jul 2026 20:10:03 -0300 Subject: [PATCH] vendor : update cpp-httplib to 0.50.1 (#25576) --- scripts/sync_vendor.py | 2 +- vendor/cpp-httplib/httplib.cpp | 35 +++++++++++++++++++++++++++++----- vendor/cpp-httplib/httplib.h | 6 ++++-- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/scripts/sync_vendor.py b/scripts/sync_vendor.py index f66e78d639..7bab415a83 100755 --- a/scripts/sync_vendor.py +++ b/scripts/sync_vendor.py @@ -5,7 +5,7 @@ import os import sys import subprocess -HTTPLIB_VERSION = "refs/tags/v0.49.0" +HTTPLIB_VERSION = "refs/tags/v0.50.1" vendor = { "https://github.com/nlohmann/json/releases/latest/download/json.hpp": "vendor/nlohmann/json.hpp", diff --git a/vendor/cpp-httplib/httplib.cpp b/vendor/cpp-httplib/httplib.cpp index d65b7921b4..e58fb3eea6 100644 --- a/vendor/cpp-httplib/httplib.cpp +++ b/vendor/cpp-httplib/httplib.cpp @@ -3705,6 +3705,12 @@ write_content_chunked(Stream &strm, const ContentProvider &content_provider, // Trailer if (trailer) { for (const auto &kv : *trailer) { + // Skip fields with invalid names or values to prevent response + // splitting via CR/LF injection, matching set_header(). + if (!fields::is_field_name(kv.first) || + !fields::is_field_value(kv.second)) { + continue; + } std::string field_line = kv.first + ": " + kv.second + "\r\n"; if (!write_data(strm, field_line.data(), field_line.size())) { ok = false; @@ -8301,8 +8307,8 @@ void Server::apply_ranges(const Request &req, Response &res, } } - auto length = std::to_string(res.body.size()); - res.set_header("Content-Length", length); + res.content_length_ = res.body.size(); + res.set_header("Content-Length", std::to_string(res.content_length_)); } } @@ -10270,6 +10276,11 @@ Result ClientImpl::Get(const std::string &path, return Get(path, Headers(), std::move(progress)); } +Result ClientImpl::Get(const std::string &path, const Params ¶ms, + DownloadProgress progress) { + return Get(path, params, Headers(), std::move(progress)); +} + Result ClientImpl::Get(const std::string &path, const Params ¶ms, const Headers &headers, DownloadProgress progress) { @@ -11348,6 +11359,10 @@ Result Client::Get(const std::string &path, const Headers &headers, return cli_->Get(path, headers, std::move(response_handler), std::move(content_receiver), std::move(progress)); } +Result Client::Get(const std::string &path, const Params ¶ms, + DownloadProgress progress) { + return cli_->Get(path, params, std::move(progress)); +} Result Client::Get(const std::string &path, const Params ¶ms, const Headers &headers, DownloadProgress progress) { return cli_->Get(path, params, headers, std::move(progress)); @@ -12076,11 +12091,18 @@ bool SSLServer::update_certs_pem(const char *cert_pem, // SSL HTTP client implementation SSLClient::~SSLClient() { - if (ctx_) { tls::free_context(ctx_); } // Make sure to shut down SSL since shutdown_ssl will resolve to the // base function rather than the derived function once we get to the // base class destructor, and won't free the SSL (causing a leak). + // This must happen before the context is freed below: some backends + // (e.g. mbedTLS) have the SSL session borrow a raw pointer into the + // context, so freeing the context first leaves close_notify reading + // freed memory. shutdown_ssl_impl(socket_, true); + if (ctx_) { + tls::free_context(ctx_); + ctx_ = nullptr; + } } bool SSLClient::is_valid() const { return ctx_ != nullptr; } @@ -16501,6 +16523,11 @@ WebSocketClient::~WebSocketClient() { bool WebSocketClient::is_valid() const { return is_valid_; } void WebSocketClient::shutdown_and_close() { + // Send the close frame while the TLS session is still alive: ws_ holds an + // SSLSocketStream that keeps a raw pointer to tls_session_, so the session + // must outlive ws_->close() and ws_.reset() to avoid a use-after-free. + if (ws_ && ws_->is_open()) { ws_->close(); } + ws_.reset(); #ifdef CPPHTTPLIB_SSL_ENABLED if (is_ssl_) { if (tls_session_) { @@ -16510,8 +16537,6 @@ void WebSocketClient::shutdown_and_close() { } } #endif - if (ws_ && ws_->is_open()) { ws_->close(); } - ws_.reset(); if (sock_ != INVALID_SOCKET) { detail::shutdown_socket(sock_); detail::close_socket(sock_); diff --git a/vendor/cpp-httplib/httplib.h b/vendor/cpp-httplib/httplib.h index e7ef56370c..de026a2532 100644 --- a/vendor/cpp-httplib/httplib.h +++ b/vendor/cpp-httplib/httplib.h @@ -8,8 +8,8 @@ #ifndef CPPHTTPLIB_HTTPLIB_H #define CPPHTTPLIB_HTTPLIB_H -#define CPPHTTPLIB_VERSION "0.49.0" -#define CPPHTTPLIB_VERSION_NUM "0x003100" +#define CPPHTTPLIB_VERSION "0.50.1" +#define CPPHTTPLIB_VERSION_NUM "0x003201" #ifdef _WIN32 #if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0A00 @@ -2219,6 +2219,7 @@ public: Result Get(const std::string &path, const Headers &headers, DownloadProgress progress = nullptr); Result Get(const std::string &path, const Headers &headers, ContentReceiver content_receiver, DownloadProgress progress = nullptr); Result Get(const std::string &path, const Headers &headers, ResponseHandler response_handler, ContentReceiver content_receiver, DownloadProgress progress = nullptr); + Result Get(const std::string &path, const Params ¶ms, DownloadProgress progress = nullptr); Result Get(const std::string &path, const Params ¶ms, const Headers &headers, DownloadProgress progress = nullptr); Result Get(const std::string &path, const Params ¶ms, const Headers &headers, ContentReceiver content_receiver, DownloadProgress progress = nullptr); Result Get(const std::string &path, const Params ¶ms, const Headers &headers, ResponseHandler response_handler, ContentReceiver content_receiver, DownloadProgress progress = nullptr); @@ -2602,6 +2603,7 @@ public: Result Get(const std::string &path, const Headers &headers, DownloadProgress progress = nullptr); Result Get(const std::string &path, const Headers &headers, ContentReceiver content_receiver, DownloadProgress progress = nullptr); Result Get(const std::string &path, const Headers &headers, ResponseHandler response_handler, ContentReceiver content_receiver, DownloadProgress progress = nullptr); + Result Get(const std::string &path, const Params ¶ms, DownloadProgress progress = nullptr); Result Get(const std::string &path, const Params ¶ms, const Headers &headers, DownloadProgress progress = nullptr); Result Get(const std::string &path, const Params ¶ms, const Headers &headers, ContentReceiver content_receiver, DownloadProgress progress = nullptr); Result Get(const std::string &path, const Params ¶ms, const Headers &headers, ResponseHandler response_handler, ContentReceiver content_receiver, DownloadProgress progress = nullptr);