diff --git a/CVE-2025-0825.patch b/CVE-2025-0825.patch deleted file mode 100644 index 3d4a08b0a798a729c72e1550932ccd0eeca827eb..0000000000000000000000000000000000000000 --- a/CVE-2025-0825.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 9c36aae4b73e2b6e493f4133e4173103c9266289 Mon Sep 17 00:00:00 2001 -From: yhirose -Date: Thu, 16 Jan 2025 00:04:17 -0500 -Subject: [PATCH] Fix HTTP Response Splitting Vulnerability - ---- - httplib.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 59 insertions(+), 3 deletions(-) - -diff --git a/httplib.h b/httplib.h -index 5a4b64a..86a7452 100644 ---- a/httplib.h -+++ b/httplib.h -@@ -2159,6 +2159,60 @@ private: - void *addr_; - }; - -+// NOTE: https://www.rfc-editor.org/rfc/rfc9110#section-5 -+namespace fields { -+ -+inline bool is_token_char(char c) { -+ return std::isalnum(c) || c == '!' || c == '#' || c == '$' || c == '%' || -+ c == '&' || c == '\'' || c == '*' || c == '+' || c == '-' || -+ c == '.' || c == '^' || c == '_' || c == '`' || c == '|' || c == '~'; -+} -+ -+inline bool is_token(const std::string &s) { -+ if (s.empty()) { return false; } -+ for (auto c : s) { -+ if (!is_token_char(c)) { return false; } -+ } -+ return true; -+} -+ -+inline bool is_field_name(const std::string &s) { return is_token(s); } -+ -+inline bool is_vchar(char c) { return c >= 33 && c <= 126; } -+ -+inline bool is_obs_text(char c) { return 128 <= static_cast(c); } -+ -+inline bool is_field_vchar(char c) { return is_vchar(c) || is_obs_text(c); } -+ -+inline bool is_field_content(const std::string &s) { -+ if (s.empty()) { return false; } -+ -+ if (s.size() == 1) { -+ return is_field_vchar(s[0]); -+ } else if (s.size() == 2) { -+ return is_field_vchar(s[0]) && is_field_vchar(s[1]); -+ } else { -+ size_t i = 0; -+ -+ if (!is_field_vchar(s[i])) { return false; } -+ i++; -+ -+ while (i < s.size() - 1) { -+ auto c = s[i++]; -+ if (c == ' ' || c == '\t' || is_field_vchar(c)) { -+ } else { -+ return false; -+ } -+ } -+ -+ return is_field_vchar(s[i]); -+ } -+} -+ -+inline bool is_field_value(const std::string &s) { return is_field_content(s); } -+ -+}; // namespace fields -+ - } // namespace detail - - // ---------------------------------------------------------------------------- -@@ -5118,7 +5172,8 @@ inline size_t Request::get_header_value_count(const std::string &key) const { - - inline void Request::set_header(const std::string &key, - const std::string &val) { -- if (!detail::has_crlf(key) && !detail::has_crlf(val)) { -+ if (detail::fields::is_field_name(key) && -+ detail::fields::is_field_value(val)) { - headers.emplace(key, val); - } - } -@@ -5183,13 +5238,14 @@ inline size_t Response::get_header_value_count(const std::string &key) const { - - inline void Response::set_header(const std::string &key, - const std::string &val) { -- if (!detail::has_crlf(key) && !detail::has_crlf(val)) { -+ if (detail::fields::is_field_name(key) && -+ detail::fields::is_field_value(val)) { - headers.emplace(key, val); - } - } - - inline void Response::set_redirect(const std::string &url, int stat) { -- if (!detail::has_crlf(url)) { -+ if (detail::fields::is_field_value(url)) { - set_header("Location", url); - if (300 <= stat && stat < 400) { - this->status = stat; --- -2.43.0 - diff --git a/CVE-2025-46728.patch b/CVE-2025-46728.patch deleted file mode 100644 index b3e5682ce312daa9ebee0d14fe1f296ab0d85150..0000000000000000000000000000000000000000 --- a/CVE-2025-46728.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 7b752106ac42bd5b907793950d9125a0972c8e8e Mon Sep 17 00:00:00 2001 -From: Ville Vesilehto -Date: Sat, 3 May 2025 11:39:01 +0300 -Subject: [PATCH] Merge commit from fork - -* fix(parser): Limit line length in getline - -Prevents potential infinite loop and memory exhaustion in -stream_line_reader::getline by enforcing max line length. - -Signed-off-by: Ville Vesilehto - -* fix: increase default max line length to 32k - -LONG_QUERY_VALUE test is set at 25k. - -Signed-off-by: Ville Vesilehto - -* test(client): expect read error with too long query - -Adds a test case (`TooLongQueryValue`) to verify client behavior -when the request URI is excessively long, exceeding -`CPPHTTPLIB_MAX_LINE_LENGTH`. In this scenario, the server is -expected to reset the connection. - -Signed-off-by: Ville Vesilehto - ---------- - -Signed-off-by: Ville Vesilehto - -Origin: https://github.com/yhirose/cpp-httplib/commit/7b752106ac42bd5b907793950d9125a0972c8e8e ---- - httplib.h | 9 +++++++++ - test/test.cc | 15 +++++++++++++++ - 2 files changed, 24 insertions(+) - -diff --git a/httplib.h b/httplib.h -index 86a7452..b13f7b6 100644 ---- a/httplib.h -+++ b/httplib.h -@@ -113,6 +113,10 @@ - #define CPPHTTPLIB_LISTEN_BACKLOG 5 - #endif - -+#ifndef CPPHTTPLIB_MAX_LINE_LENGTH -+#define CPPHTTPLIB_MAX_LINE_LENGTH 32768 -+#endif -+ - /* - * Headers - */ -@@ -2559,6 +2563,11 @@ inline bool stream_line_reader::getline() { - glowable_buffer_.clear(); - - for (size_t i = 0;; i++) { -+ if (size() >= CPPHTTPLIB_MAX_LINE_LENGTH) { -+ // Treat exceptionally long lines as an error to -+ // prevent infinite loops/memory exhaustion -+ return false; -+ } - char byte; - auto n = strm_.read(&byte, 1); - -diff --git a/test/test.cc b/test/test.cc -index e702e36..eefa33b 100644 ---- a/test/test.cc -+++ b/test/test.cc -@@ -33,6 +33,9 @@ const int PORT = 1234; - const string LONG_QUERY_VALUE = string(25000, '@'); - const string LONG_QUERY_URL = "/long-query-value?key=" + LONG_QUERY_VALUE; - -+const string TOO_LONG_QUERY_VALUE = string(35000, '@'); -+const string TOO_LONG_QUERY_URL = "/too-long-query-value?key=" + TOO_LONG_QUERY_VALUE; -+ - const std::string JSON_DATA = "{\"hello\":\"world\"}"; - - const string LARGE_DATA = string(1024 * 1024 * 100, '@'); // 100MB -@@ -1991,6 +1994,11 @@ protected: - EXPECT_EQ(LONG_QUERY_URL, req.target); - EXPECT_EQ(LONG_QUERY_VALUE, req.get_param_value("key")); - }) -+ .Get("/too-long-query-value", -+ [&](const Request &req, Response & /*res*/) { -+ EXPECT_EQ(TOO_LONG_QUERY_URL, req.target); -+ EXPECT_EQ(TOO_LONG_QUERY_VALUE, req.get_param_value("key")); -+ }) - .Get("/array-param", - [&](const Request &req, Response & /*res*/) { - EXPECT_EQ(3u, req.get_param_value_count("array")); -@@ -2697,6 +2705,13 @@ TEST_F(ServerTest, LongQueryValue) { - EXPECT_EQ(414, res->status); - } - -+TEST_F(ServerTest, TooLongQueryValue) { -+ auto res = cli_.Get(TOO_LONG_QUERY_URL.c_str()); -+ -+ ASSERT_FALSE(res); -+ EXPECT_EQ(Error::Read, res.error()); -+} -+ - TEST_F(ServerTest, TooLongHeader) { - Request req; - req.method = "GET"; --- -2.49.0 - diff --git a/cpp-httplib-0.14.0.tar.gz b/cpp-httplib-0.14.0.tar.gz deleted file mode 100644 index a232c581e095448acc966c65325077acf171b174..0000000000000000000000000000000000000000 Binary files a/cpp-httplib-0.14.0.tar.gz and /dev/null differ diff --git a/cpp-httplib-0.22.0.tar.gz b/cpp-httplib-0.22.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..33babccbc4791a83e46ddf280f6a64a4a4ae999c Binary files /dev/null and b/cpp-httplib-0.22.0.tar.gz differ diff --git a/cpp-httplib.spec b/cpp-httplib.spec index 8734c0648fb469f583bbab72bcf9b2113bb24da3..406588906eeac1a8bb2bc6ee886cc14d72d6a659 100644 --- a/cpp-httplib.spec +++ b/cpp-httplib.spec @@ -1,49 +1,74 @@ Name: cpp-httplib -Version: 0.14.0 -Release: 4 +Version: 0.22.0 +Release: 1 Summary: A C++ header-only HTTP/HTTPS server and client library License: MIT URL: https://github.com/yhirose/cpp-httplib -Source0: https://github.com/yhirose/cpp-httplib/archive/v%{version}/cpp-httplib-%{version}.tar.gz -Patch0: CVE-2025-0825.patch -Patch1: CVE-2025-46728.patch - -BuildRequires: gcc-c++ meson >= 0.47.0 openssl openssl-devel brotli-devel gtest-devel zlib-devel -Requires: openssl-devel, glibc-devel, zlib-devel +Source0: https://github.com/yhirose/cpp-httplib/archive/v%{version}/%{name}-%{version}.tar.gz +BuildRequires: gcc-c++ +BuildRequires: cmake +BuildRequires: pkgconfig(libcurl) +BuildRequires: pkgconfig(gtest) +BuildRequires: pkgconfig(libbrotlicommon) +BuildRequires: pkgconfig(libbrotlidec) +BuildRequires: pkgconfig(libbrotlienc) +BuildRequires: pkgconfig(openssl) >= 3.0.0 +BuildRequires: pkgconfig(zlib) +BuildRequires: /usr/bin/openssl +BuildRequires: /usr/bin/python3 %description A C++11 single-file header-only cross platform HTTP/HTTPS library. It's extremely easy to setup. Just include httplib.h file in your code! +%package devel +Summary: A C++11 single-file header-only cross platform HTTP/HTTPS library +Requires: %{name}%{?_isa} = %{version}-%{release} +Conflicts: %{name} < 0.18.0 + +%description devel +A C++11 single-file header-only cross platform HTTP/HTTPS library. +It's extremely easy to setup. Just include the httplib.h file in your code! +NOTE: This is a multi-threaded 'blocking' HTTP library. +If you are looking for a 'non-blocking' library, this is not the one that you want. +Development files only. + %prep %autosetup -p1 -n %{name}-%{version} %build -%meson -Dcpp-httplib_compile=true -Dcpp-httplib_test=true \ - --buildtype=release -%meson_build +%cmake \ + -S %{_vpath_srcdir} \ + -B %{_vpath_builddir} \ + -DBUILD_SHARED_LIBS=ON \ + -DHTTPLIB_COMPILE=ON \ + -DHTTPLIB_TEST=ON +cmake --build %{_vpath_builddir} %{?_smp_mflags} --verbose %install -%meson_install - -%pre -%preun -%post -%postun +DESTDIR="%{buildroot}" cmake --install %{_vpath_builddir} +rm -r $RPM_BUILD_ROOT%{_docdir}/httplib +rm -r $RPM_BUILD_ROOT%{_licensedir}/httplib %check -export GTEST_FILTER='_Online$' -%meson_test +cd %{_vpath_builddir} +/usr/bin/ctest --output-on-failure --force-new-ctest-process %{?_smp_mflags} --parallel 1 --exclude-regex '_Online$' +cd - %files -%license LICENSE +%license LICENSE +%{_libdir}/lib%{name}.so.* + +%files devel %doc README.md example %{_includedir}/httplib.h %{_libdir}/lib%{name}.so -%{_libdir}/lib%{name}.so.* -%{_libdir}/pkgconfig/%{name}.pc +%{_libdir}/cmake/httplib %changelog +* Tue Jul 01 2025 yaoxin <1024769339@qq.com> - 0.22.0-1 +- Update to 0.22.0 for fix CVE-2025-52887 + * Wed May 07 2025 yaoxin <1024769339@qq.com> - 0.14.0-4 - Fix CVE-2025-46728