We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add correct size checking to IAM ManagedPolicy resource types
*cfn-lint version: (cfn-lint 0.58.1)*

*Description of issue.*

The PolicyDocument specified in an IAM Managed Policy has a maximum length of 6,144 characters (after converted to JSON and minified).
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html

When creating through CloudFormation an AWS::IAM::ManagedPolicy and using conditionals to leverage a 3 level environment creation differentiation, is throwing an error **E3502 PolicyDocument JSON text cannot be longer than 6144 characters**.

That happens because the policy defined in CloudFormation with the 3 level conditionals exceeds the 6144 characters limit, but when it is created it only uses 1 of the paths in the conditionals so the size is not really over 6144 characters.

This is the sample code in CloudFormation:
```
  ResourcePolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Sub
        - ResourcePolicy
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: LambdaExecutionLogs
            Effect: Allow
            Action:
              - logs:CreateLogGroup
              - logs:CreateLogStream
              - logs:PutLogEvents
            Resource:
              !Split
                - ","
                - !Join
                    - ","
                    - - !If
                        - IsDev
                        - !Join
                          - ","
                          - 
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdadev1-${EnvNameCamelCase}
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdadev1-:*
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdadev2
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdadev2:*
                        - !Ref AWS::NoValue
                      - !If
                        - IsUat
                        - !Join
                          - ","
                          - 
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat1
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat1:*
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat2
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat2:*
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat3
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat3:*
                        - !Ref AWS::NoValue
                      - !If
                        - IsProd
                        - !Join
                          - ","
                          - 
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdaprod
                            - !Sub
                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdaprod:*
                        - !Ref AWS::NoValue
          - Sid: ........
          . . .
```

