aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/JSON.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-07-24 22:44:51 +0200
committerJay Berkenbilt <ejb@ql.org>2022-07-24 22:44:51 +0200
commit4674c04cb80e0a50cde1b97464642e2778f9522f (patch)
tree9a79072f17c0053e576d754fb7d22ac046b4f4b4 /libqpdf/JSON.cc
parentf8d1ab946205440ed3c44511ef42e5ad13fb9e5e (diff)
downloadqpdf-4674c04cb80e0a50cde1b97464642e2778f9522f.tar.zst
JSON schema: support multi-element array validation
Diffstat (limited to 'libqpdf/JSON.cc')
-rw-r--r--libqpdf/JSON.cc52
1 files changed, 40 insertions, 12 deletions
diff --git a/libqpdf/JSON.cc b/libqpdf/JSON.cc
index 7bd2337f..9b9da656 100644
--- a/libqpdf/JSON.cc
+++ b/libqpdf/JSON.cc
@@ -538,27 +538,55 @@ JSON::checkSchemaInternal(
}
}
} else if (sch_arr) {
- if (sch_arr->elements.size() != 1) {
- QTC::TC("libtests", "JSON schema array error");
+ auto n_elements = sch_arr->elements.size();
+ if (n_elements == 1) {
+ // A single-element array in the schema allows a single
+ // element in the object or a variable-length array, each
+ // of whose items must conform to the single element of
+ // the schema array. This doesn't apply to arrays of
+ // arrays -- we fall back to the behavior of allowing a
+ // single item only when the object is not an array.
+ if (this_arr) {
+ int i = 0;
+ for (auto const& element: this_arr->elements) {
+ checkSchemaInternal(
+ element.get(),
+ sch_arr->elements.at(0).get(),
+ flags,
+ errors,
+ prefix + "." + QUtil::int_to_string(i));
+ ++i;
+ }
+ } else {
+ QTC::TC("libtests", "JSON schema array for single item");
+ checkSchemaInternal(
+ this_v,
+ sch_arr->elements.at(0).get(),
+ flags,
+ errors,
+ prefix);
+ }
+ } else if (!this_arr || (this_arr->elements.size() != n_elements)) {
+ QTC::TC("libtests", "JSON schema array length mismatch");
errors.push_back(
- err_prefix + " schema array contains other than one item");
+ err_prefix + " is supposed to be an array of length " +
+ QUtil::uint_to_string(n_elements));
return false;
- }
- if (this_arr) {
- int i = 0;
+ } else {
+ // A multi-element array in the schema must correspond to
+ // an element of the same length in the object. Each
+ // element in the object is validated against the
+ // corresponding element in the schema.
+ size_t i = 0;
for (auto const& element: this_arr->elements) {
checkSchemaInternal(
element.get(),
- sch_arr->elements.at(0).get(),
+ sch_arr->elements.at(i).get(),
flags,
errors,
- prefix + "." + QUtil::int_to_string(i));
+ prefix + "." + QUtil::uint_to_string(i));
++i;
}
- } else {
- QTC::TC("libtests", "JSON schema array for single item");
- checkSchemaInternal(
- this_v, sch_arr->elements.at(0).get(), flags, errors, prefix);
}
} else if (!sch_str) {
QTC::TC("libtests", "JSON schema other type");