From 668ded8f26af3124b26f4839dec8d7c446927944 Mon Sep 17 00:00:00 2001
From: Henrique <999396+hjgraca@users.noreply.github.com>
Date: Fri, 31 Jan 2025 15:59:19 +0000
Subject: [PATCH 1/2] Sanitize SegmentName. Show accepted chars in the
SegmentName. Add tests
---
.../Internal/Helpers.cs | 23 +++++++++++++++++++
.../Internal/XRayRecorder.cs | 4 +++-
.../TracingAttribute.cs | 5 ++--
.../Handlers/Handlers.cs | 12 ++++++++++
.../TracingAttributeTest.cs | 22 ++++++++++++++++++
5 files changed, 63 insertions(+), 3 deletions(-)
create mode 100644 libraries/src/AWS.Lambda.Powertools.Tracing/Internal/Helpers.cs
diff --git a/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/Helpers.cs b/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/Helpers.cs
new file mode 100644
index 000000000..22b53e4be
--- /dev/null
+++ b/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/Helpers.cs
@@ -0,0 +1,23 @@
+using System.Text.RegularExpressions;
+
+namespace AWS.Lambda.Powertools.Tracing.Internal;
+
+///
+/// Helper class
+///
+public static class Helpers
+{
+ ///
+ /// Sanitize a string by removing any characters that are not alphanumeric, whitespace, or one of the following: _ . : / % & # = + - @
+ ///
+ ///
+ ///
+ public static string SanitizeString(string input)
+ {
+ // Define a regular expression pattern to match allowed characters
+ var pattern = @"[^a-zA-Z0-9\s_\.\:/%=+\-@]";
+
+ // Replace any character that does not match the pattern with an empty string
+ return Regex.Replace(input, pattern, string.Empty);
+ }
+}
\ No newline at end of file
diff --git a/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/XRayRecorder.cs b/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/XRayRecorder.cs
index e192036ee..53bface31 100644
--- a/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/XRayRecorder.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/XRayRecorder.cs
@@ -78,7 +78,9 @@ public XRayRecorder(IAWSXRayRecorder awsxRayRecorder, IPowertoolsConfigurations
public void BeginSubsegment(string name)
{
if (_isLambda)
- _awsxRayRecorder.BeginSubsegment(name);
+ {
+ _awsxRayRecorder.BeginSubsegment(Helpers.SanitizeString(name));
+ }
}
///
diff --git a/libraries/src/AWS.Lambda.Powertools.Tracing/TracingAttribute.cs b/libraries/src/AWS.Lambda.Powertools.Tracing/TracingAttribute.cs
index 1946fb9c2..c144d0387 100644
--- a/libraries/src/AWS.Lambda.Powertools.Tracing/TracingAttribute.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Tracing/TracingAttribute.cs
@@ -15,7 +15,6 @@
using System;
using AspectInjector.Broker;
-using AWS.Lambda.Powertools.Common;
using AWS.Lambda.Powertools.Tracing.Internal;
namespace AWS.Lambda.Powertools.Tracing;
@@ -114,8 +113,10 @@ public class TracingAttribute : Attribute
///
/// Set custom segment name for the operation.
/// The default is '## {MethodName}'.
+ ///
+ /// The logical name of the service that handled the request, up to 200 characters.
+ /// Names can contain Unicode letters, numbers, and whitespace, and the following symbols: \_, ., :, /, %, &, #, =, +, \\, -, @
///
- /// The name of the segment.
public string SegmentName { get; set; } = "";
///
diff --git a/libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/Handlers/Handlers.cs b/libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/Handlers/Handlers.cs
index 385ce96c1..38210ac92 100644
--- a/libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/Handlers/Handlers.cs
+++ b/libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/Handlers/Handlers.cs
@@ -31,6 +31,18 @@ public void HandleWithSegmentName()
}
+ [Tracing(SegmentName = "## <$>g__Handler|0_0")]
+ public void HandleWithInvalidSegmentName()
+ {
+ MethodWithInvalidSegmentName();
+ }
+
+ [Tracing(SegmentName = "Inval$#id | ")]
+ private void MethodWithInvalidSegmentName()
+ {
+
+ }
+
[Tracing(Namespace = "Namespace Defined")]
public void HandleWithNamespace()
{
diff --git a/libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/TracingAttributeTest.cs b/libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/TracingAttributeTest.cs
index 58252d67c..f02619c1f 100644
--- a/libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/TracingAttributeTest.cs
+++ b/libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/TracingAttributeTest.cs
@@ -256,6 +256,28 @@ public void OnEntry_WhenSegmentNameHasValue_BeginSubsegmentWithValue()
Assert.Single(segment.Subsegments);
Assert.Equal("SegmentName", subSegment.Name);
}
+
+ [Fact]
+ public void OnEntry_WhenSegmentName_Is_Unsupported()
+ {
+ // Arrange
+ Environment.SetEnvironmentVariable("LAMBDA_TASK_ROOT", "AWS");
+ Environment.SetEnvironmentVariable("POWERTOOLS_SERVICE_NAME", "POWERTOOLS");
+
+ // Act
+ var segment = AWSXRayRecorder.Instance.TraceContext.GetEntity();
+ _handler.HandleWithInvalidSegmentName();
+ var subSegment = segment.Subsegments[0];
+ var childSegment = subSegment.Subsegments[0];
+
+ // Assert
+ Assert.True(segment.IsSubsegmentsAdded);
+ Assert.True(subSegment.IsSubsegmentsAdded);
+ Assert.Single(segment.Subsegments);
+ Assert.Single(subSegment.Subsegments);
+ Assert.Equal("## Maing__Handler0_0", subSegment.Name);
+ Assert.Equal("Inval#id Segment", childSegment.Name);
+ }
[Fact]
public void OnEntry_WhenNamespaceIsNull_SetNamespaceWithService()
From 284834c6e58455b4a93dfe6ab2dcd13327d42def Mon Sep 17 00:00:00 2001
From: Henrique <999396+hjgraca@users.noreply.github.com>
Date: Fri, 31 Jan 2025 16:22:26 +0000
Subject: [PATCH 2/2] fix sonar, add timeout to regex
---
.../src/AWS.Lambda.Powertools.Tracing/Internal/Helpers.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/Helpers.cs b/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/Helpers.cs
index 22b53e4be..f124852dd 100644
--- a/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/Helpers.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Tracing/Internal/Helpers.cs
@@ -1,3 +1,4 @@
+using System;
using System.Text.RegularExpressions;
namespace AWS.Lambda.Powertools.Tracing.Internal;
@@ -17,7 +18,7 @@ public static string SanitizeString(string input)
// Define a regular expression pattern to match allowed characters
var pattern = @"[^a-zA-Z0-9\s_\.\:/%=+\-@]";
- // Replace any character that does not match the pattern with an empty string
- return Regex.Replace(input, pattern, string.Empty);
+ // Replace any character that does not match the pattern with an empty string, with a timeout
+ return Regex.Replace(input, pattern, string.Empty, RegexOptions.None, TimeSpan.FromMilliseconds(100));
}
}
\ No newline at end of file