From ed61747f328ff6aa343881b269600308ab8eac93 Mon Sep 17 00:00:00 2001
From: Narpat Mali <narpat.mali@windriver.com>
Date: Wed, 6 Sep 2023 10:32:38 +0000
Subject: [PATCH] Improve the Smithy metadata matcher.

Previously, metadata foo bar baz = 23 was accepted, but according to
the definition https://smithy.io/2.0/spec/idl.html#grammar-token-smithy-MetadataSection
it should be "metadata"<whitespace>Identifier/String<optional whitespace>.

CVE: CVE-2022-40896

Upstream-Status: Backport [https://github.com/pygments/pygments/commit/dd52102c38ebe78cd57748e09f38929fd283ad04]

Signed-off-by: Narpat Mali <narpat.mali@windriver.com>
---
 pygments/lexers/smithy.py                    |  5 +-
 tests/examplefiles/smithy/test.smithy        | 12 +++++
 tests/examplefiles/smithy/test.smithy.output | 52 ++++++++++++++++++++
 3 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/pygments/lexers/smithy.py b/pygments/lexers/smithy.py
index 0f0a912..c5e25cd 100644
--- a/pygments/lexers/smithy.py
+++ b/pygments/lexers/smithy.py
@@ -58,8 +58,9 @@ class SmithyLexer(RegexLexer):
             (words(aggregate_shapes,
                    prefix=r'^', suffix=r'(\s+' + identifier + r')'),
                 bygroups(Keyword.Declaration, Name.Class)),
-            (r'^(metadata)(\s+.+)(\s*)(=)',
-                bygroups(Keyword.Declaration, Name.Class, Whitespace, Name.Decorator)),
+            (r'^(metadata)(\s+)((?:\S+)|(?:\"[^"]+\"))(\s*)(=)',
+                bygroups(Keyword.Declaration, Whitespace, Name.Class,
+                         Whitespace, Name.Decorator)),
             (r"(true|false|null)", Keyword.Constant),
             (r"(-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)", Number),
             (identifier + ":", Name.Label),
diff --git a/tests/examplefiles/smithy/test.smithy b/tests/examplefiles/smithy/test.smithy
index 3d20f06..9317fee 100644
--- a/tests/examplefiles/smithy/test.smithy
+++ b/tests/examplefiles/smithy/test.smithy
@@ -2,6 +2,18 @@ $version: "1.0"

 namespace test

+metadata "foo" = ["bar", "baz"]
+metadata validators = [
+    {
+        name: "ValidatorName"
+        id: "ValidatorId"
+        message: "Some string"
+        configuration: {
+            selector: "operation"
+        }
+    }
+]
+
 /// Define how an HTTP request is serialized given a specific protocol,
 /// authentication scheme, and set of input parameters.
 @trait(selector: "operation")
diff --git a/tests/examplefiles/smithy/test.smithy.output b/tests/examplefiles/smithy/test.smithy.output
index 1f22489..db44a38 100644
--- a/tests/examplefiles/smithy/test.smithy.output
+++ b/tests/examplefiles/smithy/test.smithy.output
@@ -7,6 +7,58 @@
 ' test'       Name.Class
 '\n\n'        Text.Whitespace

+'metadata'    Keyword.Declaration
+' '           Text.Whitespace
+'"foo"'       Name.Class
+' '           Text.Whitespace
+'='           Name.Decorator
+' '           Text.Whitespace
+'['           Text
+'"bar"'       Literal.String.Double
+','           Punctuation
+' '           Text.Whitespace
+'"baz"'       Literal.String.Double
+']'           Text
+'\n'          Text.Whitespace
+
+'metadata'    Keyword.Declaration
+' '           Text.Whitespace
+'validators'  Name.Class
+' '           Text.Whitespace
+'='           Name.Decorator
+' '           Text.Whitespace
+'['           Text
+'\n    '      Text.Whitespace
+'{'           Text
+'\n        '  Text.Whitespace
+'name:'       Name.Label
+' '           Text.Whitespace
+'"ValidatorName"' Literal.String.Double
+'\n        '  Text.Whitespace
+'id:'         Name.Label
+' '           Text.Whitespace
+'"ValidatorId"' Literal.String.Double
+'\n        '  Text.Whitespace
+'message:'    Name.Label
+' '           Text.Whitespace
+'"Some string"' Literal.String.Double
+'\n        '  Text.Whitespace
+'configuration:' Name.Label
+' '           Text.Whitespace
+'{'           Text
+'\n            ' Text.Whitespace
+'selector:'   Name.Label
+' '           Text.Whitespace
+'"operation"' Literal.String.Double
+'\n        '  Text.Whitespace
+'}'           Text
+'\n    '      Text.Whitespace
+'}'           Text
+'\n'          Text.Whitespace
+
+']'           Text
+'\n\n'        Text.Whitespace
+
 '/// Define how an HTTP request is serialized given a specific protocol,' Comment.Multiline
 '\n'          Text.Whitespace

--
2.40.0
