Download raw body.
devel/boost: backport a regression fix to 1.91.0
please use "make update-patches" to generate the patch files; from what you
have now, "make clean; make patch; rm
patches/patch-libs_url_base_edit_params; make update-patches".
--
Sent from a phone, apologies for poor formatting.
On 13 September 2026 20:34:36 Sergii Rudchenko <sergii@rudchenko.nl> wrote:
> The current version of the Boost C++ library in OpenBSD ports (1.91.0)
> has an
> annoying regression in Boost.URL: https://github.com/boostorg/url/issues/989
>
> The issue is fixed upstream and released in in 1.92.0:
> https://github.com/boostorg/url/commit/41b467a389a68321608138a432b15024b6c11918
>
> After talking to Marc Espie at EuroBSDCon I understood that that
> updating boost
> to 1.92.0 is at this point in the release cycle is risky and will most
> likely
> be postponed until 8.0 is out. He suggested to try backporting the fix
> for the
> time being.
>
> Below is the patch taken as-is from the upstream and it luckily applies
> cleanly
> on top of 1.91.0. I have verified the fix on the resulting build from
> the port.
>
> Can we please apply this stopgap measure until we move to 1.92.0?
>
> Index: devel/boost/Makefile
> ===================================================================
> RCS file: /cvs/ports/devel/boost/Makefile,v
> diff -u -p -u -r1.163 Makefile
> --- devel/boost/Makefile 18 May 2026 05:48:17 -0000 1.163
> +++ devel/boost/Makefile 13 Sep 2026 18:07:29 -0000
> @@ -6,6 +6,7 @@ COMMENT-main= free peer-reviewed portabl
> COMMENT-md= machine-dependent libraries for boost
>
> VERSION= 1.91.0
> +REVISION= 0
> DISTNAME= boost_${VERSION:S/./_/g}
> PKGNAME= boost-${VERSION}
> EPOCH= 0
> Index: devel/boost/patches/patch-libs_url_base_edit_params
> ===================================================================
> RCS file: devel/boost/patches/patch-libs_url_base_edit_params
> diff -N devel/boost/patches/patch-libs_url_base_edit_params
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ devel/boost/patches/patch-libs_url_base_edit_params 13 Sep 2026
> 18:07:29 -0000
> @@ -0,0 +1,140 @@
> +Backport the fix for the URL corruption bug on url.params().append() in
> Boost 1.91.0
> +
> +Fixed upstream in 1.92.0: 41b467a389a68321608138a432b15024b6c11918
> +Index: boost/include/boost/url/impl/url_base.hpp
> +--- boost/url/impl/url_base.hpp.orig
> ++++ boost/url/impl/url_base.hpp
> +@@ -3159,7 +3159,12 @@ edit_params(
> + BOOST_ASSERT(pos1 <= impl_.offset(id_frag));
> +
> + // calc decoded size of old range,
> +- // minus one if '?' or '&' prefixed
> ++ // minus one for the leading '?' which is
> ++ // not counted in decoded_[id_query].
> ++ // dn0 may be -1 here when the old range is
> ++ // empty and the query was non-empty; the
> ++ // matching subtraction on dn below cancels
> ++ // that out when the delta is taken.
> + auto dn0 =
> + static_cast<std::ptrdiff_t>(
> + detail::decode_bytes_unsafe(
> +@@ -3168,8 +3173,6 @@ edit_params(
> + pos1 - pos0)));
> + if(impl_.len(id_query) > 0)
> + dn0 -= 1;
> +- if(dn0 < 0)
> +- dn0 = 0;
> +
> + //------------------------------------------------
> + //
> +@@ -3267,16 +3270,13 @@ edit_params(
> + }
> + }
> +
> +- // calc decoded size of new range,
> +- // minus one if '?' or '&' prefixed
> ++ // calc decoded size of new range; see dn0.
> + auto dn =
> + static_cast<std::ptrdiff_t>(
> + detail::decode_bytes_unsafe(
> + core::string_view(dest0, dest - dest0)));
> + if(impl_.len(id_query) > 0)
> + dn -= 1;
> +- if(dn < 0)
> +- dn = 0;
> +
> + if(dn >= dn0)
> + impl_.decoded_[id_query] +=
> +Index: libs/url/test/unit/params_encoded_ref.cpp
> +--- libs/url/test/unit/params_encoded_ref.cpp.orig
> ++++ libs/url/test/unit/params_encoded_ref.cpp
> +@@ -121,6 +121,11 @@ struct params_encoded_ref_test
> + params_encoded_ref ps(u.encoded_params());
> + f(ps);
> + BOOST_TEST_EQ(u.encoded_query(), s1);
> ++ BOOST_TEST_EQ(
> ++ u.encoded_query().decoded_size(),
> ++ pct_string_view(s1).decoded_size());
> ++ BOOST_TEST_NO_THROW(u.encoded_target());
> ++ BOOST_TEST_NO_THROW(u.encoded_resource());
> + if(! BOOST_TEST_EQ(
> + ps.size(), init.size()))
> + return;
> +Index: libs/url/test/unit/params_ref.cpp
> +--- libs/url/test/unit/params_ref.cpp.orig
> ++++ libs/url/test/unit/params_ref.cpp
> +@@ -142,6 +142,11 @@ struct params_ref_test
> + params_ref ps(u.params());
> + f(ps);
> + BOOST_TEST_EQ(u.encoded_query(), s1);
> ++ BOOST_TEST_EQ(
> ++ u.encoded_query().decoded_size(),
> ++ pct_string_view(s1).decoded_size());
> ++ BOOST_TEST_NO_THROW(u.encoded_target());
> ++ BOOST_TEST_NO_THROW(u.encoded_resource());
> + if(! BOOST_TEST_EQ(
> + ps.size(), init.size()))
> + return;
> +@@ -814,6 +819,62 @@ struct params_ref_test
> + check(f, "?k0&k1=&k2=key", "k0&k1=" BIGSTR "&k2=key",
> + { {"k0",no_value}, {"k1",BIGSTR}, {"k2","key"} });
> + }
> ++
> ++ // issue #989: encoded_target() asserts after
> ++ // successive params().set() on a fresh url.
> ++ // Regression for broken decoded_[id_query]
> ++ // bookkeeping in url_base::edit_params.
> ++ {
> ++ url u;
> ++ u.params().set("a", "b");
> ++ BOOST_TEST_EQ(u.encoded_query(), "a=b");
> ++ BOOST_TEST_EQ(u.encoded_query().decoded_size(), 3u);
> ++ BOOST_TEST_EQ(u.encoded_target(), "?a=b");
> ++
> ++ u.params().set("c", "d");
> ++ BOOST_TEST_EQ(u.encoded_query(), "a=b&c=d");
> ++ BOOST_TEST_EQ(u.encoded_query().decoded_size(), 7u);
> ++ BOOST_TEST_EQ(u.encoded_target(), "?a=b&c=d");
> ++ }
> ++
> ++ // Related: erase first param must leave a
> ++ // consistent decoded_[id_query].
> ++ {
> ++ url u("?a=b&c=d");
> ++ BOOST_TEST_EQ(u.encoded_query().decoded_size(), 7u);
> ++ u.params().erase(u.params().begin());
> ++ BOOST_TEST_EQ(u.encoded_query(), "c=d");
> ++ BOOST_TEST_EQ(u.encoded_query().decoded_size(), 3u);
> ++ BOOST_TEST_EQ(u.encoded_target(), "?c=d");
> ++ }
> ++
> ++ // Related: erase last param must leave a
> ++ // consistent decoded_[id_query].
> ++ {
> ++ url u("?a=b&c=d");
> ++ u.params().erase(std::next(u.params().begin()));
> ++ BOOST_TEST_EQ(u.encoded_query(), "a=b");
> ++ BOOST_TEST_EQ(u.encoded_query().decoded_size(), 3u);
> ++ BOOST_TEST_EQ(u.encoded_target(), "?a=b");
> ++ }
> ++
> ++ // Related: insert at front of non-empty query.
> ++ {
> ++ url u("?x=y");
> ++ u.params().insert(u.params().begin(), {"a", "b"});
> ++ BOOST_TEST_EQ(u.encoded_query(), "a=b&x=y");
> ++ BOOST_TEST_EQ(u.encoded_query().decoded_size(), 7u);
> ++ BOOST_TEST_EQ(u.encoded_target(), "?a=b&x=y");
> ++ }
> ++
> ++ // Related: append to non-empty query.
> ++ {
> ++ url u("?x=y");
> ++ u.params().append({"a", "b"});
> ++ BOOST_TEST_EQ(u.encoded_query(), "x=y&a=b");
> ++ BOOST_TEST_EQ(u.encoded_query().decoded_size(), 7u);
> ++ BOOST_TEST_EQ(u.encoded_target(), "?x=y&a=b");
> ++ }
> + }
> +
> + static
devel/boost: backport a regression fix to 1.91.0