Skip to content

Commit a8c0088

Browse files
fix: only check minProperties or maxProperties on objects (#802)
`minProperties` and `maxProperties` are only applicable on objects. https://www.learnjsonschema.com/draft4/validation/minproperties/ https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.5.4.2
1 parent dff04e3 commit a8c0088

File tree

3 files changed

+57
-38
lines changed

3 files changed

+57
-38
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
9+
### Fixed
10+
- only check minProperties or maxProperties on objects ([#802](https://github.com/jsonrainbow/json-schema/pull/802))
911

1012
## [6.2.1] - 2025-03-06
1113
### Fixed

src/JsonSchema/Constraints/ObjectConstraint.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,19 @@ protected function &getProperty(&$element, $property, $fallback = null)
175175
*/
176176
protected function validateMinMaxConstraint($element, $objectDefinition, ?JsonPointer $path = null)
177177
{
178+
if (!$this->getTypeCheck()::isObject($element)) {
179+
return;
180+
}
181+
178182
// Verify minimum number of properties
179-
if (isset($objectDefinition->minProperties) && !is_object($objectDefinition->minProperties)) {
180-
if ($this->getTypeCheck()->propertyCount($element) < $objectDefinition->minProperties) {
183+
if (isset($objectDefinition->minProperties) && is_int($objectDefinition->minProperties)) {
184+
if ($this->getTypeCheck()->propertyCount($element) < max(0, $objectDefinition->minProperties)) {
181185
$this->addError(ConstraintError::PROPERTIES_MIN(), $path, ['minProperties' => $objectDefinition->minProperties]);
182186
}
183187
}
184188
// Verify maximum number of properties
185-
if (isset($objectDefinition->maxProperties) && !is_object($objectDefinition->maxProperties)) {
186-
if ($this->getTypeCheck()->propertyCount($element) > $objectDefinition->maxProperties) {
189+
if (isset($objectDefinition->maxProperties) && is_int($objectDefinition->maxProperties)) {
190+
if ($this->getTypeCheck()->propertyCount($element) > max(0, $objectDefinition->maxProperties)) {
187191
$this->addError(ConstraintError::PROPERTIES_MAX(), $path, ['maxProperties' => $objectDefinition->maxProperties]);
188192
}
189193
}

tests/Constraints/MinMaxPropertiesTest.php

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
namespace JsonSchema\Tests\Constraints;
1111

12+
use JsonSchema\Constraints\Constraint;
13+
1214
class MinMaxPropertiesTest extends BaseTestCase
1315
{
1416
protected $validateSchema = true;
@@ -19,50 +21,71 @@ class MinMaxPropertiesTest extends BaseTestCase
1921
public function getValidTests(): array
2022
{
2123
return [
22-
[
23-
'{
24+
'Empty object with minProperties: 0' => [
25+
'input' => '{
2426
"value": {}
2527
}',
26-
'{
28+
'schema' => '{
2729
"type": "object",
2830
"properties": {
2931
"value": {"type": "object", "minProperties": 0}
3032
}
3133
}'
3234
],
33-
[
34-
'{
35+
'Empty object with maxProperties: 1' => [
36+
'input' => '{
3537
"value": {}
3638
}',
37-
'{
39+
'schema' => '{
3840
"type": "object",
3941
"properties": {
4042
"value": {"type": "object", "maxProperties": 1}
4143
}
4244
}'
4345
],
44-
[
45-
'{
46+
'Empty object with minProperties: 0 and maxProperties: 1' => [
47+
'input' => '{
4648
"value": {}
4749
}',
48-
'{
50+
'schema' => '{
4951
"type": "object",
5052
"properties": {
5153
"value": {"type": "object", "minProperties": 0,"maxProperties": 1}
5254
}
5355
}'
5456
],
55-
[
56-
'{
57+
'Object with two properties with minProperties: 1 and maxProperties: 2' => [
58+
'input' => '{
5759
"value": {"foo": 1, "bar": 2}
5860
}',
59-
'{
61+
'schema' => '{
6062
"type": "object",
6163
"properties": {
6264
"value": {"type": "object", "minProperties": 1,"maxProperties": 2}
6365
}
6466
}'
6567
],
68+
'Empty array with minProperties: 1 and maxProperties: 2' => [
69+
'input' => '{
70+
"value": []
71+
}',
72+
'schema' => '{
73+
"properties": {
74+
"value": {"minProperties": 1,"maxProperties": 2}
75+
}
76+
}',
77+
'checkMode' => Constraint::CHECK_MODE_NORMAL,
78+
],
79+
'Array with two items with maxProperties: 1' => [
80+
'input' => '{
81+
"value": [1, 2]
82+
}',
83+
'schema' => '{
84+
"properties": {
85+
"value": {"maxProperties": 1}
86+
}
87+
}'
88+
],
6689
];
6790
}
6891

@@ -72,20 +95,20 @@ public function getValidTests(): array
7295
public function getInvalidTests(): array
7396
{
7497
return [
75-
[
76-
'{
98+
'Empty object with minProperties: 1' => [
99+
'input' => '{
77100
"value": {}
78101
}',
79-
'{
102+
'schema' => '{
80103
"type": "object",
81104
"properties": {
82105
"value": {"type": "object", "minProperties": 1}
83106
}
84107
}'
85108
],
86-
[
87-
'{}',
88-
'{
109+
'Empty object with minProperties' => [
110+
'input' => '{}',
111+
'schema' => '{
89112
"type": "object",
90113
"properties": {
91114
"propertyOne": {
@@ -98,41 +121,31 @@ public function getInvalidTests(): array
98121
"minProperties": 1
99122
}'
100123
],
101-
[
102-
'{
124+
'Object with two properties with maxProperties: 1' => [
125+
'input' => '{
103126
"value": {
104127
"propertyOne": "valueOne",
105128
"propertyTwo": "valueTwo"
106129
}
107130
}',
108-
'{
131+
'schema' => '{
109132
"type": "object",
110133
"properties": {
111134
"value": {"type": "object", "maxProperties": 1}
112135
}
113136
}'
114137
],
115-
[
116-
'{
138+
'Object with two properties with minProperties: 1 and maxProperties: 2' => [
139+
'input' => '{
117140
"value": {"foo": 1, "bar": 2, "baz": 3}
118141
}',
119-
'{
142+
'schema' => '{
120143
"type": "object",
121144
"properties": {
122145
"value": {"type": "object", "minProperties": 1,"maxProperties": 2}
123146
}
124147
}'
125148
],
126-
[
127-
'{
128-
"value": []
129-
}',
130-
'{
131-
"properties": {
132-
"value": {"minProperties": 1,"maxProperties": 2}
133-
}
134-
}'
135-
],
136149
];
137150
}
138151
}

0 commit comments

Comments
 (0)