Skip to content

Commit cbfb28b

Browse files
authored
When format is json reparse string (#3947)
1 parent 5c274fa commit cbfb28b

File tree

7 files changed

+65
-21
lines changed

7 files changed

+65
-21
lines changed

src/cfnlint/data/schemas/patches/providers/all/aws_iam_managedpolicy/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[
2+
{
3+
"op": "add",
4+
"path": "/properties/PolicyDocument",
5+
"value": {
6+
"format": "json"
7+
}
8+
}
9+
]

src/cfnlint/data/schemas/providers/us_east_1/aws-iam-managedpolicy.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,10 @@
5050
"type": "string"
5151
},
5252
"PolicyDocument": {
53+
"format": "json",
5354
"maxLength": 6144,
5455
"minLength": 1,
55-
"pattern": "[\\u0009\\u000A\\u000D\\u0020-\\u00FF]+",
56-
"type": [
57-
"object",
58-
"string"
59-
]
56+
"pattern": "[\\u0009\\u000A\\u000D\\u0020-\\u00FF]+"
6057
},
6158
"PolicyId": {
6259
"type": "string"

src/cfnlint/data/schemas/providers/us_gov_east_1/aws-iam-managedpolicy.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,10 @@
4949
"type": "string"
5050
},
5151
"PolicyDocument": {
52+
"format": "json",
5253
"maxLength": 6144,
5354
"minLength": 1,
54-
"pattern": "[\\u0009\\u000A\\u000D\\u0020-\\u00FF]+",
55-
"type": [
56-
"object",
57-
"string"
58-
]
55+
"pattern": "[\\u0009\\u000A\\u000D\\u0020-\\u00FF]+"
5956
},
6057
"PolicyId": {
6158
"type": "string"

src/cfnlint/data/schemas/providers/us_gov_west_1/aws-iam-managedpolicy.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,10 @@
4949
"type": "string"
5050
},
5151
"PolicyDocument": {
52+
"format": "json",
5253
"maxLength": 6144,
5354
"minLength": 1,
54-
"pattern": "[\\u0009\\u000A\\u000D\\u0020-\\u00FF]+",
55-
"type": [
56-
"object",
57-
"string"
58-
]
55+
"pattern": "[\\u0009\\u000A\\u000D\\u0020-\\u00FF]+"
5956
},
6057
"PolicyId": {
6158
"type": "string"

src/cfnlint/rules/resources/properties/StringLength.py

+26-6
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,19 @@ def _non_string_min_length(self, instance, mL):
7575
# pylint: disable=unused-argument, arguments-renamed
7676
def maxLength(self, validator, mL, instance, schema):
7777
if validator.is_type(instance, "string"):
78-
if len(instance) > mL:
79-
yield ValidationError(f"{instance!r} is longer than {mL}")
80-
return
78+
if schema.get("format") == "json":
79+
try:
80+
instance = json.loads(instance)
81+
except: # noqa: E722
82+
pass
83+
return
84+
yield from self._non_string_max_length(instance, mL)
85+
return
86+
else:
87+
if len(instance) > mL:
88+
yield ValidationError(f"{instance!r} is longer than {mL}")
89+
return
90+
8191
# there are scenarios where Fn::Sub may not predictable so use
8292
# best judgement
8393
key, value = is_function(instance)
@@ -93,15 +103,25 @@ def maxLength(self, validator, mL, instance, schema):
93103
validator, mL, self._fix_sub_string(value[0]), schema
94104
)
95105
return
106+
96107
if "object" in ensure_list(schema.get("type")):
97108
yield from self._non_string_max_length(instance, mL)
98109

99110
# pylint: disable=unused-argument, arguments-renamed
100111
def minLength(self, validator, mL, instance, schema):
101112
if validator.is_type(instance, "string"):
102-
if len(instance) < mL:
103-
yield ValidationError(f"{instance!r} is shorter than {mL}")
104-
return
113+
if schema.get("format") == "json":
114+
try:
115+
instance = json.loads(instance)
116+
except: # noqa: E722
117+
pass
118+
return
119+
yield from self._non_string_min_length(instance, mL)
120+
return
121+
else:
122+
if len(instance) < mL:
123+
yield ValidationError(f"{instance!r} is shorter than {mL}")
124+
return
105125

106126
# there are scenarios where Fn::Sub may not predictable so use
107127
# best judgement

test/unit/rules/resources/properties/test_string_length.py

+24
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ def rule():
4343
{"type": ["string", "object"]},
4444
1,
4545
),
46+
(
47+
'{"foo": 1, "bar": {"Fn::Sub": ["2", {}]}}',
48+
20,
49+
{"type": ["string", "object"], "format": "json"},
50+
1,
51+
),
52+
(
53+
'{"foo: 1, "bar": {"Fn::Sub": ["2", {}]}}',
54+
20,
55+
{"type": ["string", "object"], "format": "json"},
56+
0,
57+
),
4658
],
4759
)
4860
def test_min_length(instance, mL, expected, rule, schema, validator):
@@ -77,6 +89,18 @@ def test_min_length(instance, mL, expected, rule, schema, validator):
7789
{"type": ["string", "object"]},
7890
1,
7991
),
92+
(
93+
'{"foo": 1, "bar": {"Fn::Sub": ["2", {}]}}',
94+
4,
95+
{"type": ["string", "object"], "format": "json"},
96+
1,
97+
),
98+
(
99+
'{"foo: 1, "bar": {"Fn::Sub": ["2", {}]}}',
100+
4,
101+
{"type": ["string", "object"], "format": "json"},
102+
0,
103+
),
80104
],
81105
)
82106
def test_max_length(instance, mL, expected, rule, schema, validator):

0 commit comments

Comments
 (0)