validator: escape json-pointer-field when appending

This commit is contained in:
Patrick Boettcher 2016-12-27 00:34:11 +01:00
parent b2240084fe
commit 9b3769a132
3 changed files with 70 additions and 4 deletions

View File

@ -116,6 +116,12 @@ public:
const std::string url() const;
// decode and encode strings for ~ and % escape sequences
static std::string unescape(const std::string &);
static std::string escape(const std::string &);
// create a new json_uri based in this one and the given uri
// resolves relative changes (pathes or pointers) and resets part if proto or hostname changes
json_uri derive(const std::string &uri) const
{
json_uri u = *this;
@ -123,6 +129,7 @@ public:
return u;
}
// append a pointer-field to the pointer-part of this uri
json_uri append(const std::string &field) const
{
json_uri u = *this;
@ -145,7 +152,6 @@ public:
friend std::ostream &operator<<(std::ostream &os, const json_uri &u);
};
//
namespace json_schema_draft4
{

View File

@ -25,7 +25,8 @@
*/
#include "json-schema.hpp"
namespace nlohmann {
namespace nlohmann
{
void json_pointer::from_string(const std::string &r)
{
@ -124,4 +125,63 @@ std::ostream &operator<<(std::ostream &os, const json_uri &u)
return os << u.to_string();
}
std::string json_uri::unescape(const std::string &src)
{
std::string l = src;
std::size_t pos = src.size() - 1;
do {
pos = l.rfind('~', pos);
if (pos == std::string::npos)
break;
if (pos < l.size() - 1) {
switch (l[pos + 1]) {
case '0':
l.replace(pos, 2, "~");
break;
case '1':
l.replace(pos, 2, "/");
break;
default:
break;
}
}
if (pos == 0)
break;
pos--;
} while (pos != std::string::npos);
// TODO - percent handling
return l;
}
std::string json_uri::escape(const std::string &src)
{
std::vector<std::pair<std::string, std::string>> chars = {
{"~", "~0"},
{"/", "~1"},
{"%", "%25"}};
std::string l = src;
for (const auto &c : chars) {
std::size_t pos = 0;
do {
pos = l.find(c.first, pos);
if (pos == std::string::npos)
break;
l.replace(pos, 1, c.second);
pos += c.second.size();
} while (1);
}
return l;
}
} // nlohmann

View File

@ -57,12 +57,12 @@ class resolver
switch (i.value().type()) {
case json::value_t::object: // child is object, it is a schema
resolve(i.value(), id.append(i.key()));
resolve(i.value(), id.append( json_uri::escape(i.key())) );
break;
case json::value_t::array: {
std::size_t index = 0;
auto child_id = id.append(i.key());
auto child_id = id.append(json_uri::escape(i.key()));
for (auto &v : i.value()) {
if (v.type() == json::value_t::object) // array element is object
resolve(v, child_id.append(std::to_string(index)) );