Fix HandlebarsContext.ParseAndEvaluate (#1329)

This commit is contained in:
Stef Heyenrath
2025-07-12 11:05:02 +02:00
committed by GitHub
parent b0076b4e81
commit a06ee6b158
2 changed files with 11 additions and 9 deletions

View File

@@ -1,5 +1,6 @@
// Copyright © WireMock.Net // Copyright © WireMock.Net
using System.Text.RegularExpressions;
using HandlebarsDotNet; using HandlebarsDotNet;
using HandlebarsDotNet.Helpers.Extensions; using HandlebarsDotNet.Helpers.Extensions;
using Stef.Validation; using Stef.Validation;
@@ -9,6 +10,8 @@ namespace WireMock.Transformers.Handlebars;
internal class HandlebarsContext : IHandlebarsContext internal class HandlebarsContext : IHandlebarsContext
{ {
private static readonly Regex _tryEvaluateRegex = new(@"\{\{.*?\}\}", RegexOptions.Compiled);
public IHandlebars Handlebars { get; } public IHandlebars Handlebars { get; }
public IFileSystemHandler FileSystemHandler { get; } public IFileSystemHandler FileSystemHandler { get; }
@@ -27,9 +30,8 @@ internal class HandlebarsContext : IHandlebarsContext
public object? ParseAndEvaluate(string text, object model) public object? ParseAndEvaluate(string text, object model)
{ {
if (text.StartsWith("{{") && text.EndsWith("}}") && // Only try to evaluate if the text matches the pattern `{{ xxx }}` exactly once.
Handlebars.TryEvaluate(text, model, out var result) && if (_tryEvaluateRegex.Matches(text).Count == 1 && Handlebars.TryEvaluate(text, model, out var result) && result is not UndefinedBindingResult)
result is not UndefinedBindingResult)
{ {
return result; return result;
} }

View File

@@ -120,21 +120,21 @@ public class ResponseWithTransformerTests
var request = new RequestMessage(urlDetails, "POST", ClientIp); var request = new RequestMessage(urlDetails, "POST", ClientIp);
var responseBuilder = Response.Create() var responseBuilder = Response.Create()
.WithBody("{{request.PathSegments.[0]}} {{request.AbsolutePathSegments.[0]}}") .WithBody("{{request.PathSegments.[0]}} {{request.PathSegments.[1]}} {{request.AbsolutePathSegments.[0]}}")
.WithTransformer(); .WithTransformer();
// Act // Act
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false); var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
// Assert // Assert
Check.That(response.Message.BodyData!.BodyAsString).Equals("a wiremock"); Check.That(response.Message.BodyData!.BodyAsString).Equals("a b wiremock");
} }
[Theory] [Theory]
[InlineData("{{request.PathSegments.[0]}}", "a")] [InlineData("{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}", "a b")]
[InlineData("prefix_{{request.PathSegments.[0]}}", "prefix_a")] [InlineData("prefix_{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}", "prefix_a b")]
[InlineData("{{request.PathSegments.[0]}}_postfix", "a_postfix")] [InlineData("{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}_postfix", "a b_postfix")]
[InlineData("prefix_{{request.PathSegments.[0]}}_postfix", "prefix_a_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) public async Task Response_ProvideResponse_Handlebars_BodyAsJson_PathSegments(string field, string expected)
{ {
// Assign // Assign