Trying to verify if a node has a child node, using operator [], if the node is a Sequence node (a yaml list), yaml-cpp converts the parent node to be a Map.
See the sample code here:
#include <yaml-cpp/yaml.h>
#include <cassert>
#include <iostream>
int main() {
std::string yaml =
R"(
---
b:
- 1
- 2
- 3
)";
auto yaml_node = YAML::Load(yaml);
if (yaml_node["b"]) {
assert(yaml_node["b"].size() == 3);
assert(yaml_node["b"].IsSequence());
}
if (yaml_node["b"][1]) {
assert(yaml_node["b"].size() == 3);
assert(yaml_node["b"].IsSequence());
}
if (!yaml_node["b"][4]) {
assert(yaml_node["b"].size() == 3);
// this assert passes
assert(yaml_node["b"].IsMap());
// this assert crashes
// assert(yaml_node["b"].IsSequence());
}
// reload
yaml_node = YAML::Load(yaml);
if (yaml_node["b"]) {
assert(yaml_node["b"].size() == 3);
assert(yaml_node["b"].IsSequence());
}
if (!yaml_node["b"]["b"]) {
assert(yaml_node["b"].size() == 3);
// this assert passes
assert(yaml_node["b"].IsMap());
// this assert crashes
// assert(yaml_node["b"].IsSequence());
}
}
Exepcted Results:
yaml_node["b"] should not change while testing for a non existent node
Actual Results:
yaml_node["b"] changes to be a Map if an out-of-bounds verification is done through the operator []
yaml_node["b"] changes to be a Map if a map access is done through the operator []
Workarround:
Verify if node is a Sequence, check its size and only access this until the size.
Only access the node with a string if it is type is a Map
if (yaml_node["b"].IsMap() && yaml_node["b"]["b"]);
// or
if (yaml_node["b"].IsSequence() && 4 < yaml_node["b"].size() && yaml_node["b"][4]);
Trying to verify if a node has a child node, using operator [], if the node is a Sequence node (a yaml list), yaml-cpp converts the parent node to be a Map. See the sample code here:
Exepcted Results:
yaml_node["b"]
should not change while testing for a non existent nodeActual Results:
yaml_node["b"]
changes to be a Map if an out-of-bounds verification is done through the operator []yaml_node["b"]
changes to be a Map if a map access is done through the operator []Workarround: Verify if node is a Sequence, check its size and only access this until the size. Only access the node with a string if it is type is a Map