Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions include/boost/url/impl/url_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -3168,8 +3173,6 @@ edit_params(
pos1 - pos0)));
if(impl_.len(id_query) > 0)
dn0 -= 1;
if(dn0 < 0)
dn0 = 0;

//------------------------------------------------
//
Expand Down Expand Up @@ -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] +=
Expand Down
5 changes: 5 additions & 0 deletions test/unit/params_encoded_ref.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
61 changes: 61 additions & 0 deletions test/unit/params_ref.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
Loading