mirror of
https://github.com/boostorg/url.git
synced 2026-01-19 04:42:15 +00:00
This commit refactors all functions so they have consistent behavior for the space-as-plus encoding option. - any_params_iter objects store and apply the appropriate option when measuring and copying - when the option is enabled, encoding functions encode space-as-plus and plus as %2B regardless of the charset - normalization and comparison algorithms take into consideration special query chars whose meaning changes depending on encoding - all params_view objects created with default options enable space-as-plus encoding fix #903
214 lines
5.1 KiB
C++
214 lines
5.1 KiB
C++
//
|
|
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
|
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
// Official repository: https://github.com/boostorg/url
|
|
//
|
|
|
|
// Test that header file is self-contained.
|
|
#include <boost/url/encode.hpp>
|
|
|
|
#include <boost/url/rfc/pchars.hpp>
|
|
#include <boost/core/ignore_unused.hpp>
|
|
|
|
#include "test_suite.hpp"
|
|
|
|
#include <memory>
|
|
|
|
#ifdef assert
|
|
#undef assert
|
|
#endif
|
|
#define assert BOOST_TEST
|
|
|
|
namespace boost {
|
|
namespace urls {
|
|
|
|
template <bool allow_plus, bool allow_space>
|
|
struct space_as_plus_test_chars
|
|
{
|
|
constexpr
|
|
bool
|
|
operator()(char c) const noexcept
|
|
{
|
|
return
|
|
(allow_plus && c == '+') ||
|
|
(allow_space && c == ' ') ||
|
|
unreserved_chars(c);
|
|
}
|
|
};
|
|
|
|
class encode_test
|
|
{
|
|
public:
|
|
struct test_chars
|
|
{
|
|
constexpr
|
|
bool
|
|
operator()(char c) const noexcept
|
|
{
|
|
return c == 'A' || c == '+';
|
|
}
|
|
};
|
|
|
|
void
|
|
check(
|
|
core::string_view s,
|
|
core::string_view m0,
|
|
bool space_as_plus = false)
|
|
{
|
|
// encoded_size
|
|
{
|
|
encoding_opts opt;
|
|
opt.space_as_plus =
|
|
space_as_plus;
|
|
BOOST_TEST(encoded_size(
|
|
s, test_chars{}, opt) ==
|
|
m0.size());
|
|
}
|
|
// encode
|
|
{
|
|
encoding_opts opt;
|
|
opt.space_as_plus =
|
|
space_as_plus;
|
|
std::string t;
|
|
t.resize(
|
|
encoded_size(s, test_chars{}, opt));
|
|
encode(
|
|
&t[0], t.size(), s, test_chars{}, opt);
|
|
BOOST_TEST(t == m0);
|
|
}
|
|
encoding_opts opt;
|
|
opt.space_as_plus =
|
|
space_as_plus;
|
|
auto const m = encode(
|
|
s, test_chars{}, opt, {});
|
|
if(! BOOST_TEST(m == m0))
|
|
return;
|
|
char buf[64];
|
|
BOOST_ASSERT(
|
|
m.size() < sizeof(buf));
|
|
for(std::size_t i = 0;
|
|
i <= sizeof(buf); ++i)
|
|
{
|
|
char* dest = buf;
|
|
std::size_t n = encode(
|
|
dest, i, s, test_chars{}, opt);
|
|
core::string_view r(buf, n);
|
|
if(n == m.size())
|
|
{
|
|
BOOST_TEST_EQ(i, m.size());
|
|
BOOST_TEST_EQ(r, m);
|
|
break;
|
|
}
|
|
BOOST_TEST(
|
|
core::string_view(buf, n) ==
|
|
m.substr(0, n));
|
|
}
|
|
};
|
|
|
|
void
|
|
testEncode()
|
|
{
|
|
check("", "");
|
|
check(" ", "%20");
|
|
check("A", "A");
|
|
check("B", "%42");
|
|
check("AB", "A%42");
|
|
check("A B", "A%20%42");
|
|
|
|
check("", "", true);
|
|
check(" ", "+", true);
|
|
check("A", "A", true);
|
|
check("B", "%42", true);
|
|
check("AB", "A%42", true);
|
|
check("A B", "A+%42", true);
|
|
}
|
|
|
|
void
|
|
testEncodeExtras()
|
|
{
|
|
// space_as_plus
|
|
{
|
|
BOOST_TEST(encode(
|
|
" ", test_chars{}, {}, {}) == "%20");
|
|
encoding_opts opt;
|
|
BOOST_TEST_EQ(opt.space_as_plus, false);
|
|
BOOST_TEST(encode(
|
|
" ", test_chars{}, opt, {}) == "%20");
|
|
BOOST_TEST(encode(
|
|
"A", test_chars{}, opt, {}) == "A");
|
|
BOOST_TEST(encode(
|
|
" A+", test_chars{}, opt, {}) == "%20A+");
|
|
opt.space_as_plus = true;
|
|
BOOST_TEST(encode(
|
|
" ", test_chars{}, opt, {}) == "+");
|
|
BOOST_TEST(encode(
|
|
"A", test_chars{}, opt, {}) == "A");
|
|
BOOST_TEST_EQ(encode(
|
|
" A+", test_chars{}, opt, {}), "+A%2B");
|
|
}
|
|
|
|
// optimization of space-as-plus when the charset
|
|
// already includes or excludes plus or space
|
|
{
|
|
encoding_opts opt;
|
|
opt.space_as_plus = true;
|
|
BOOST_TEST_EQ(
|
|
encode(
|
|
"a +",
|
|
space_as_plus_test_chars<true, true>{},
|
|
opt), "a+%2B");
|
|
BOOST_TEST_EQ(
|
|
encode(
|
|
"a +",
|
|
space_as_plus_test_chars<true, false>{},
|
|
opt), "a+%2B");
|
|
BOOST_TEST_EQ(
|
|
encode(
|
|
"a +",
|
|
space_as_plus_test_chars<false, true>{},
|
|
opt), "a+%2B");
|
|
BOOST_TEST_EQ(
|
|
encode(
|
|
"a +",
|
|
space_as_plus_test_chars<false, false>{},
|
|
opt), "a+%2B");
|
|
}
|
|
}
|
|
|
|
void
|
|
testJavadocs()
|
|
{
|
|
// encoded_size()
|
|
{
|
|
assert( encoded_size( "My Stuff", pchars ) == 10 );
|
|
}
|
|
|
|
// encode()
|
|
{
|
|
char buf[100];
|
|
assert( encode( buf, sizeof(buf), "Program Files", pchars ) == 15 );
|
|
|
|
ignore_unused(buf);
|
|
}
|
|
}
|
|
|
|
void
|
|
run()
|
|
{
|
|
testEncode();
|
|
testEncodeExtras();
|
|
testJavadocs();
|
|
}
|
|
};
|
|
|
|
TEST_SUITE(
|
|
encode_test,
|
|
"boost.url.encode");
|
|
|
|
} // urls
|
|
} // boost
|