@@ -50,6 +50,10 @@ sub _eval_keyword_unevaluatedItems ($self, $data, $schema, $state) {
50
50
51
51
return 1 if not is_type(' array' , $data );
52
52
53
+ # local applicator keywords count as "evaluated"
54
+ return 1 if exists $schema -> { $state -> {spec_version } =~ / ^draft(?:7|2019-09)$ / ? ' additionalItems' : ' items' };
55
+ return 1 if $state -> {spec_version } !~ / ^draft(?:7|2019-09)$ / and exists $schema -> {contains };
56
+
53
57
my @annotations = local_annotations($state );
54
58
55
59
# a relevant keyword already produced a 'true' annotation at this location
@@ -61,11 +65,14 @@ sub _eval_keyword_unevaluatedItems ($self, $data, $schema, $state) {
61
65
if any { $bools {$_ -> keyword} && is_type(' boolean' , $_ -> annotation) && $_ -> annotation }
62
66
@annotations ;
63
67
64
- # otherwise, evaluate at every instance item greater than the max of all 'prefixItems'/numeric
65
- # 'items' annotations that isn't in a 'contains' annotation
68
+ # otherwise, evaluate at every instance item greater than the max of all 'prefixItems'
69
+ # or numeric 'items' annotations
66
70
my $max_index_annotation_keyword = $state -> {spec_version } eq ' draft2019-09' ? ' items' : ' prefixItems' ;
67
- my $last_index = max(-1, grep is_type(' integer' , $_ ),
68
- map +($_ -> keyword eq $max_index_annotation_keyword ? $_ -> annotation : ()), @annotations );
71
+ my $last_index = max(-1,
72
+ (grep is_type(' integer' , $_ ),
73
+ map +($_ -> keyword eq $max_index_annotation_keyword ? $_ -> annotation : ()), @annotations ),
74
+ ($schema -> {$max_index_annotation_keyword }//[])-> $# *,
75
+ );
69
76
70
77
return 1 if $last_index == $data -> $# *;
71
78
@@ -120,6 +127,8 @@ sub _eval_keyword_unevaluatedProperties ($self, $data, $schema, $state) {
120
127
121
128
return 1 if not is_type(' object' , $data );
122
129
130
+ return 1 if exists $schema -> {additionalProperties };
131
+
123
132
my @evaluated_properties = map {
124
133
my $keyword = $_ -> keyword;
125
134
(grep $keyword eq $_ , qw( properties additionalProperties patternProperties unevaluatedProperties) )
@@ -130,6 +139,10 @@ sub _eval_keyword_unevaluatedProperties ($self, $data, $schema, $state) {
130
139
my @orig_annotations = $state -> {annotations }-> @*;
131
140
my (@valid_properties , @new_annotations );
132
141
foreach my $property (sort keys %$data ) {
142
+ next if exists (($schema -> {properties }//{})-> {$property })
143
+ or any { $property =~ m /$ _/ } keys (($schema -> {patternProperties }//{})-> %*)
144
+ or exists $schema -> {additionalProperties };
145
+
133
146
next if any { $_ eq $property } @evaluated_properties ;
134
147
135
148
if (is_type(' boolean' , $schema -> {unevaluatedProperties })) {
0 commit comments