Skip to content

Bug: Flaky test due to json escaping when plus sign present #201

@hjgraca

Description

@hjgraca

Expected Behaviour

Relaxed escaping of json encoded strings. should allow characters such as plus sign '+' to go through unescaped.

Current Behaviour

Currently the plus sign is escaped and transformed into "\u002B". This is not the expected behaviour because it will break bas64 encoding/decoding

Code snippet

The bellow test reproduces the bug when the UnsafeRelaxedJsonEscaping is not enabled

[Fact]
        public void Log_WhenMemoryStream_LogsBase64String_UnsafeRelaxedJsonEscaping()
        {
            // Arrange
            var loggerName = Guid.NewGuid().ToString();
            var service = Guid.NewGuid().ToString();
            
            // This will produce the encoded string dW5zYWZlIHN0cmluZyB+IHRlc3Q= (which has a plus sign to test unsafe escaping)
            var bytes = Encoding.UTF8.GetBytes("unsafe string ~ test");

            var memoryStream = new MemoryStream(bytes) 
            {
                Position = 0
            };
            var logLevel = LogLevel.Information;
            var randomSampleRate = 0.5;

            var configurations = new Mock<IPowertoolsConfigurations>();
            configurations.Setup(c => c.Service).Returns(service);
            configurations.Setup(c => c.LogLevel).Returns(logLevel.ToString);

            var systemWrapper = new Mock<ISystemWrapper>();
            systemWrapper.Setup(c => c.GetRandom()).Returns(randomSampleRate);            

            var logger = new PowertoolsLogger(loggerName, configurations.Object, systemWrapper.Object, () =>
                new LoggerConfiguration
                {                     
                    Service = null,
                    MinimumLevel = null
                });

            // Act
            logger.LogInformation(new { Name = "Test Object", Stream = memoryStream });
            
            // Assert
            systemWrapper.Verify(v =>
                v.LogLine(
                    It.Is<string>
                    (s =>
                        s.Contains("\"stream\":\"" + Convert.ToBase64String(bytes) + "\"")
                    )
                ), Times.Once);
        }

Possible Solution

Add the following to BuildJsonSerializerOptions

jsonOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;

Steps to Reproduce

[Fact]
        public void Log_WhenMemoryStream_LogsBase64String_UnsafeRelaxedJsonEscaping()
        {
            // Arrange
            var loggerName = Guid.NewGuid().ToString();
            var service = Guid.NewGuid().ToString();
            
            // This will produce the encoded string dW5zYWZlIHN0cmluZyB+IHRlc3Q= (which has a plus sign to test unsafe escaping)
            var bytes = Encoding.UTF8.GetBytes("unsafe string ~ test");

            var memoryStream = new MemoryStream(bytes) 
            {
                Position = 0
            };
            var logLevel = LogLevel.Information;
            var randomSampleRate = 0.5;

            var configurations = new Mock<IPowertoolsConfigurations>();
            configurations.Setup(c => c.Service).Returns(service);
            configurations.Setup(c => c.LogLevel).Returns(logLevel.ToString);

            var systemWrapper = new Mock<ISystemWrapper>();
            systemWrapper.Setup(c => c.GetRandom()).Returns(randomSampleRate);            

            var logger = new PowertoolsLogger(loggerName, configurations.Object, systemWrapper.Object, () =>
                new LoggerConfiguration
                {                     
                    Service = null,
                    MinimumLevel = null
                });

            // Act
            logger.LogInformation(new { Name = "Test Object", Stream = memoryStream });
            
            // Assert
            systemWrapper.Verify(v =>
                v.LogLine(
                    It.Is<string>
                    (s =>
                        s.Contains("\"stream\":\"" + Convert.ToBase64String(bytes) + "\"")
                    )
                ), Times.Once);
        }

AWS Lambda Powertools for .NET version

latest

AWS Lambda function runtime

dotnet6

Debugging logs

No response

Metadata

Metadata

Assignees

Labels

bugUnexpected, reproducible and unintended software behaviourtriagePending triage from maintainers

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions