Correct escaping of list keys with single quotes
YANG 1.1 still uses XPath 1.0 which defines [1] strings in such a manner
that it is impossible to represent both single and double quotes in the
same string. That's why sysrepo chokes on such XPaths, for example.
Let's just ensure that anything which already contains an apostrophe (a
single quote) will be double-quoted instead of the default single-quoted
thingy.
Note that the parser itself treats all list keys as strings internally;
there's no validation, and the information about the underlying data
type is not preserved. That's why a numeric list key would be still
single-quoted in the current code.
[1] https://www.w3.org/TR/1999/REC-xpath-19991116/#exprlex
Change-Id: I87a2b88bb4f5d8f3383c1637088980c5a670aee3
diff --git a/src/ast_path.cpp b/src/ast_path.cpp
index e943d0e..bb14425 100644
--- a/src/ast_path.cpp
+++ b/src/ast_path.cpp
@@ -84,6 +84,18 @@
return node.m_name;
}
};
+
+std::string escapeListKeyString(const std::string& what)
+{
+ // If we have both single and double quote, then we're screwed, but that "shouldn't happen"
+ // in <= YANG 1.1 due to limitations in XPath 1.0.
+ if (what.find('\'') != std::string::npos) {
+ return '\"' + what + '\"';
+ } else {
+ return '\'' + what + '\'';
+ }
+}
+
struct nodeToDataStringVisitor : public boost::static_visitor<std::string> {
std::string operator()(const listElement_& node) const
{
@@ -91,7 +103,7 @@
res << node.m_name + "[";
std::transform(node.m_keys.begin(), node.m_keys.end(),
std::experimental::make_ostream_joiner(res, ' '),
- [] (const auto& it) { return it.first + "=" + '\'' + it.second + '\''; });
+ [] (const auto& it) { return it.first + "=" + escapeListKeyString(it.second); });
res << "]";
return res.str();
}