From 49fb44c299ff16c114858f9ec4c254806dadef04 Mon Sep 17 00:00:00 2001 From: Alexis Jeandet Date: Wed, 18 Feb 2026 10:16:09 +0100 Subject: [PATCH] Do not allow anymore to create Variables or Attributes with an empty name. While technically legal (no mention in the official format doc), others CDF implementations consider the file corrupted if a name is empty. Fixes #48 --- include/cdfpp/attribute.hpp | 8 ++++++++ include/cdfpp/cdf-file.hpp | 2 ++ include/cdfpp/variable.hpp | 8 ++++++++ tests/python_variable_set_values/test.py | 14 ++++++++++++++ 4 files changed, 32 insertions(+) diff --git a/include/cdfpp/attribute.hpp b/include/cdfpp/attribute.hpp index 5d0dcc2..97be0d6 100644 --- a/include/cdfpp/attribute.hpp +++ b/include/cdfpp/attribute.hpp @@ -56,6 +56,10 @@ struct Attribute Attribute& operator=(const Attribute&) = default; Attribute(const std::string& name, attr_data_t&& data) : name { name } { + if (name.empty()) + { + throw std::invalid_argument { "Attribute name cannot be empty" }; + } this->data = std::move(data); } @@ -177,6 +181,10 @@ struct VariableAttribute VariableAttribute& operator=(const VariableAttribute&) = default; VariableAttribute(const std::string& name, attr_data_t&& data) : name { name } { + if (name.empty()) + { + throw std::invalid_argument { "Attribute name cannot be empty" }; + } this->data = std::move(data); } diff --git a/include/cdfpp/cdf-file.hpp b/include/cdfpp/cdf-file.hpp index 4de9547..56bdb44 100644 --- a/include/cdfpp/cdf-file.hpp +++ b/include/cdfpp/cdf-file.hpp @@ -36,6 +36,8 @@ template inline stream_t& operator<<(stream_t& os, const cdf_map& variables) { + std::for_each(std::cbegin(variables), std::cend(variables), + [&os](const auto& item) { item.second.__repr__(os, indent_t {}, false); }); return os; } diff --git a/include/cdfpp/variable.hpp b/include/cdfpp/variable.hpp index 74c9ac1..a497b0a 100644 --- a/include/cdfpp/variable.hpp +++ b/include/cdfpp/variable.hpp @@ -102,6 +102,10 @@ struct Variable , p_is_nrv { is_nrv } , p_compression { compression_type } { + if (name.empty()) + { + throw std::invalid_argument { "Variable name cannot be empty" }; + } if (this->majority() == cdf_majority::column) { majority::swap(_data(), p_shape); @@ -120,6 +124,10 @@ struct Variable , p_is_nrv { is_nrv } , p_compression { compression_type } { + if (name.empty()) + { + throw std::invalid_argument { "Variable name cannot be empty" }; + } } inline bool operator==(const Variable& other) const diff --git a/tests/python_variable_set_values/test.py b/tests/python_variable_set_values/test.py index 7727d23..314bf11 100755 --- a/tests/python_variable_set_values/test.py +++ b/tests/python_variable_set_values/test.py @@ -263,6 +263,20 @@ def test_filter_cdf_with_regex(self): self.assertIn("global_attr2", self.cdf.attributes) self.assertIn("global_attr3", self.cdf.attributes) +class PycdfEmptyNamesAreNotAllowed(unittest.TestCase): + def test_variable_name_cannot_be_empty(self): + cdf = pycdfpp.CDF() + with self.assertRaises(ValueError): + cdf.add_variable("", values=np.arange(10)) + + def test_attribute_name_cannot_be_empty(self): + cdf = pycdfpp.CDF() + cdf.add_variable("var1", values=np.arange(10)) + with self.assertRaises(ValueError): + cdf["var1"].add_attribute("", "value") + with self.assertRaises(ValueError): + cdf.add_attribute("", ["value"]) + if __name__ == '__main__': unittest.main()