Repository: aws-cloudformation/cfn-lint

Issue:
E0002: Unknown exception while processing rule E1024: 'list' object has no attribute 'path'
### CloudFormation Lint Version

cfn-lint 0.77.10

### What operating system are you using?

Mac

### Describe the bug

When validation checks run on a the Cidr function `!Cidr [ ipBlock, count, cidrBits ]`, the count and cidrBits doesn't validate more complex functions like the `!If` in the example.

### Expected behavior

Doesn't throw unknown exception

### Reproduction template

```yaml
PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs ""]
      CidrBlock: !If
        - defineYourOwnSubnetCIDR
        - !Ref FirstTierSubnet1CIDR
        - !Select
          - 0
          - !Cidr
            - 10.0.0.0/24
            - !If [3AZ, 16, 8]
            - 4
```


Discussion:
Found the issue and working to correct it.

Resolving patch:
diff --git a/src/cfnlint/rules/functions/Cidr.py b/src/cfnlint/rules/functions/Cidr.py
--- a/src/cfnlint/rules/functions/Cidr.py
+++ b/src/cfnlint/rules/functions/Cidr.py
@@ -49,7 +49,10 @@ def check_ip_block(self, value, path):
                                     )
                                 )
                         else:
-                            message = "Cidr ipBlock should be Cidr Range, Ref, GetAtt, Sub or Select for {0}"
+                            message = (
+                                "Cidr ipBlock should be Cidr Range, Ref, GetAtt, Sub or"
+                                " Select for {0}"
+                            )
                             matches.append(
                                 RuleMatch(
                                     path, message.format("/".join(map(str, value)))
@@ -78,18 +81,16 @@ def check_count(self, value, path):
                             if len(value.get("Fn::If")) == 3 and isinstance(
                                 value.get("Fn::If"), list
                             ):
-                                matches.extend(
-                                    self.check_count(
-                                        value.get("Fn::If")[1],
-                                        path=path[:] + [index_key, 1],
-                                    )
-                                )
-                                matches.extend(
-                                    self.check_count(
-                                        value.get("Fn::If")[2],
-                                        path=path[:] + [index_key, 2],
+                                for i in [1, 2]:
+                                    (
+                                        new_count_parameters,
+                                        new_matches,
+                                    ) = self.check_count(
+                                        value.get("Fn::If")[i],
+                                        path=path[:] + [index_key, i],
                                     )
-                                )
+                                    count_parameters.extend(new_count_parameters)
+                                    matches.extend(new_matches)
                         else:
                             message = "Cidr count should be Int, Ref, or Select for {0}"
                             matches.append(
@@ -168,7 +169,10 @@ def check_parameter_count(self, cfn, parameter_name):
                 max_value = parameter_obj.get("MaxValue")
                 min_value = parameter_obj.get("MinValue")
                 if (not min_value) or min_value < 1 or min_value > 256:
-                    message = "Parameter for Cidr count have MinValue between 1 and 256 at {0}"
+                    message = (
+                        "Parameter for Cidr count have MinValue between 1 and 256"
+                        " at {0}"
+                    )
                     matches.append(
                         RuleMatch(
                             tree + ["MinValue"],
@@ -176,7 +180,10 @@ def check_parameter_count(self, cfn, parameter_name):
                         )
                     )
                 if (not max_value) or max_value < 1 or max_value > 256:
-                    message = "Parameter for Cidr count have MaxValue between 1 and 256 at {0}"
+                    message = (
+                        "Parameter for Cidr count have MaxValue between 1 and 256"
+                        " at {0}"
+                    )
                     matches.append(
                         RuleMatch(
                             tree + ["MaxValue"],
@@ -258,7 +265,6 @@ def match(self, cfn):
                     )
                     count_parameters.extend(new_count_parameters)
                     matches.extend(new_matches)
-
                     new_size_mask_parameters, new_matches = self.check_size_mask(
                         size_mask_obj, tree[:] + [2]
                     )


Test patch:
diff --git a/test/fixtures/templates/good/functions/cidr.yaml b/test/fixtures/templates/good/functions/cidr.yaml
--- a/test/fixtures/templates/good/functions/cidr.yaml
+++ b/test/fixtures/templates/good/functions/cidr.yaml
@@ -13,6 +13,8 @@ Parameters:
     MaxValue: 6
   Size:
     Type: String
+  FirstTierSubnet1CIDR:
+    Type: String
 Mappings:
   CidrBitsMap:
     "2":
@@ -55,7 +57,7 @@ Resources:
                       - 8
                   - Fn::Select:
                     - 15
-                    - Fn::Cidr: 
+                    - Fn::Cidr:
                       - Fn::GetAtt: MyVPC.CidrBlock
                       - 16
                       - 8
@@ -64,3 +66,17 @@ Resources:
             - 2
             - 4
         VpcId: 'vpc-123456'
+  PublicSubnet1:
+    Type: AWS::EC2::Subnet
+    Properties:
+      VpcId: !Ref MyVPC
+      AvailabilityZone: !Select [0, !GetAZs ""]
+      CidrBlock: !If
+          - IsProd
+          - !Ref FirstTierSubnet1CIDR
+          - !Select
+            - 0
+            - !Cidr
+              - 10.0.0.0/24
+              - !If [IsProd, 16, 8]
+              - 4