From efdd7528cc05c2da0be1b842b7ee7617c5b01e26 Mon Sep 17 00:00:00 2001 From: Alex Groleau Date: Wed, 11 Jun 2025 20:28:39 -0400 Subject: [PATCH] switched strict validation from additionalProperties to unevaluatedProperties to catch conditional properties automatically in verification --- src/lib.rs | 6 +++--- src/tests.rs | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8ff8842..414e529 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,10 +95,10 @@ fn cache_json_schema(schema_id: &str, schema: JsonB, strict: bool) -> JsonB { fn apply_strict_validation(schema: &mut Value) { match schema { Value::Object(map) => { - // If this is an object type schema, add additionalProperties: false + // If this is an object type schema, add unevaluatedProperties: false if let Some(Value::String(t)) = map.get("type") { - if t == "object" && !map.contains_key("additionalProperties") { - map.insert("additionalProperties".to_string(), Value::Bool(false)); + if t == "object" && !map.contains_key("unevaluatedProperties") && !map.contains_key("additionalProperties") { + map.insert("unevaluatedProperties".to_string(), Value::Bool(false)); } } // Recurse into all properties diff --git a/src/tests.rs b/src/tests.rs index 5792964..40d98fb 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -448,10 +448,10 @@ fn test_auto_strict_validation() { // Should fail with strict schema let result_root_strict = validate_json_schema(schema_id, jsonb(invalid_root_extra.clone())); - assert_failure_with_json!(result_root_strict, 1, "Object contains properties that are not allowed"); + assert_failure_with_json!(result_root_strict, 1, "Schema validation always fails"); let errors_root = result_root_strict.0["errors"].as_array().unwrap(); - assert_eq!(errors_root[0]["code"], "ADDITIONAL_PROPERTIES_NOT_ALLOWED"); - assert_eq!(errors_root[0]["details"]["path"], ""); + assert_eq!(errors_root[0]["code"], "FALSE_SCHEMA"); + assert_eq!(errors_root[0]["details"]["path"], "/extraField"); // Should pass with non-strict schema let result_root_non_strict = validate_json_schema(schema_id_non_strict, jsonb(invalid_root_extra)); @@ -468,10 +468,10 @@ fn test_auto_strict_validation() { // Should fail with strict schema let result_nested_strict = validate_json_schema(schema_id, jsonb(invalid_nested_extra.clone())); - assert_failure_with_json!(result_nested_strict, 1, "Object contains properties that are not allowed"); + assert_failure_with_json!(result_nested_strict, 1, "Schema validation always fails"); let errors_nested = result_nested_strict.0["errors"].as_array().unwrap(); - assert_eq!(errors_nested[0]["code"], "ADDITIONAL_PROPERTIES_NOT_ALLOWED"); - assert_eq!(errors_nested[0]["details"]["path"], "/profile"); + assert_eq!(errors_nested[0]["code"], "FALSE_SCHEMA"); + assert_eq!(errors_nested[0]["details"]["path"], "/profile/extraNested"); // Should pass with non-strict schema let result_nested_non_strict = validate_json_schema(schema_id_non_strict, jsonb(invalid_nested_extra)); @@ -491,10 +491,10 @@ fn test_auto_strict_validation() { // Should fail with strict schema let result_deep_strict = validate_json_schema(schema_id, jsonb(invalid_deep_extra.clone())); - assert_failure_with_json!(result_deep_strict, 1, "Object contains properties that are not allowed"); + assert_failure_with_json!(result_deep_strict, 1, "Schema validation always fails"); let errors_deep = result_deep_strict.0["errors"].as_array().unwrap(); - assert_eq!(errors_deep[0]["code"], "ADDITIONAL_PROPERTIES_NOT_ALLOWED"); - assert_eq!(errors_deep[0]["details"]["path"], "/profile/preferences"); + assert_eq!(errors_deep[0]["code"], "FALSE_SCHEMA"); + assert_eq!(errors_deep[0]["details"]["path"], "/profile/preferences/extraDeep"); // Should pass with non-strict schema let result_deep_non_strict = validate_json_schema(schema_id_non_strict, jsonb(invalid_deep_extra)); @@ -510,15 +510,15 @@ fn test_auto_strict_validation() { // Should fail with strict schema let result_array_strict = validate_json_schema(schema_id, jsonb(invalid_array_item_extra.clone())); - assert_failure_with_json!(result_array_strict, 1, "Object contains properties that are not allowed"); + assert_failure_with_json!(result_array_strict, 1, "Schema validation always fails"); let errors_array = result_array_strict.0["errors"].as_array().unwrap(); - assert_eq!(errors_array[0]["code"], "ADDITIONAL_PROPERTIES_NOT_ALLOWED"); - assert_eq!(errors_array[0]["details"]["path"], "/tags/0"); + assert_eq!(errors_array[0]["code"], "FALSE_SCHEMA"); + assert_eq!(errors_array[0]["details"]["path"], "/tags/0/extraInArray"); // Should pass with non-strict schema let result_array_non_strict = validate_json_schema(schema_id_non_strict, jsonb(invalid_array_item_extra)); assert_success_with_json!(result_array_non_strict, "Extra array item property should be allowed with non-strict schema"); - + // Test 6: Schema with explicit additionalProperties: true should allow extras even with strict=true let schema_id_permissive = "permissive_test"; let permissive_schema = json!({ @@ -538,4 +538,4 @@ fn test_auto_strict_validation() { let result_permissive = validate_json_schema(schema_id_permissive, jsonb(instance_with_extra)); assert_success_with_json!(result_permissive, "Instance with extra property should pass when additionalProperties is explicitly true, even with strict=true"); -} \ No newline at end of file +}