diff options
| -rw-r--r-- | libnvxx/const_nv_list.cc | 13 | ||||
| -rw-r--r-- | libnvxx/nv_list.cc | 45 | ||||
| -rw-r--r-- | libnvxx/nvxx.cc | 9 | ||||
| -rw-r--r-- | libnvxx/nvxx_base.h | 1 | ||||
| -rw-r--r-- | libnvxx/tests/nvxx_basic.cc | 386 |
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); |
