Skip to content

Commit 6f3b99c

Browse files
brondaniSGSSGene
authored andcommitted
Validate mapping key uniqueness
1 parent 5b04bd3 commit 6f3b99c

6 files changed

Lines changed: 23 additions & 3 deletions

File tree

include/yaml-cpp/exceptions.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ const char* const INVALID_ALIAS = "invalid alias";
9090
const char* const INVALID_TAG = "invalid tag";
9191
const char* const BAD_FILE = "bad file";
9292
const char* const UNEXPECTED_TOKEN_AFTER_DOC = "unexpected token after end of document";
93+
const char* const NON_UNIQUE_MAP_KEY = "map keys must be unique";
9394

9495
template <typename T>
9596
inline const std::string KEY_NOT_FOUND_WITH_KEY(
@@ -301,6 +302,16 @@ class YAML_CPP_API BadFile : public Exception {
301302
BadFile(const BadFile&) = default;
302303
~BadFile() YAML_CPP_NOEXCEPT override;
303304
};
305+
306+
class YAML_CPP_API NonUniqueMapKey : public RepresentationException {
307+
public:
308+
template <typename Key>
309+
NonUniqueMapKey(const Mark& mark_, const Key& key)
310+
: RepresentationException(mark_, ErrorMsg::NON_UNIQUE_MAP_KEY) {}
311+
NonUniqueMapKey(const NonUniqueMapKey&) = default;
312+
~NonUniqueMapKey() YAML_CPP_NOEXCEPT override;
313+
};
314+
304315
} // namespace YAML
305316

306317
#if defined(_MSC_VER)

include/yaml-cpp/node/detail/impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ inline void node_data::force_insert(const Key& key, const Value& value,
218218

219219
node& k = convert_to_node(key, pMemory);
220220
node& v = convert_to_node(value, pMemory);
221-
insert_map_pair(k, v);
221+
insert_map_pair(k, v, true);
222222
}
223223

224224
template <typename T>

include/yaml-cpp/node/detail/node_data.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class YAML_CPP_API node_data {
9090
void reset_sequence();
9191
void reset_map();
9292

93-
void insert_map_pair(node& key, node& value);
93+
void insert_map_pair(node& key, node& value, bool force = false);
9494
void convert_to_map(const shared_memory_holder& pMemory);
9595
void convert_sequence_to_map(const shared_memory_holder& pMemory);
9696

src/exceptions.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ BadPushback::~BadPushback() YAML_CPP_NOEXCEPT = default;
1717
BadInsert::~BadInsert() YAML_CPP_NOEXCEPT = default;
1818
EmitterException::~EmitterException() YAML_CPP_NOEXCEPT = default;
1919
BadFile::~BadFile() YAML_CPP_NOEXCEPT = default;
20+
NonUniqueMapKey::~NonUniqueMapKey() YAML_CPP_NOEXCEPT = default;
2021
} // namespace YAML

src/node_data.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,12 @@ void node_data::reset_map() {
279279
m_undefinedPairs.clear();
280280
}
281281

282-
void node_data::insert_map_pair(node& key, node& value) {
282+
void node_data::insert_map_pair(node& key, node& value, bool force) {
283+
if (!force && !key.scalar().empty())
284+
for (const auto& mapEntry : m_map)
285+
if (mapEntry.first->scalar() == key.scalar())
286+
throw NonUniqueMapKey(m_mark, key);
287+
283288
m_map.emplace_back(&key, &value);
284289

285290
if (!key.is_defined() || !value.is_defined())

test/integration/load_node_test.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,9 @@ TEST(LoadNodeTest, IncorrectSeqEnd) {
465465
EXPECT_THROW(Load("[foo]_bar"), ParserException);
466466
}
467467

468+
TEST(LoadNodeTest, NonUniqueMapKey) {
469+
EXPECT_THROW(Load("{a: A, b: B, a: A}"), NonUniqueMapKey);
470+
}
468471

469472
} // namespace
470473
} // namespace YAML

0 commit comments

Comments
 (0)