Repository: aws-cloudformation/cfn-lint

Issue:
False alarm -  E8003 Every Fn::Equals object requires a list of 2 string parameters
*cfn-lint version: 0.42.0*

*Description of issue.*

Please provide as much information as possible:

cfn-lint is showing a false alarm for the check E8003 when you use conditional with Equals and Ref function and the **previous parameter** listed in the template is a List type.

I've checked and it seems to be related to the file https://github.com/aws-cloudformation/cfn-python-lint/blob/master/src/cfnlint/rules/conditions/Equals.py#L39 on line 39 which uses `valid_refs[element_value].get('Type')` method to get the parameter type, but for some reason, this is returning the type of the previous parameter. When switching to `valid_refs.get(element_value).get('Type')`  the validation works as expected.

You can use the following template to test:

```yaml
---

AWSTemplateFormatVersion: "2010-09-09"
Parameters:

  CreatePolicy:
    Type: String
    Default: 'true'
    Description: "Create IAM policy"
    AllowedValues:
    - 'false'
    - 'true'

  IAMArn:
    Type: "CommaDelimitedList"
    Description: The Cross account IAM having access on the repository
    Default: "None"

  IAMArnAllowWrite:
    Type: String
    Default: 'false'
    Description: "Allow IAM writer policy"
    AllowedValues:
    - 'false'
    - 'true'

Conditions: 
  ShouldCreatePolicy: !Equals [!Ref CreatePolicy, 'true']
  ShouldAllowWritePolicy: !Equals [!Ref IAMArnAllowWrite, 'true']

Resources:

  ECRRepositry:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryPolicyText:
        Fn::If:
        - ShouldCreatePolicy
        - 
          Version: "2012-10-17"
          Statement:
            -
              Sid: AllowPushPull
              Effect: Allow
              Principal:
                AWS: !Ref IAMArn
              Action:
                Fn::If:
                - ShouldAllowWritePolicy
                - - "ecr:GetDownloadUrlForLayer"
                  - "ecr:BatchGetImage"
                  - "ecr:PutImage"
                  - "ecr:BatchCheckLayerAvailability"
                  - "ecr:InitiateLayerUpload"
                  - "ecr:UploadLayerPart"
                  - "ecr:CompleteLayerUpload"
                - - "ecr:GetDownloadUrlForLayer"
                  - "ecr:BatchGetImage"
        - Ref: AWS::NoValue
```
Executing the test:
```shell
$ cfn-lint -c E8003  -t template.yaml
E8003 Every Fn::Equals object requires a list of 2 string parameters
template.yaml:29:36
```

If you change the type from IAMArn to String, it will work as intended.



Discussion:
It seems to be related to the naming used there, if I change IAMArnAllowWrite to BAR, for example, it works as expected.
It's caused by the regex match from https://github.com/aws-cloudformation/cfn-python-lint/pull/1801.

Because of module support, cfn-lint is looking in comparing IAMArnAllowWrite with all Refable resources, to see if a module could have created `IAMArnAllowWrite`, a module named `IAMArn` could have been that module, so the properties of that resource are returned instead of the one from IAMArnAllowWrite, If you switch the order of the parameters the error disappears, because another resources is matched first.

----
On a related note, If I understand the behaviour correctly, I think the matcher should do a startswith instead of a regex.match

Resolving patch:
diff --git a/src/cfnlint/helpers.py b/src/cfnlint/helpers.py
--- a/src/cfnlint/helpers.py
+++ b/src/cfnlint/helpers.py
@@ -204,10 +204,11 @@
 class RegexDict(dict):
 
     def __getitem__(self, item):
-        for k, v in self.items():
-            if re.match(k, item):
-                return v
-        raise KeyError
+        possible_items = {k: v for k, v in self.items() if re.match(k, item)}
+        if not possible_items:
+            raise KeyError
+        longest_match = sorted(possible_items.keys(), key=len)[-1]
+        return possible_items[longest_match]
 
     def __contains__(self, item):
         for k in self.keys():


Test patch: