validator: escape json-pointer-field when appending
This commit is contained in:
parent
b2240084fe
commit
9b3769a132
@ -116,6 +116,12 @@ public:
|
|||||||
|
|
||||||
const std::string url() const;
|
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 derive(const std::string &uri) const
|
||||||
{
|
{
|
||||||
json_uri u = *this;
|
json_uri u = *this;
|
||||||
@ -123,6 +129,7 @@ public:
|
|||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// append a pointer-field to the pointer-part of this uri
|
||||||
json_uri append(const std::string &field) const
|
json_uri append(const std::string &field) const
|
||||||
{
|
{
|
||||||
json_uri u = *this;
|
json_uri u = *this;
|
||||||
@ -145,7 +152,6 @@ public:
|
|||||||
friend std::ostream &operator<<(std::ostream &os, const json_uri &u);
|
friend std::ostream &operator<<(std::ostream &os, const json_uri &u);
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
|
||||||
namespace json_schema_draft4
|
namespace json_schema_draft4
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,8 @@
|
|||||||
*/
|
*/
|
||||||
#include "json-schema.hpp"
|
#include "json-schema.hpp"
|
||||||
|
|
||||||
namespace nlohmann {
|
namespace nlohmann
|
||||||
|
{
|
||||||
|
|
||||||
void json_pointer::from_string(const std::string &r)
|
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();
|
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
|
||||||
|
|||||||
@ -57,12 +57,12 @@ class resolver
|
|||||||
switch (i.value().type()) {
|
switch (i.value().type()) {
|
||||||
|
|
||||||
case json::value_t::object: // child is object, it is a schema
|
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;
|
break;
|
||||||
|
|
||||||
case json::value_t::array: {
|
case json::value_t::array: {
|
||||||
std::size_t index = 0;
|
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()) {
|
for (auto &v : i.value()) {
|
||||||
if (v.type() == json::value_t::object) // array element is object
|
if (v.type() == json::value_t::object) // array element is object
|
||||||
resolve(v, child_id.append(std::to_string(index)) );
|
resolve(v, child_id.append(std::to_string(index)) );
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user