aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/JSON.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-01-22 20:33:26 +0100
committerJay Berkenbilt <ejb@ql.org>2022-01-30 19:11:03 +0100
commit8dea480c9f065fdac76f848ed9ec7a07fd1e9870 (patch)
tree8334231ae683dcf239f439f1602268fa98f39f10 /libqpdf/JSON.cc
parent558ba2823e40867eac47686edea3fe318ce3c446 (diff)
downloadqpdf-8dea480c9f065fdac76f848ed9ec7a07fd1e9870.tar.zst
Allow optional fields in json "schema" checks
Diffstat (limited to 'libqpdf/JSON.cc')
-rw-r--r--libqpdf/JSON.cc54
1 files changed, 38 insertions, 16 deletions
diff --git a/libqpdf/JSON.cc b/libqpdf/JSON.cc
index af98553e..f70145a7 100644
--- a/libqpdf/JSON.cc
+++ b/libqpdf/JSON.cc
@@ -394,12 +394,21 @@ JSON::checkSchema(JSON schema, std::list<std::string>& errors)
{
return checkSchemaInternal(this->m->value.getPointer(),
schema.m->value.getPointer(),
- errors, "");
+ 0, errors, "");
}
+bool
+JSON::checkSchema(JSON schema, unsigned long flags,
+ std::list<std::string>& errors)
+{
+ return checkSchemaInternal(this->m->value.getPointer(),
+ schema.m->value.getPointer(),
+ flags, errors, "");
+}
bool
JSON::checkSchemaInternal(JSON_value* this_v, JSON_value* sch_v,
+ unsigned long flags,
std::list<std::string>& errors,
std::string prefix)
{
@@ -409,6 +418,8 @@ JSON::checkSchemaInternal(JSON_value* this_v, JSON_value* sch_v,
JSON_array* sch_arr = dynamic_cast<JSON_array*>(sch_v);
JSON_dictionary* sch_dict = dynamic_cast<JSON_dictionary*>(sch_v);
+ JSON_string* sch_str = dynamic_cast<JSON_string*>(sch_v);
+
std::string err_prefix;
if (prefix.empty())
{
@@ -446,34 +457,38 @@ JSON::checkSchemaInternal(JSON_value* this_v, JSON_value* sch_v,
{
std::string const& key = iter.first;
checkSchemaInternal(
- this_dict->members[key].getPointer(),
- pattern_schema,
- errors, prefix + "." + key);
+ this_dict->members[key].getPointer(), pattern_schema,
+ flags, errors, prefix + "." + key);
}
}
else if (sch_dict)
{
- for (std::map<std::string, PointerHolder<JSON_value> >::iterator iter =
- sch_dict->members.begin();
- iter != sch_dict->members.end(); ++iter)
+ for (auto& iter: sch_dict->members)
{
- std::string const& key = (*iter).first;
+ std::string const& key = iter.first;
if (this_dict->members.count(key))
{
checkSchemaInternal(
this_dict->members[key].getPointer(),
- (*iter).second.getPointer(),
- errors, prefix + "." + key);
+ iter.second.getPointer(),
+ flags, errors, prefix + "." + key);
}
else
{
- QTC::TC("libtests", "JSON key missing in object");
- errors.push_back(
- err_prefix + ": key \"" + key +
- "\" is present in schema but missing in object");
+ if (flags & f_optional)
+ {
+ QTC::TC("libtests", "JSON optional key");
+ }
+ else
+ {
+ QTC::TC("libtests", "JSON key missing in object");
+ errors.push_back(
+ err_prefix + ": key \"" + key +
+ "\" is present in schema but missing in object");
+ }
}
}
- for (std::map<std::string, PointerHolder<JSON_value> >::iterator iter =
+ for (std::map<std::string, PointerHolder<JSON_value>>::iterator iter =
this_dict->members.begin();
iter != this_dict->members.end(); ++iter)
{
@@ -510,9 +525,16 @@ JSON::checkSchemaInternal(JSON_value* this_v, JSON_value* sch_v,
checkSchemaInternal(
(*iter).getPointer(),
sch_arr->elements.at(0).getPointer(),
- errors, prefix + "." + QUtil::int_to_string(i));
+ flags, errors, prefix + "." + QUtil::int_to_string(i));
}
}
+ else if (! sch_str)
+ {
+ QTC::TC("libtests", "JSON schema other type");
+ errors.push_back(err_prefix +
+ " schema value is not dictionary, array, or string");
+ return false;
+ }
return errors.empty();
}