Parcourir la source

fix: proper support for anyOf in unevaluated* context

Sam Jaffe il y a 1 an
Parent
commit
3d3b1e15a2
2 fichiers modifiés avec 15 ajouts et 4 suppressions
  1. 3 0
      include/jvalidate/schema.h
  2. 12 4
      include/jvalidate/validation_visitor.h

+ 3 - 0
include/jvalidate/schema.h

@@ -43,6 +43,9 @@ public:
   bool is_pure_reference() const {
     return reference_ && constraints_.empty() && post_constraints_.empty() && not default_;
   }
+  bool accepts_all() const {
+    return not reference_ && constraints_.empty() && post_constraints_.empty();
+  }
   std::optional<std::string> const & rejects_all() const { return rejects_all_; }
   std::optional<schema::Node const *> reference_schema() const { return reference_; }
 

+ 12 - 4
include/jvalidate/validation_visitor.h

@@ -93,14 +93,17 @@ public:
 
   Status visit(constraint::AnyOfConstraint const & cons) const {
     size_t i = 0;
+
+    Status rval = Status::Reject;
     for (schema::Node const * subschema : cons.children) {
       if (validate_subschema(subschema, i)) {
-        return Status::Accept;
+        // TODO(samjaffe): Perhaps we should store some UnevaluatedTracking object for short-circuit
+        rval = Status::Accept;
       }
       ++i;
     }
 
-    return Status::Reject;
+    return rval;
   }
 
   Status visit(constraint::OneOfConstraint const & cons) const {
@@ -117,11 +120,11 @@ public:
   }
 
   Status visit(constraint::NotConstraint const & cons) const {
-    return validate_subschema(cons.child, "not") == Status::Reject;
+    return validate_subschema(cons.child, "") == Status::Reject;
   }
 
   Status visit(constraint::ConditionalConstraint const & cons) const {
-    if (validate_subschema(cons.if_constraint, "if")) {
+    if (validate_subschema(cons.if_constraint, "")) {
       return validate_subschema(cons.then_constraint, "then");
     }
     return validate_subschema(cons.else_constraint, "else");
@@ -425,6 +428,11 @@ public:
       return Status::Reject;
     }
 
+    if (schema_.accepts_all()) {
+      // An accept-all schema is not No-Op for the purpose of unevaluated*
+      return Status::Accept;
+    }
+
     Status rval = Status::Noop;
     if (auto ref = schema_.reference_schema()) {
       rval = validate_subschema(*ref, "$ref");