Repository: aws-cloudformation/cfn-lint

Issue:
typo not being caught in Stack Parameters
### CloudFormation Lint Version

0.67.0

### What operating system are you using?

WSL2

### Describe the bug

Type is not getting caught inside stack parameters:

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Typo not caught by cfn-lint'

Parameters:
  WakandaBucket:
    Type: String
    Description: Something.

Resources:
  WakandaStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: "https://somewhere/foo.yaml"
      Parameters:
        Foobar: !Red WakandaBucket

  Wakanda4EverBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref WakandaBucket
```

>Note that after Foobar comes `!Red` insead of `!Ref`.

cfn-lint output for above template is empty, exitcode 0.

When I change the BucketName !Ref to !Red, that one gives me a proper error. But not for the Stack Parameters.

### Expected behavior

I expect something like `Property X/Y/Z has an illegal function Fn::Red`

### Reproduction template

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Typo not caught by cfn-lint'

Parameters:
  WakandaBucket:
    Type: String
    Description: Something.

Resources:
  WakandaStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: "https://somewhere/foo.yaml"
      Parameters:
        Foobar: !Red WakandaBucket

  Wakanda4EverBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref WakandaBucket
```


Discussion:
reproduced with another property-type that was also a map of strings as well

Resolving patch:
diff --git a/src/cfnlint/rules/resources/properties/ValuePrimitiveType.py b/src/cfnlint/rules/resources/properties/ValuePrimitiveType.py
--- a/src/cfnlint/rules/resources/properties/ValuePrimitiveType.py
+++ b/src/cfnlint/rules/resources/properties/ValuePrimitiveType.py
@@ -162,6 +162,26 @@ def check_value(self, value, path, **kwargs):
                                 strict_check,
                             )
                         )
+                    else:
+                        # types that represent a singular value (not json)
+                        cfnlint.helpers.FUNCTIONS_SINGLE.sort()
+                        if primitive_type in ['String', 'Boolean', 'Integer', 'Double']:
+                            if len(map_value) != 1:
+                                matches.append(
+                                    RuleMatch(
+                                        path,
+                                        f'Use a valid function [{", ".join(cfnlint.helpers.FUNCTIONS_SINGLE)}] when providing a value of type [{primitive_type}]',
+                                    )
+                                )
+                            else:
+                                for k in map_value.keys():
+                                    if k not in cfnlint.helpers.FUNCTIONS_SINGLE:
+                                        matches.append(
+                                            RuleMatch(
+                                                path,
+                                                f'Use a valid function [{", ".join(cfnlint.helpers.FUNCTIONS_SINGLE)}] when providing a value of type [{primitive_type}]',
+                                            )
+                                        )
         else:
             # some properties support primitive types and objects
             # skip in the case it could be an object and the value is a object


Test patch:
diff --git a/test/unit/rules/resources/properties/test_value_primitive_type.py b/test/unit/rules/resources/properties/test_value_primitive_type.py
--- a/test/unit/rules/resources/properties/test_value_primitive_type.py
+++ b/test/unit/rules/resources/properties/test_value_primitive_type.py
@@ -104,3 +104,42 @@ def test_file_positive(self):
         self.assertEqual(len(self.rule._value_check(1, ['test'], 'Unknown', False, {})), 0)
         self.assertEqual(len(self.rule._value_check('1', ['test'], 'Unknown', False, {})), 0)
         self.assertEqual(len(self.rule._value_check(True, ['test'], 'Unknown', False, {})), 0)
+
+class TestResourceValuePrimitiveTypeCheckValue(BaseRuleTestCase):
+    """Test Check Value for maps"""
+
+    def setUp(self):
+        """Setup"""
+        self.rule = ValuePrimitiveType()
+        self.rule.config['strict'] = False
+
+    def test_file_check_value_good_function(self):
+        results = self.rule.check_value({'key': {'Ref': ['Parameter']}}, [], primitive_type='String', item_type='Map')
+        self.assertEqual(len(results), 0)
+    
+    def test_file_check_value_is_string(self):
+        results = self.rule.check_value({'key': 1}, [], primitive_type='Integer', item_type='Map')
+        self.assertEqual(len(results), 0)
+
+    def test_file_check_value_is_json(self):
+        results = self.rule.check_value({'key': {}}, [], primitive_type='Json', item_type='Map')
+        self.assertEqual(len(results), 0)
+
+    def test_file_check_value_bad_function(self):
+        results = self.rule.check_value({'key': {'Func': ['Parameter']}}, [], primitive_type='Boolean', item_type='Map')
+        self.assertEqual(len(results), 1)
+        self.assertEqual(results[0].message, 'Use a valid function [Fn::Base64, Fn::Cidr, Fn::Contains, '
+            'Fn::FindInMap, Fn::GetAtt, Fn::If, Fn::ImportValue, Fn::Join, Fn::Length, '
+            'Fn::Select, Fn::Sub, Fn::ToJsonString, Ref] when '
+            'providing a value of type [Boolean]')
+    
+    def test_file_check_value_bad_object(self):
+        results = self.rule.check_value({'key': {'Func': ['Parameter'], 'Func2': ['Parameter']}}, [], primitive_type='String', item_type='Map')
+        self.assertEqual(len(results), 1)
+        self.assertEqual(results[0].message, 'Use a valid function [Fn::Base64, Fn::Cidr, Fn::Contains, '
+            'Fn::FindInMap, Fn::GetAtt, Fn::If, Fn::ImportValue, Fn::Join, Fn::Length, '
+            'Fn::Select, Fn::Sub, Fn::ToJsonString, Ref] when '
+            'providing a value of type [String]')
+    
+
+