aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLexi Winter <lexi@hemlock.eden.le-fay.org>2025-03-29 04:11:17 +0000
committerLexi Winter <lexi@hemlock.eden.le-fay.org>2025-03-29 04:11:17 +0000
commitc114065f84f085ca0f8944eb0c7f337bbdf4b788 (patch)
treee751b60192204d24bc88e6b774d7496ac436c575
parent25cf4d9fe5b67e143cfaf2e8962c5f9e8e0828c1 (diff)
downloadlibnvxx-c114065f84f085ca0f8944eb0c7f337bbdf4b788.tar.gz
libnvxx-c114065f84f085ca0f8944eb0c7f337bbdf4b788.tar.bz2
ensure string keys/value don't contain NUL
-rw-r--r--libnvxx/const_nv_list.cc13
-rw-r--r--libnvxx/nv_list.cc45
-rw-r--r--libnvxx/nvxx.cc9
-rw-r--r--libnvxx/nvxx_base.h1
-rw-r--r--libnvxx/tests/nvxx_basic.cc386
5 files changed, 438 insertions, 16 deletions
diff --git a/libnvxx/const_nv_list.cc b/libnvxx/const_nv_list.cc
index abd1115..d382691 100644
--- a/libnvxx/const_nv_list.cc
+++ b/libnvxx/const_nv_list.cc
@@ -71,6 +71,8 @@ bool
__const_nv_list::exists_type(std::string_view key, int type) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
+
return (::nvlist_exists_type(__m_nv, std::string(key).c_str(), type));
}
@@ -174,6 +176,7 @@ bool
__const_nv_list::get_bool(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -193,6 +196,7 @@ std::span<bool const>
__const_nv_list::get_bool_array(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -218,6 +222,7 @@ std::uint64_t
__const_nv_list::get_number(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -237,6 +242,7 @@ std::span<std::uint64_t const>
__const_nv_list::get_number_array(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -262,6 +268,7 @@ std::string_view
__const_nv_list::get_string(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -281,6 +288,7 @@ std::vector<std::string_view>
__const_nv_list::get_string_array(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -308,6 +316,7 @@ const_nv_list
__const_nv_list::get_nvlist(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -328,6 +337,7 @@ std::vector<const_nv_list>
__const_nv_list::get_nvlist_array(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -348,6 +358,7 @@ int
__const_nv_list::get_descriptor(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -361,6 +372,7 @@ std::span<int const>
__const_nv_list::get_descriptor_array(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -399,6 +411,7 @@ std::span<std::byte const>
__const_nv_list::get_binary(std::string_view key) const
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
diff --git a/libnvxx/nv_list.cc b/libnvxx/nv_list.cc
index 98f2c93..533edd7 100644
--- a/libnvxx/nv_list.cc
+++ b/libnvxx/nv_list.cc
@@ -164,6 +164,7 @@ void
__nv_list::free_type(std::string_view key, int type)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -181,6 +182,7 @@ void
__nv_list::add_null(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -213,6 +215,7 @@ void
__nv_list::add_bool(std::string_view key, bool value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -235,6 +238,7 @@ bool
__nv_list::take_bool(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -254,6 +258,7 @@ std::vector<bool>
__nv_list::take_bool_array(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto nitems = std::size_t{};
auto ptr = __ptr_guard(::nvlist_take_bool_array(
@@ -266,6 +271,7 @@ __nv_list::add_bool_array(std::string_view key,
std::span<bool const> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -290,6 +296,7 @@ void
__nv_list::move_bool_array(std::string_view key, std::span<bool> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_move_bool_array(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
@@ -300,6 +307,7 @@ void
__nv_list::append_bool_array(std::string_view key, bool value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_append_bool_array(__m_nv, std::string(key).c_str(), value);
}
@@ -318,6 +326,7 @@ void
__nv_list::add_number(std::string_view key, std::uint64_t value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -340,6 +349,7 @@ std::uint64_t
__nv_list::take_number(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -359,6 +369,7 @@ std::vector<std::uint64_t>
__nv_list::take_number_array(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto nitems = std::size_t{};
auto ptr = __ptr_guard(
@@ -373,6 +384,7 @@ __nv_list::add_number_array(std::string_view key,
std::span<std::uint64_t const> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -398,6 +410,7 @@ __nv_list::move_number_array(std::string_view key,
std::span<std::uint64_t> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_move_number_array(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
@@ -408,6 +421,7 @@ void
__nv_list::append_number_array(std::string_view key, std::uint64_t value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_append_number_array(__m_nv, std::string(key).c_str(), value);
}
@@ -426,6 +440,8 @@ void
__nv_list::add_string(std::string_view key, std::string_view value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
+ __check_string_null(value, "nv_list string values may not contain NUL");
auto skey = std::string(key);
@@ -448,6 +464,7 @@ void
__nv_list::move_string(std::string_view key, char *value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_move_string(__m_nv, std::string(key).c_str(), value);
}
@@ -456,6 +473,7 @@ std::string
__nv_list::take_string(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -476,6 +494,10 @@ __nv_list::add_string_array(std::string_view key,
std::span<std::string_view const> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
+
+ for (auto &str: value)
+ __check_string_null(str, "nv_list string values may not contain NUL");
auto skey = std::string(key);
@@ -511,6 +533,7 @@ __nv_list::move_string_array(std::string_view key,
std::span<char *> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_move_string_array(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
@@ -521,6 +544,8 @@ void
__nv_list::append_string_array(std::string_view key, std::string_view value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
+ __check_string_null(value, "nv_list string values may not contain NUL");
::nvlist_append_string_array(__m_nv,
std::string(key).c_str(),
@@ -531,6 +556,7 @@ std::vector<std::string>
__nv_list::take_string_array(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto nitems = std::size_t{};
auto *data = nvlist_take_string_array(__m_nv, std::string(key).c_str(),
@@ -554,6 +580,7 @@ void
__nv_list::add_nvlist(std::string_view key, const_nv_list const &other)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -576,6 +603,7 @@ void
__nv_list::move_nvlist(std::string_view key, nv_list &&value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_move_nvlist(__m_nv, std::string(key).c_str(),
std::exchange(value.__m_nv, nullptr));
@@ -585,6 +613,7 @@ void
__nv_list::move_nvlist(std::string_view key, ::nvlist_t *value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_move_nvlist(__m_nv, std::string(key).c_str(), value);
}
@@ -593,6 +622,7 @@ nv_list
__nv_list::take_nvlist(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -614,6 +644,7 @@ __nv_list::add_nvlist_array(std::string_view key,
std::span<const_nv_list const> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -642,6 +673,7 @@ __nv_list::add_nvlist_array(std::string_view key,
std::span<nv_list const> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -670,6 +702,7 @@ __nv_list::move_nvlist_array(std::string_view key,
std::span<::nvlist_t *> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_move_nvlist_array(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
@@ -681,6 +714,7 @@ __nv_list::append_nvlist_array(std::string_view key,
const_nv_list const &value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_append_nvlist_array(__m_nv, std::string(key).c_str(),
value.__m_nv);
@@ -690,6 +724,7 @@ std::vector<nv_list>
__nv_list::take_nvlist_array(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto nitems = std::size_t{};
auto ptr = __ptr_guard(
@@ -714,6 +749,7 @@ nv_fd
__nv_list::take_descriptor(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto fd = ::nvlist_take_descriptor(__m_nv, std::string(key).c_str());
return (nv_fd(fd));
@@ -723,6 +759,7 @@ void
__nv_list::add_descriptor(std::string_view key, int value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -745,6 +782,7 @@ void
__nv_list::move_descriptor(std::string_view key, nv_fd &&fd)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_move_descriptor(__m_nv,
std::string(key).c_str(),
@@ -761,6 +799,7 @@ void
__nv_list::append_descriptor_array(std::string_view key, int value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_append_descriptor_array(__m_nv,
std::string(key).c_str(),
@@ -772,6 +811,7 @@ __nv_list::add_descriptor_array(std::string_view key,
std::span<int const> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -796,6 +836,7 @@ void
__nv_list::move_descriptor_array(std::string_view key, std::span<int> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_add_descriptor_array(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
@@ -812,6 +853,7 @@ std::vector<nv_fd>
__nv_list::take_descriptor_array(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
/*
* don't use nvlist_take_descriptor_array() here, because we don't
@@ -846,6 +888,7 @@ void
__nv_list::add_binary(std::string_view key, std::span<std::byte const> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
@@ -870,6 +913,7 @@ void
__nv_list::move_binary(std::string_view key, std::span<std::byte> value)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
::nvlist_move_binary(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
@@ -886,6 +930,7 @@ std::vector<std::byte>
__nv_list::take_binary(std::string_view key)
{
__throw_if_error();
+ __check_string_null(key, "nv_list keys may not contain NUL");
auto skey = std::string(key);
diff --git a/libnvxx/nvxx.cc b/libnvxx/nvxx.cc
index 2785aa0..619e67c 100644
--- a/libnvxx/nvxx.cc
+++ b/libnvxx/nvxx.cc
@@ -50,4 +50,13 @@ __nv_list_base::__throw_if_null() const
throw std::logic_error("attempt to access a null nv_list");
}
+void
+__nv_list_base::__check_string_null(std::string_view str,
+ std::string_view error) const
+{
+ if (str.find('\0') == str.npos)
+ return;
+ throw std::runtime_error(std::string(error));
+}
+
} // namespace bsd::__detail
diff --git a/libnvxx/nvxx_base.h b/libnvxx/nvxx_base.h
index bcf5012..f47eb6b 100644
--- a/libnvxx/nvxx_base.h
+++ b/libnvxx/nvxx_base.h
@@ -93,6 +93,7 @@ protected:
void __throw_if_error() const;
void __throw_if_null() const;
+ void __check_string_null(std::string_view, std::string_view) const;
::nvlist_t *__m_nv{};
__nvlist_owning __m_owning;
diff --git a/libnvxx/tests/nvxx_basic.cc b/libnvxx/tests/nvxx_basic.cc
index c432331..d16426f 100644
--- a/libnvxx/tests/nvxx_basic.cc
+++ b/libnvxx/tests/nvxx_basic.cc
@@ -44,6 +44,15 @@ TEST_CASE(nvxx_exists)
ATF_REQUIRE_EQ(false, nvl.exists("nonesuch"));
}
+TEST_CASE(nvxx_exists_nul_key)
+{
+ using namespace std::literals;
+ auto key = "test\0number"sv;
+
+ auto nvl = bsd::nv_list{};
+ ATF_REQUIRE_THROW(std::runtime_error, (void)nvl.exists(key));
+}
+
TEST_CASE(nvxx_exists_type)
{
using namespace std::literals;
@@ -57,6 +66,16 @@ TEST_CASE(nvxx_exists_type)
ATF_REQUIRE_EQ(false, nvl.exists_type("nonesuch", NV_TYPE_NUMBER));
}
+TEST_CASE(nvxx_exists_type_nul_key)
+{
+ using namespace std::literals;
+ auto key = "test\0number"sv;
+
+ auto nvl = bsd::nv_list{};
+ ATF_REQUIRE_THROW(std::runtime_error,
+ (void)nvl.exists_type(key, NV_TYPE_NUMBER));
+}
+
/*
* free(_type)
*/
@@ -74,6 +93,15 @@ TEST_CASE(nvxx_free)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_free_nul_key)
+{
+ using namespace std::literals;
+ auto key = "test\0number"sv;
+
+ auto nvl = bsd::nv_list{};
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free(key));
+}
+
TEST_CASE(nvxx_free_type)
{
using namespace std::literals;
@@ -87,6 +115,16 @@ TEST_CASE(nvxx_free_type)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_free_type_nul_key)
+{
+ using namespace std::literals;
+ auto key = "test\0number"sv;
+
+ auto nvl = bsd::nv_list{};
+ ATF_REQUIRE_THROW(std::runtime_error,
+ nvl.free_type(key, NV_TYPE_NUMBER));
+}
+
TEST_CASE(nvxx_free_type_nonexistent)
{
using namespace std::literals;
@@ -138,6 +176,15 @@ TEST_CASE(nvxx_add_null_error)
ATF_REQUIRE_THROW(bsd::nv_error_state, nvl.add_null(key));
}
+TEST_CASE(nvxx_add_null_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0null"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_null(key));
+}
+
TEST_CASE(nvxx_add_duplicate_null)
{
using namespace std::literals;
@@ -165,6 +212,15 @@ TEST_CASE(nvxx_free_null)
ATF_REQUIRE_EQ(false, nvl.exists_null(key));
}
+TEST_CASE(nvxx_free_null_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0null"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_null(key));
+}
+
TEST_CASE(nvxx_free_null_nonexistent)
{
using namespace std::literals;
@@ -192,6 +248,16 @@ TEST_CASE(nvxx_add_bool)
ATF_REQUIRE_EQ(value, nvl.get_bool(key));
}
+TEST_CASE(nvxx_add_bool_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0bool"sv;
+ auto constexpr value = true;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_bool(key, value));
+}
+
TEST_CASE(nvxx_add_bool_error)
{
using namespace std::literals;
@@ -242,6 +308,15 @@ TEST_CASE(nvxx_take_bool)
(void)nvl.take_bool(key));
}
+TEST_CASE(nvxx_take_bool_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0bool"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, (void)nvl.take_bool(key));
+}
+
TEST_CASE(nvxx_free_bool)
{
using namespace std::literals;
@@ -254,6 +329,15 @@ TEST_CASE(nvxx_free_bool)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_free_bool_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0bool"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_bool(key));
+}
+
TEST_CASE(nvxx_free_bool_nonexistent)
{
using namespace std::literals;
@@ -288,6 +372,17 @@ TEST_CASE(nvxx_add_bool_array)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_add_bool_array_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0bool"sv;
+
+ auto data = std::array<bool, 2>{true, false};
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_bool_array(key, data));
+}
+
TEST_CASE(nvxx_add_bool_array_error)
{
using namespace std::literals;
@@ -374,6 +469,15 @@ TEST_CASE(nvxx_free_bool_array)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_free_bool_array_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0bool"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_bool_array(key));
+}
+
TEST_CASE(nvxx_free_bool_array_nonexistent)
{
using namespace std::literals;
@@ -406,6 +510,16 @@ TEST_CASE(nvxx_add_number)
ATF_REQUIRE_EQ(value, nvl.get_number(key));
}
+TEST_CASE(nvxx_add_number_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0number"sv;
+ auto constexpr value = 42_u64;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_number(key, value));
+}
+
TEST_CASE(nvxx_add_number_error)
{
using namespace std::literals;
@@ -457,6 +571,15 @@ TEST_CASE(nvxx_take_number)
(void)nvl.take_number(key));
}
+TEST_CASE(nvxx_take_number_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0number"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, (void)nvl.take_number(key));
+}
+
TEST_CASE(nvxx_free_number)
{
using namespace std::literals;
@@ -470,6 +593,15 @@ TEST_CASE(nvxx_free_number)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_free_number_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0number"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_number(key));
+}
+
TEST_CASE(nvxx_free_number_nonexistent)
{
using namespace std::literals;
@@ -502,6 +634,18 @@ TEST_CASE(nvxx_add_number_array)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_add_number_array_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0number"sv;
+ auto constexpr size = 16u;
+
+ auto data = std::array<std::uint64_t, size>{};
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_number_array(key, data));
+}
+
TEST_CASE(nvxx_add_number_array_error)
{
using namespace std::literals;
@@ -550,6 +694,15 @@ TEST_CASE(nvxx_free_number_array)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_free_number_array_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0number"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_number_array(key));
+}
+
TEST_CASE(nvxx_free_number_array_nonexistent)
{
using namespace std::literals;
@@ -615,6 +768,26 @@ TEST_CASE(nvxx_add_string)
ATF_REQUIRE_EQ(value, nvl.get_string(key));
}
+TEST_CASE(nvxx_add_string_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0string"sv;
+ auto constexpr value = "testing value"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_string(key, value));
+}
+
+TEST_CASE(nvxx_add_string_nul_value)
+{
+ using namespace std::literals;
+ auto constexpr key = "test_string"sv;
+ auto constexpr value = "testing\0value"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_string(key, value));
+}
+
TEST_CASE(nvxx_add_duplicate_string)
{
using namespace std::literals;
@@ -653,6 +826,15 @@ TEST_CASE(nvxx_take_string)
(void)nvl.take_string(key));
}
+TEST_CASE(nvxx_take_string_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0string"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, (void)nvl.take_string(key));
+}
+
TEST_CASE(nvxx_free_string)
{
using namespace std::literals;
@@ -665,6 +847,15 @@ TEST_CASE(nvxx_free_string)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_free_string_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0string"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_string(key));
+}
+
TEST_CASE(nvxx_free_string_nonexistent)
{
using namespace std::literals;
@@ -695,6 +886,28 @@ TEST_CASE(nvxx_add_string_array)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_add_string_array_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0string"sv;
+
+ auto data = std::array<std::string_view, 2>{"one"sv, "two"sv};
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_string_array(key, data));
+}
+
+TEST_CASE(nvxx_add_string_array_nul_value)
+{
+ using namespace std::literals;
+ auto constexpr key = "test_string"sv;
+
+ auto data = std::array<std::string_view, 2>{"one"sv, "two\0ohno"sv};
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_string_array(key, data));
+}
+
TEST_CASE(nvxx_add_string_error)
{
using namespace std::literals;
@@ -731,6 +944,15 @@ TEST_CASE(nvxx_free_string_array)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_free_string_array_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0string"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_string_array(key));
+}
+
TEST_CASE(nvxx_free_string_array_nonexistent)
{
using namespace std::literals;
@@ -811,15 +1033,28 @@ TEST_CASE(nvxx_add_string_contig_range)
TEST_CASE(nvxx_add_nvlist)
{
- auto nvl = bsd::nv_list(), nvl2 = bsd::nv_list();
+ using namespace std::literals;
+ auto constexpr key = "test_nvlist"sv;
+ auto value = bsd::nv_list{};
+ value.add_number("test_number", 42);
- nvl2.add_number("test_number", 42);
- nvl.add_nvlist("test_nvlist", nvl2);
+ auto nvl = bsd::nv_list{};
+ nvl.add_nvlist(key, value);
- ATF_REQUIRE_EQ(true, nvl.exists("test_nvlist"));
- ATF_REQUIRE_EQ(true, nvl.exists_nvlist("test_nvlist"));
- ATF_REQUIRE_EQ(42, nvl.get_nvlist("test_nvlist")
- .get_number("test_number"));
+ ATF_REQUIRE_EQ(true, nvl.exists(key));
+ ATF_REQUIRE_EQ(true, nvl.exists_nvlist(key));
+ ATF_REQUIRE_EQ(42, nvl.get_nvlist(key).get_number("test_number"));
+}
+
+TEST_CASE(nvxx_add_nvlist_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0nvlist"sv;
+ auto value = bsd::nv_list{};
+ value.add_number("test_number", 42);
+
+ auto nvl = bsd::nv_list{};
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_nvlist(key, value));
}
TEST_CASE(nvxx_add_nvlist_error)
@@ -872,6 +1107,15 @@ TEST_CASE(nvxx_take_nvlist)
(void)nvl.take_nvlist(key));
}
+TEST_CASE(nvxx_take_nvlist_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0nvlist"sv;
+ auto nvl = bsd::nv_list{};
+
+ ATF_REQUIRE_THROW(std::runtime_error, (void)nvl.take_nvlist(key));
+}
+
TEST_CASE(nvxx_free_nvlist)
{
auto nvl = bsd::nv_list(), nvl2 = bsd::nv_list();
@@ -883,6 +1127,15 @@ TEST_CASE(nvxx_free_nvlist)
ATF_REQUIRE_EQ(false, nvl.exists("test_nvlist"));
}
+TEST_CASE(nvxx_free_nvlist_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0nvlist"sv;
+ auto nvl = bsd::nv_list{};
+
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_nvlist(key));
+}
+
TEST_CASE(nvxx_free_nvlist_nonexistent)
{
using namespace std::literals;
@@ -926,6 +1179,16 @@ TEST_CASE(nvxx_add_nvlist_array)
ATF_REQUIRE_EQ(n2, 2);
}
+TEST_CASE(nvxx_add_nvlist_array_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0nvlist"sv;
+ auto value = std::array<bsd::nv_list, 2>();
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_nvlist_array(key, value));
+}
+
TEST_CASE(nvxx_add_nvlist_array_error)
{
using namespace std::literals;
@@ -974,6 +1237,15 @@ TEST_CASE(nvxx_free_nvlist_array)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_free_nvlist_array_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test nvlist"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_nvlist_array(key));
+}
+
TEST_CASE(nvxx_free_nvlist_array_nonexistent)
{
using namespace std::literals;
@@ -993,14 +1265,11 @@ TEST_CASE(nvxx_add_descriptor)
auto ret = ::pipe(&fds[0]);
ATF_REQUIRE_EQ(0, ret);
- auto guard = std::unique_ptr<int[],
- decltype([](auto fds) {
- ::close(fds[0]);
- ::close(fds[1]);
- })>(&fds[0]);
+ bsd::nv_fd fd0(fds[0]);
+ bsd::nv_fd fd1(fds[1]);
auto nvl = bsd::nv_list();
- nvl.add_descriptor("test_descriptor", fds[0]);
+ nvl.add_descriptor("test_descriptor", fd0.get());
ATF_REQUIRE_EQ(true, nvl.exists("test_descriptor"));
ATF_REQUIRE_EQ(true, nvl.exists_descriptor("test_descriptor"));
@@ -1009,7 +1278,7 @@ TEST_CASE(nvxx_add_descriptor)
ATF_REQUIRE_EQ(4, ret);
auto buf = std::array<char, 4>{};
- ret = ::read(fds[1], &buf[0], 4);
+ ret = ::read(fd1.get(), &buf[0], 4);
ATF_REQUIRE_EQ(4, ret);
ATF_REQUIRE_EQ('1', buf[0]);
@@ -1018,6 +1287,22 @@ TEST_CASE(nvxx_add_descriptor)
ATF_REQUIRE_EQ('4', buf[3]);
}
+TEST_CASE(nvxx_add_descriptor_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0descriptor"sv;
+
+ auto fds = std::array<int, 2>{};
+ auto ret = ::pipe(&fds[0]);
+ ATF_REQUIRE_EQ(0, ret);
+
+ bsd::nv_fd fd0(fds[0]);
+ bsd::nv_fd fd1(fds[1]);
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_descriptor(key, fd0.get()));
+}
+
TEST_CASE(nvxx_add_descriptor_error)
{
using namespace std::literals;
@@ -1083,14 +1368,22 @@ TEST_CASE(nvxx_free_descriptor_array)
ATF_REQUIRE_EQ(false, nvl.exists(key));
}
+TEST_CASE(nvxx_free_descriptor_array_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0descriptor"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_descriptor_array(key));
+}
+
TEST_CASE(nvxx_free_descriptor_array_nonexistent)
{
using namespace std::literals;
auto constexpr key = "test descriptor"sv;
auto nvl = bsd::nv_list();
- ATF_REQUIRE_THROW(bsd::nv_key_not_found,
- nvl.free_descriptor_array(key));
+ ATF_REQUIRE_THROW(bsd::nv_key_not_found, nvl.free_descriptor_array(key));
}
/*
@@ -1113,6 +1406,16 @@ TEST_CASE(nvxx_add_binary)
ATF_REQUIRE_EQ(true, std::ranges::equal(data, data2));
}
+TEST_CASE(nvxx_add_binary_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0binary"sv;
+ auto constexpr value = std::array<std::byte, 16>{};
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.add_binary(key, value));
+}
+
TEST_CASE(nvxx_add_binary_error)
{
using namespace std::literals;
@@ -1147,6 +1450,15 @@ TEST_CASE(nvxx_free_binary_nonexistent)
ATF_REQUIRE_THROW(bsd::nv_key_not_found, nvl.free_binary(key));
}
+TEST_CASE(nvxx_free_binary_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0binary"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, nvl.free_binary(key));
+}
+
TEST_CASE(nvxx_add_duplicate_binary)
{
using namespace std::literals;
@@ -1192,6 +1504,15 @@ TEST_CASE(nvxx_take_binary)
(void)nvl.take_binary(key));
}
+TEST_CASE(nvxx_take_binary_nul_key)
+{
+ using namespace std::literals;
+ auto constexpr key = "test\0binary"sv;
+
+ auto nvl = bsd::nv_list();
+ ATF_REQUIRE_THROW(std::runtime_error, (void)nvl.take_binary(key));
+}
+
TEST_CASE(nvxx_add_binary_range)
{
auto nvl = bsd::nv_list();
@@ -1214,98 +1535,131 @@ ATF_INIT_TEST_CASES(tcs)
ATF_ADD_TEST_CASE(tcs, nvxx_ignore_case);
ATF_ADD_TEST_CASE(tcs, nvxx_exists);
+ ATF_ADD_TEST_CASE(tcs, nvxx_exists_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_exists_type);
+ ATF_ADD_TEST_CASE(tcs, nvxx_exists_type_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_type);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_type_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_type_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_null);
ATF_ADD_TEST_CASE(tcs, nvxx_add_null_error);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_null);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_null_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_null);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_null_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_null_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_bool);
ATF_ADD_TEST_CASE(tcs, nvxx_add_bool_error);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_bool_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_bool);
ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_bool);
ATF_ADD_TEST_CASE(tcs, nvxx_take_bool);
+ ATF_ADD_TEST_CASE(tcs, nvxx_take_bool_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_bool);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_bool_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_bool_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_bool_array);
ATF_ADD_TEST_CASE(tcs, nvxx_add_bool_array_error);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_bool_array_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_bool_array);
ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_bool_array);
ATF_ADD_TEST_CASE(tcs, nvxx_add_bool_range);
ATF_ADD_TEST_CASE(tcs, nvxx_add_bool_contig_range);
ATF_ADD_TEST_CASE(tcs, nvxx_free_bool_array);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_bool_array_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_bool_array_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_number);
ATF_ADD_TEST_CASE(tcs, nvxx_add_number_error);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_number_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_number);
ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_number);
ATF_ADD_TEST_CASE(tcs, nvxx_take_number);
+ ATF_ADD_TEST_CASE(tcs, nvxx_take_number_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_number);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_number_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_number_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_number_array);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_number_array_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_add_number_array_error);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_number_array);
ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_number_array);
ATF_ADD_TEST_CASE(tcs, nvxx_add_number_range);
ATF_ADD_TEST_CASE(tcs, nvxx_add_number_contig_range);
ATF_ADD_TEST_CASE(tcs, nvxx_free_number_array);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_number_array_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_number_array_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_string);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_string_nul_key);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_string_nul_value);
ATF_ADD_TEST_CASE(tcs, nvxx_add_string_error);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_string);
ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_string);
ATF_ADD_TEST_CASE(tcs, nvxx_take_string);
+ ATF_ADD_TEST_CASE(tcs, nvxx_take_string_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_string);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_string_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_string_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_string_array);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_string_array_nul_key);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_string_array_nul_value);
ATF_ADD_TEST_CASE(tcs, nvxx_add_string_array_error);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_string_array);
ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_string_array);
ATF_ADD_TEST_CASE(tcs, nvxx_add_string_range);
ATF_ADD_TEST_CASE(tcs, nvxx_add_string_contig_range);
ATF_ADD_TEST_CASE(tcs, nvxx_free_string_array);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_string_array_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_string_array_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_nvlist);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_nvlist_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_add_nvlist_error);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_nvlist);
ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_nvlist);
ATF_ADD_TEST_CASE(tcs, nvxx_take_nvlist);
+ ATF_ADD_TEST_CASE(tcs, nvxx_take_nvlist_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_nvlist);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_nvlist_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_nvlist_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_nvlist_array);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_nvlist_array_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_add_nvlist_array_error);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_nvlist_array);
ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_nvlist_array);
ATF_ADD_TEST_CASE(tcs, nvxx_free_nvlist_array);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_nvlist_array_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_nvlist_array_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_descriptor);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_descriptor_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_add_descriptor_error);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_descriptor);
ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_descriptor);
ATF_ADD_TEST_CASE(tcs, nvxx_free_descriptor_array);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_descriptor_array_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_descriptor_array_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_binary);
+ ATF_ADD_TEST_CASE(tcs, nvxx_add_binary_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_add_binary_error);
ATF_ADD_TEST_CASE(tcs, nvxx_add_duplicate_binary);
ATF_ADD_TEST_CASE(tcs, nvxx_get_nonexistent_binary);
ATF_ADD_TEST_CASE(tcs, nvxx_take_binary);
+ ATF_ADD_TEST_CASE(tcs, nvxx_take_binary_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_binary);
+ ATF_ADD_TEST_CASE(tcs, nvxx_free_binary_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_free_binary_nonexistent);
ATF_ADD_TEST_CASE(tcs, nvxx_add_binary_range);