So the missing feature is to be able to check the size of the policy which is going to be finally created, not the source CloudFormation code, so in that regard it needs to evaluate the parameter and resolve the conditionals to end up with the final resource code to be created.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cfnlint/rules/resources/properties/JsonSize.py`
Content:
```
1 """
2 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 SPDX-License-Identifier: MIT-0
4 """
5 import datetime
6 import json
7 import re
8 import six
9 import cfnlint.helpers
10 from cfnlint.rules import CloudFormationLintRule
11 from cfnlint.rules import RuleMatch
12 from cfnlint.helpers import RESOURCE_SPECS
13 
14 
15 class JsonSize(CloudFormationLintRule):
16     """Check if JSON Object Size is within the specified length"""
17     id = 'E3502'
18     shortdesc = 'Check if a JSON Object is within size limits'
19     description = 'Validate properties that are JSON values so that their length is within the limits'
20     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html'
21     tags = ['resources', 'limits', 'json']
22 
23     def initialize(self, cfn):
24         """Initialize the rule"""
25         for resource_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('ResourceTypes'):
26             self.resource_property_types.append(resource_type_spec)
27         for property_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('PropertyTypes'):
28             self.resource_sub_property_types.append(property_type_spec)
29 
30     def _serialize_date(self, obj):
31         if isinstance(obj, datetime.date):
32             return obj.isoformat()
33         raise TypeError('Object of type {} is not JSON serializable'.format(obj.__class__.__name__))
34 
35     def check_value(self, value, path, prop, cfn, specs):
36         """Check Role.AssumeRolePolicyDocument is within limits"""
37         matches = []
38 
39         def remove_functions(obj):
40             """ Replaces intrinsic functions with string """
41             if isinstance(obj, dict):
42                 new_obj = {}
43                 if len(obj) == 1:
44                     for k, v in obj.items():
45                         if k in cfnlint.helpers.FUNCTIONS:
46                             if k == 'Fn::Sub':
47                                 if isinstance(v, six.string_types):
48                                     return re.sub(r'\${.*}', '', v)
49                                 if isinstance(v, list):
50                                     return re.sub(r'\${.*}', '', v[0])
51                         else:
52                             new_obj[k] = remove_functions(v)
53                             return new_obj
54                 else:
55                     for k, v in obj.items():
56                         new_obj[k] = remove_functions(v)
57                     return new_obj
58             elif isinstance(obj, list):
59                 new_list = []
60                 for v in obj:
61                     new_list.append(remove_functions(v))
62                 return new_list
63 
64             return obj
65 
66         scenarios = cfn.get_object_without_nested_conditions(value, path)
67         json_max_size = specs.get('JsonMax')
68         for scenario in scenarios:
69             j = remove_functions(scenario['Object'][prop])
70             if isinstance(j, six.string_types):
71                 try:
72                     j = json.loads(j)
73                 except:  #pylint: disable=bare-except
74                     continue
75             if len(json.dumps(j, separators=(',', ':'), default=self._serialize_date)) > json_max_size:
76                 if scenario['Scenario']:
77                     message = '{0} JSON text cannot be longer than {1} characters when {2}'
78                     scenario_text = ' and '.join(['when condition "%s" is %s' % (
79                         k, v) for (k, v) in scenario['Scenario'].items()])
80                     matches.append(
81                         RuleMatch(path + [prop], message.format(prop, json_max_size, scenario_text)))
82                 else:
83                     message = '{0} JSON text cannot be longer than {1} characters'
84                     matches.append(
85                         RuleMatch(
86                             path + [prop],
87                             message.format(prop, json_max_size),
88                         )
89                     )
90 
91         return matches
92 
93     def check(self, cfn, properties, specs, path):
94         """Check itself"""
95         matches = []
96         for p_value, p_path in properties.items_safe(path[:]):
97             for prop in p_value:
98                 if prop in specs:
99                     value = specs.get(prop).get('Value', {})
100                     if value:
101                         value_type = value.get('ValueType', '')
102                         primitive_type = specs.get(prop).get('PrimitiveType')
103                         if primitive_type == 'Json':
104                             matches.extend(
105                                 self.check_value(
106                                     p_value, p_path, prop, cfn,
107                                     RESOURCE_SPECS.get(cfn.regions[0]).get(
108                                         'ValueTypes').get(value_type, {})
109                                 )
110                             )
111         return matches
112 
113     def match_resource_sub_properties(self, properties, property_type, path, cfn):
114         """Match for sub properties"""
115         matches = list()
116 
117         specs = RESOURCE_SPECS.get(cfn.regions[0]).get(
118             'PropertyTypes').get(property_type, {}).get('Properties', {})
119         matches.extend(self.check(cfn, properties, specs, path))
120 
121         return matches
122 
123     def match_resource_properties(self, properties, resource_type, path, cfn):
124         """Check CloudFormation Properties"""
125         matches = list()
126 
127         specs = RESOURCE_SPECS.get(cfn.regions[0]).get(
128             'ResourceTypes').get(resource_type, {}).get('Properties', {})
129         matches.extend(self.check(cfn, properties, specs, path))
130 
131         return matches
132
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/cfnlint/rules/resources/properties/JsonSize.py b/src/cfnlint/rules/resources/properties/JsonSize.py
--- a/src/cfnlint/rules/resources/properties/JsonSize.py
+++ b/src/cfnlint/rules/resources/properties/JsonSize.py
@@ -36,6 +36,7 @@
         """Check Role.AssumeRolePolicyDocument is within limits"""
         matches = []
 
+        #pylint: disable=too-many-return-statements
         def remove_functions(obj):
             """ Replaces intrinsic functions with string """
             if isinstance(obj, dict):
@@ -48,6 +49,8 @@
                                     return re.sub(r'\${.*}', '', v)
                                 if isinstance(v, list):
                                     return re.sub(r'\${.*}', '', v[0])
+                            else:
+                                return ''
                         else:
                             new_obj[k] = remove_functions(v)
                             return new_obj

