From a06ee6b158f2ae5157259df61230602833c4fef8 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Sat, 12 Jul 2025 11:05:02 +0200 Subject: [PATCH] Fix HandlebarsContext.ParseAndEvaluate (#1329) --- .../Transformers/Handlebars/HandlebarsContext.cs | 8 +++++--- .../ResponseBuilders/ResponseWithTransformerTests.cs | 12 ++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/WireMock.Net.Minimal/Transformers/Handlebars/HandlebarsContext.cs b/src/WireMock.Net.Minimal/Transformers/Handlebars/HandlebarsContext.cs index 57632ba3..e94f93a7 100644 --- a/src/WireMock.Net.Minimal/Transformers/Handlebars/HandlebarsContext.cs +++ b/src/WireMock.Net.Minimal/Transformers/Handlebars/HandlebarsContext.cs @@ -1,5 +1,6 @@ // Copyright © WireMock.Net +using System.Text.RegularExpressions; using HandlebarsDotNet; using HandlebarsDotNet.Helpers.Extensions; using Stef.Validation; @@ -9,6 +10,8 @@ namespace WireMock.Transformers.Handlebars; internal class HandlebarsContext : IHandlebarsContext { + private static readonly Regex _tryEvaluateRegex = new(@"\{\{.*?\}\}", RegexOptions.Compiled); + public IHandlebars Handlebars { get; } public IFileSystemHandler FileSystemHandler { get; } @@ -27,9 +30,8 @@ internal class HandlebarsContext : IHandlebarsContext public object? ParseAndEvaluate(string text, object model) { - if (text.StartsWith("{{") && text.EndsWith("}}") && - Handlebars.TryEvaluate(text, model, out var result) && - result is not UndefinedBindingResult) + // Only try to evaluate if the text matches the pattern `{{ xxx }}` exactly once. + if (_tryEvaluateRegex.Matches(text).Count == 1 && Handlebars.TryEvaluate(text, model, out var result) && result is not UndefinedBindingResult) { return result; } diff --git a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithTransformerTests.cs b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithTransformerTests.cs index d6727acd..9f663fd0 100644 --- a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithTransformerTests.cs +++ b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithTransformerTests.cs @@ -120,21 +120,21 @@ public class ResponseWithTransformerTests var request = new RequestMessage(urlDetails, "POST", ClientIp); var responseBuilder = Response.Create() - .WithBody("{{request.PathSegments.[0]}} {{request.AbsolutePathSegments.[0]}}") + .WithBody("{{request.PathSegments.[0]}} {{request.PathSegments.[1]}} {{request.AbsolutePathSegments.[0]}}") .WithTransformer(); // Act var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false); // Assert - Check.That(response.Message.BodyData!.BodyAsString).Equals("a wiremock"); + Check.That(response.Message.BodyData!.BodyAsString).Equals("a b wiremock"); } [Theory] - [InlineData("{{request.PathSegments.[0]}}", "a")] - [InlineData("prefix_{{request.PathSegments.[0]}}", "prefix_a")] - [InlineData("{{request.PathSegments.[0]}}_postfix", "a_postfix")] - [InlineData("prefix_{{request.PathSegments.[0]}}_postfix", "prefix_a_postfix")] + [InlineData("{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}", "a b")] + [InlineData("prefix_{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}", "prefix_a b")] + [InlineData("{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}_postfix", "a b_postfix")] + [InlineData("prefix_{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}_postfix", "prefix_a b_postfix")] public async Task Response_ProvideResponse_Handlebars_BodyAsJson_PathSegments(string field, string expected) { // Assign