2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 19:08:59 +00:00

JSON: implement pattern keys in schema

This commit is contained in:
Jay Berkenbilt 2020-04-04 17:31:07 -04:00
parent 67d5ed3a64
commit 7246404177
4 changed files with 51 additions and 7 deletions

View File

@ -323,6 +323,7 @@ JSON::checkSchemaInternal(JSON_value* this_v, JSON_value* sch_v,
err_prefix = "json key \"" + prefix + "\""; err_prefix = "json key \"" + prefix + "\"";
} }
std::string pattern_key;
if (sch_dict) if (sch_dict)
{ {
if (! this_dict) if (! this_dict)
@ -331,6 +332,31 @@ JSON::checkSchemaInternal(JSON_value* this_v, JSON_value* sch_v,
errors.push_back(err_prefix + " is supposed to be a dictionary"); errors.push_back(err_prefix + " is supposed to be a dictionary");
return false; return false;
} }
auto members = sch_dict->members;
std::string key;
if ((members.size() == 1) &&
((key = members.begin()->first, key.length() > 2) &&
(key.at(0) == '<') &&
(key.at(key.length() - 1) == '>')))
{
pattern_key = key;
}
}
if (sch_dict && (! pattern_key.empty()))
{
auto pattern_schema = sch_dict->members[pattern_key].getPointer();
for (auto iter: this_dict->members)
{
std::string const& key = iter.first;
checkSchemaInternal(
this_dict->members[key].getPointer(),
pattern_schema,
errors, prefix + "." + key);
}
}
else if (sch_dict)
{
for (std::map<std::string, PointerHolder<JSON_value> >::iterator iter = for (std::map<std::string, PointerHolder<JSON_value> >::iterator iter =
sch_dict->members.begin(); sch_dict->members.begin();
iter != sch_dict->members.end(); ++iter) iter != sch_dict->members.end(); ++iter)

View File

@ -112,6 +112,11 @@ static void test_schema()
" >>" " >>"
" ]" " ]"
">>").getJSON(); ">>").getJSON();
JSON three = JSON::makeDictionary();
three.addDictionaryMember(
"<objid>",
QPDFObjectHandle::parse("<< /z (ebra) >>").getJSON());
schema.addDictionaryMember("/three", three);
JSON a = QPDFObjectHandle::parse("[(not a) (dictionary)]").getJSON(); JSON a = QPDFObjectHandle::parse("[(not a) (dictionary)]").getJSON();
check_schema(a, schema, false, "top-level type mismatch"); check_schema(a, schema, false, "top-level type mismatch");
JSON b = QPDFObjectHandle::parse( JSON b = QPDFObjectHandle::parse(
@ -142,8 +147,12 @@ static void test_schema()
" /glarp (4 enspliel)" " /glarp (4 enspliel)"
" >>" " >>"
" ]" " ]"
" /three <<"
" /anything << /x (oops) >>"
" /else << /z (okay) >>"
" >>"
">>").getJSON(); ">>").getJSON();
check_schema(b, schema, false, "top-level type mismatch"); check_schema(b, schema, false, "missing items");
check_schema(a, a, false, "top-level schema array error"); check_schema(a, a, false, "top-level schema array error");
check_schema(b, b, false, "lower-level schema array error"); check_schema(b, b, false, "lower-level schema array error");
check_schema(schema, schema, true, "pass"); check_schema(schema, schema, true, "pass");

View File

@ -1,11 +1,13 @@
--- top-level type mismatch --- top-level type mismatch
top-level object is supposed to be a dictionary top-level object is supposed to be a dictionary
--- ---
--- top-level type mismatch --- missing items
json key "./one./a": key "/q" is present in schema but missing in object json key "./one./a": key "/q" is present in schema but missing in object
json key "./one./a./r" is supposed to be a dictionary json key "./one./a./r" is supposed to be a dictionary
json key "./one./a./s" is supposed to be an array json key "./one./a./s" is supposed to be an array
json key "./one./a": key "/t" is not present in schema but appears in object json key "./one./a": key "/t" is not present in schema but appears in object
json key "./three./anything": key "/z" is present in schema but missing in object
json key "./three./anything": key "/x" is not present in schema but appears in object
json key "./two.1": key "/glarp" is present in schema but missing in object json key "./two.1": key "/glarp" is present in schema but missing in object
json key "./two.1": key "/flarp" is not present in schema but appears in object json key "./two.1": key "/flarp" is not present in schema but appears in object
json key "./two.2" is supposed to be a dictionary json key "./two.2" is supposed to be a dictionary

View File

@ -3082,11 +3082,18 @@ outfile.pdf</option>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
A dictionary in the help output means that the corresponding A dictionary in the help output means that the
location in the actual JSON output is also a dictionary with corresponding location in the actual JSON output is also a
exactly the same keys; that is, no keys present in help are dictionary with exactly the same keys; that is, no keys
absent in the real output, and no keys will be present in present in help are absent in the real output, and no keys
the real output that are not in help. will be present in the real output that are not in help. As
a special case, if the dictionary has a single key whose
name starts with <literal>&lt;</literal> and ends with
<literal>&gt;</literal>, it means that the JSON output is a
dictionary that can have any keys, each of which conforms
to the value of the special key. This is used for cases in
which the keys of the dictionary are things like object
IDs.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>