{"golden_diff": "diff --git a/src/cfnlint/rules/resources/properties/JsonSize.py b/src/cfnlint/rules/resources/properties/JsonSize.py\n--- a/src/cfnlint/rules/resources/properties/JsonSize.py\n+++ b/src/cfnlint/rules/resources/properties/JsonSize.py\n@@ -36,6 +36,7 @@\n         \"\"\"Check Role.AssumeRolePolicyDocument is within limits\"\"\"\n         matches = []\n \n+        #pylint: disable=too-many-return-statements\n         def remove_functions(obj):\n             \"\"\" Replaces intrinsic functions with string \"\"\"\n             if isinstance(obj, dict):\n@@ -48,6 +49,8 @@\n                                     return re.sub(r'\\${.*}', '', v)\n                                 if isinstance(v, list):\n                                     return re.sub(r'\\${.*}', '', v[0])\n+                            else:\n+                                return ''\n                         else:\n                             new_obj[k] = remove_functions(v)\n                             return new_obj\n", "issue": "Add correct size checking to IAM ManagedPolicy resource types\n*cfn-lint version: (cfn-lint 0.58.1)*\r\n\r\n*Description of issue.*\r\n\r\nThe PolicyDocument specified in an IAM Managed Policy has a maximum length of 6,144 characters (after converted to JSON and minified).\r\nhttps://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html\r\n\r\nWhen creating through CloudFormation an AWS::IAM::ManagedPolicy and using conditionals to leverage a 3 level environment creation differentiation, is throwing an error **E3502 PolicyDocument JSON text cannot be longer than 6144 characters**.\r\n\r\nThat happens because the policy defined in CloudFormation with the 3 level conditionals exceeds the 6144 characters limit, but when it is created it only uses 1 of the paths in the conditionals so the size is not really over 6144 characters.\r\n\r\nThis is the sample code in CloudFormation:\r\n```\r\n  ResourcePolicy:\r\n    Type: AWS::IAM::ManagedPolicy\r\n    Properties:\r\n      ManagedPolicyName: !Sub\r\n        - ResourcePolicy\r\n      PolicyDocument:\r\n        Version: '2012-10-17'\r\n        Statement:\r\n          - Sid: LambdaExecutionLogs\r\n            Effect: Allow\r\n            Action:\r\n              - logs:CreateLogGroup\r\n              - logs:CreateLogStream\r\n              - logs:PutLogEvents\r\n            Resource:\r\n              !Split\r\n                - \",\"\r\n                - !Join\r\n                    - \",\"\r\n                    - - !If\r\n                        - IsDev\r\n                        - !Join\r\n                          - \",\"\r\n                          - \r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdadev1-${EnvNameCamelCase}\r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdadev1-:*\r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdadev2\r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdadev2:*\r\n                        - !Ref AWS::NoValue\r\n                      - !If\r\n                        - IsUat\r\n                        - !Join\r\n                          - \",\"\r\n                          - \r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat1\r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat1:*\r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat2\r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat2:*\r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat3\r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdauat3:*\r\n                        - !Ref AWS::NoValue\r\n                      - !If\r\n                        - IsProd\r\n                        - !Join\r\n                          - \",\"\r\n                          - \r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdaprod\r\n                            - !Sub\r\n                              arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/lambdaprod:*\r\n                        - !Ref AWS::NoValue\r\n          - Sid: ........\r\n          . . .\r\n```\r\n\r\nSo the missing feature is to be able to check the size of the policy which is going to be finally created, not the source CloudFormation code, so in that regard it needs to evaluate the parameter and resolve the conditionals to end up with the final resource code to be created.\r\n\n", "before_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport datetime\nimport json\nimport re\nimport six\nimport cfnlint.helpers\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\nfrom cfnlint.helpers import RESOURCE_SPECS\n\n\nclass JsonSize(CloudFormationLintRule):\n    \"\"\"Check if JSON Object Size is within the specified length\"\"\"\n    id = 'E3502'\n    shortdesc = 'Check if a JSON Object is within size limits'\n    description = 'Validate properties that are JSON values so that their length is within the limits'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html'\n    tags = ['resources', 'limits', 'json']\n\n    def initialize(self, cfn):\n        \"\"\"Initialize the rule\"\"\"\n        for resource_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('ResourceTypes'):\n            self.resource_property_types.append(resource_type_spec)\n        for property_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('PropertyTypes'):\n            self.resource_sub_property_types.append(property_type_spec)\n\n    def _serialize_date(self, obj):\n        if isinstance(obj, datetime.date):\n            return obj.isoformat()\n        raise TypeError('Object of type {} is not JSON serializable'.format(obj.__class__.__name__))\n\n    def check_value(self, value, path, prop, cfn, specs):\n        \"\"\"Check Role.AssumeRolePolicyDocument is within limits\"\"\"\n        matches = []\n\n        def remove_functions(obj):\n            \"\"\" Replaces intrinsic functions with string \"\"\"\n            if isinstance(obj, dict):\n                new_obj = {}\n                if len(obj) == 1:\n                    for k, v in obj.items():\n                        if k in cfnlint.helpers.FUNCTIONS:\n                            if k == 'Fn::Sub':\n                                if isinstance(v, six.string_types):\n                                    return re.sub(r'\\${.*}', '', v)\n                                if isinstance(v, list):\n                                    return re.sub(r'\\${.*}', '', v[0])\n                        else:\n                            new_obj[k] = remove_functions(v)\n                            return new_obj\n                else:\n                    for k, v in obj.items():\n                        new_obj[k] = remove_functions(v)\n                    return new_obj\n            elif isinstance(obj, list):\n                new_list = []\n                for v in obj:\n                    new_list.append(remove_functions(v))\n                return new_list\n\n            return obj\n\n        scenarios = cfn.get_object_without_nested_conditions(value, path)\n        json_max_size = specs.get('JsonMax')\n        for scenario in scenarios:\n            j = remove_functions(scenario['Object'][prop])\n            if isinstance(j, six.string_types):\n                try:\n                    j = json.loads(j)\n                except:  #pylint: disable=bare-except\n                    continue\n            if len(json.dumps(j, separators=(',', ':'), default=self._serialize_date)) > json_max_size:\n                if scenario['Scenario']:\n                    message = '{0} JSON text cannot be longer than {1} characters when {2}'\n                    scenario_text = ' and '.join(['when condition \"%s\" is %s' % (\n                        k, v) for (k, v) in scenario['Scenario'].items()])\n                    matches.append(\n                        RuleMatch(path + [prop], message.format(prop, json_max_size, scenario_text)))\n                else:\n                    message = '{0} JSON text cannot be longer than {1} characters'\n                    matches.append(\n                        RuleMatch(\n                            path + [prop],\n                            message.format(prop, json_max_size),\n                        )\n                    )\n\n        return matches\n\n    def check(self, cfn, properties, specs, path):\n        \"\"\"Check itself\"\"\"\n        matches = []\n        for p_value, p_path in properties.items_safe(path[:]):\n            for prop in p_value:\n                if prop in specs:\n                    value = specs.get(prop).get('Value', {})\n                    if value:\n                        value_type = value.get('ValueType', '')\n                        primitive_type = specs.get(prop).get('PrimitiveType')\n                        if primitive_type == 'Json':\n                            matches.extend(\n                                self.check_value(\n                                    p_value, p_path, prop, cfn,\n                                    RESOURCE_SPECS.get(cfn.regions[0]).get(\n                                        'ValueTypes').get(value_type, {})\n                                )\n                            )\n        return matches\n\n    def match_resource_sub_properties(self, properties, property_type, path, cfn):\n        \"\"\"Match for sub properties\"\"\"\n        matches = list()\n\n        specs = RESOURCE_SPECS.get(cfn.regions[0]).get(\n            'PropertyTypes').get(property_type, {}).get('Properties', {})\n        matches.extend(self.check(cfn, properties, specs, path))\n\n        return matches\n\n    def match_resource_properties(self, properties, resource_type, path, cfn):\n        \"\"\"Check CloudFormation Properties\"\"\"\n        matches = list()\n\n        specs = RESOURCE_SPECS.get(cfn.regions[0]).get(\n            'ResourceTypes').get(resource_type, {}).get('Properties', {})\n        matches.extend(self.check(cfn, properties, specs, path))\n\n        return matches\n", "path": "src/cfnlint/rules/resources/properties/JsonSize.py"}], "after_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport datetime\nimport json\nimport re\nimport six\nimport cfnlint.helpers\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\nfrom cfnlint.helpers import RESOURCE_SPECS\n\n\nclass JsonSize(CloudFormationLintRule):\n    \"\"\"Check if JSON Object Size is within the specified length\"\"\"\n    id = 'E3502'\n    shortdesc = 'Check if a JSON Object is within size limits'\n    description = 'Validate properties that are JSON values so that their length is within the limits'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html'\n    tags = ['resources', 'limits', 'json']\n\n    def initialize(self, cfn):\n        \"\"\"Initialize the rule\"\"\"\n        for resource_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('ResourceTypes'):\n            self.resource_property_types.append(resource_type_spec)\n        for property_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('PropertyTypes'):\n            self.resource_sub_property_types.append(property_type_spec)\n\n    def _serialize_date(self, obj):\n        if isinstance(obj, datetime.date):\n            return obj.isoformat()\n        raise TypeError('Object of type {} is not JSON serializable'.format(obj.__class__.__name__))\n\n    def check_value(self, value, path, prop, cfn, specs):\n        \"\"\"Check Role.AssumeRolePolicyDocument is within limits\"\"\"\n        matches = []\n\n        #pylint: disable=too-many-return-statements\n        def remove_functions(obj):\n            \"\"\" Replaces intrinsic functions with string \"\"\"\n            if isinstance(obj, dict):\n                new_obj = {}\n                if len(obj) == 1:\n                    for k, v in obj.items():\n                        if k in cfnlint.helpers.FUNCTIONS:\n                            if k == 'Fn::Sub':\n                                if isinstance(v, six.string_types):\n                                    return re.sub(r'\\${.*}', '', v)\n                                if isinstance(v, list):\n                                    return re.sub(r'\\${.*}', '', v[0])\n                            else:\n                                return ''\n                        else:\n                            new_obj[k] = remove_functions(v)\n                            return new_obj\n                else:\n                    for k, v in obj.items():\n                        new_obj[k] = remove_functions(v)\n                    return new_obj\n            elif isinstance(obj, list):\n                new_list = []\n                for v in obj:\n                    new_list.append(remove_functions(v))\n                return new_list\n\n            return obj\n\n        scenarios = cfn.get_object_without_nested_conditions(value, path)\n        json_max_size = specs.get('JsonMax')\n        for scenario in scenarios:\n            j = remove_functions(scenario['Object'][prop])\n            if isinstance(j, six.string_types):\n                try:\n                    j = json.loads(j)\n                except:  #pylint: disable=bare-except\n                    continue\n            if len(json.dumps(j, separators=(',', ':'), default=self._serialize_date)) > json_max_size:\n                if scenario['Scenario']:\n                    message = '{0} JSON text cannot be longer than {1} characters when {2}'\n                    scenario_text = ' and '.join(['when condition \"%s\" is %s' % (\n                        k, v) for (k, v) in scenario['Scenario'].items()])\n                    matches.append(\n                        RuleMatch(path + [prop], message.format(prop, json_max_size, scenario_text)))\n                else:\n                    message = '{0} JSON text cannot be longer than {1} characters'\n                    matches.append(\n                        RuleMatch(\n                            path + [prop],\n                            message.format(prop, json_max_size),\n                        )\n                    )\n\n        return matches\n\n    def check(self, cfn, properties, specs, path):\n        \"\"\"Check itself\"\"\"\n        matches = []\n        for p_value, p_path in properties.items_safe(path[:]):\n            for prop in p_value:\n                if prop in specs:\n                    value = specs.get(prop).get('Value', {})\n                    if value:\n                        value_type = value.get('ValueType', '')\n                        primitive_type = specs.get(prop).get('PrimitiveType')\n                        if primitive_type == 'Json':\n                            matches.extend(\n                                self.check_value(\n                                    p_value, p_path, prop, cfn,\n                                    RESOURCE_SPECS.get(cfn.regions[0]).get(\n                                        'ValueTypes').get(value_type, {})\n                                )\n                            )\n        return matches\n\n    def match_resource_sub_properties(self, properties, property_type, path, cfn):\n        \"\"\"Match for sub properties\"\"\"\n        matches = list()\n\n        specs = RESOURCE_SPECS.get(cfn.regions[0]).get(\n            'PropertyTypes').get(property_type, {}).get('Properties', {})\n        matches.extend(self.check(cfn, properties, specs, path))\n\n        return matches\n\n    def match_resource_properties(self, properties, resource_type, path, cfn):\n        \"\"\"Check CloudFormation Properties\"\"\"\n        matches = list()\n\n        specs = RESOURCE_SPECS.get(cfn.regions[0]).get(\n            'ResourceTypes').get(resource_type, {}).get('Properties', {})\n        matches.extend(self.check(cfn, properties, specs, path))\n\n        return matches\n", "path": "src/cfnlint/rules/resources/properties/JsonSize.py"}]}