Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions source/Handlebars.Test/Issues/Issue434Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ public void Issue434_CaseSensitiveLookupWithSameSpellingVariables()
data.TEST = "Upper";
data.test = "Lower";
var result = template(data);
var parts = result.Split(' ');
Assert.Equal("Upper", parts[0]);
Assert.Equal("Lower", parts[1]);
Assert.Equal("Upper Lower", result);
}
}
}
44 changes: 44 additions & 0 deletions source/Handlebars.Test/Issues/Issue559Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Xunit;
using Xunit.Abstractions;

namespace HandlebarsDotNet.Test
{
public class Issue559Tests
{
private readonly ITestOutputHelper _output;

public Issue559Tests(ITestOutputHelper output)
{
_output = output;
}

[Fact]
public void WriteSafeString_ConsistentRegardlessOfRegistrationOrder()
{
HandlebarsHelper link_to = (writer, context, parameters) =>
writer.WriteSafeString($"<a href='{context["url"]}'>{context["text"]}</a>");

string source = "Click here: {{link_to}}";
var data = new { url = "https://example.com", text = "Click" };

// Register BEFORE compile
var h1 = Handlebars.Create();
h1.RegisterHelper("link_to", link_to);
var t1 = h1.Compile(source);
var result1 = t1(data);

// Register AFTER compile
var h2 = Handlebars.Create();
var t2 = h2.Compile(source);
h2.RegisterHelper("link_to", link_to);
var result2 = t2(data);

_output.WriteLine($"result1 (before compile): {result1}");
_output.WriteLine($"result2 (after compile): {result2}");

// Both should produce identical, unescaped HTML
Assert.Equal(result1, result2);
Assert.Contains("<a href=", result1);
}
}
}
49 changes: 47 additions & 2 deletions source/Handlebars/Compiler/Translation/Expression/PathBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,55 @@

protected override Expression VisitStatementExpression(StatementExpression sex)
{
if (!(sex.Body is PathExpression)) return Visit(sex.Body);
if (!(sex.Body is PathExpression pex)) return Visit(sex.Body);

var configuration = CompilationContext.Configuration;
var pathInfo = PathInfoStore.Current.GetOrAdd(pex.Path);

if (pex.Context != PathExpression.ResolutionContext.Parameter
&& !pathInfo.IsVariable
&& !pathInfo.IsThis
&& (pathInfo.IsValidHelperLiteral || configuration.Compatibility.RelaxedHelperNaming))

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Build

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Build

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on ubuntu-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on macos-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

See more on https://sonarcloud.io/project/issues?id=Handlebars-Net_Handlebars.Net&issues=AZ7nJgX7dewo-eGl6GsF&open=AZ7nJgX7dewo-eGl6GsF&pullRequest=637

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on windows-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on windows-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 29 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Run Benchmark.Net

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'
{
var pathInfoLight = new PathInfoLight(pathInfo);
Ref<IHelperDescriptor<HelperOptions>> helper;

if (!configuration.Helpers.TryGetValue(pathInfoLight, out helper))
{
var lateBindHelperDescriptor = new LateBindHelperDescriptor(pathInfo);
helper = new Ref<IHelperDescriptor<HelperOptions>>(lateBindHelperDescriptor);
configuration.Helpers.AddOrReplace(pathInfoLight, helper);
}
else if (helper.Value is LateBindHelperDescriptor existingLateBindDescriptor
&& !string.Equals(existingLateBindDescriptor.Name.Path, pathInfo.Path, System.StringComparison.Ordinal))
{
// The case-insensitive lookup found a late-bind descriptor registered for a
// differently-cased path (e.g. {{TEST}} was registered; now compiling {{test}}).
// Create a fresh descriptor bound to the exact current path so that runtime
// path resolution is case-sensitive.
var lateBindHelperDescriptor = new LateBindHelperDescriptor(pathInfo);
helper = new Ref<IHelperDescriptor<HelperOptions>>(lateBindHelperDescriptor);
}
else if (configuration.Compatibility.RelaxedHelperNaming)

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Build

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Build

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on ubuntu-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on macos-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

See more on https://sonarcloud.io/project/issues?id=Handlebars-Net_Handlebars.Net&issues=AZ7nJgX7dewo-eGl6GsG&open=AZ7nJgX7dewo-eGl6GsG&pullRequest=637

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on windows-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on windows-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 50 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Run Benchmark.Net

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'
{
pathInfoLight = pathInfoLight.TagComparer();
if (!configuration.Helpers.ContainsKey(pathInfoLight))
{
var lateBindHelperDescriptor = new LateBindHelperDescriptor(pathInfo);
helper = new Ref<IHelperDescriptor<HelperOptions>>(lateBindHelperDescriptor);
configuration.Helpers.AddOrReplace(pathInfoLight, helper);
}
}

var bindingContext = CompilationContext.Args.BindingContext;
var options = New(() => new HelperOptions(pathInfo, bindingContext));
var contextValue = New(() => new Context(bindingContext));
var args = New(() => new Arguments(0));
var textWriter = CompilationContext.Args.EncodedWriter;
return Call(() => helper.Value.Invoke(textWriter, options, contextValue, args));
}

var writer = CompilationContext.Args.EncodedWriter;

var value = Arg<object>(Visit(sex.Body));
return writer.Call(o => o.Write<object>(value));
}
Expand All @@ -36,7 +81,7 @@

if (pex.Context == PathExpression.ResolutionContext.Parameter) return resolvePath;
if (pathInfo.IsVariable || pathInfo.IsThis) return resolvePath;
if (!pathInfo.IsValidHelperLiteral && !configuration.Compatibility.RelaxedHelperNaming) return resolvePath;

Check warning on line 84 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Build

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 84 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Build

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 84 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on ubuntu-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 84 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on macos-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 84 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 84 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 84 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 84 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on windows-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 84 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on windows-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 84 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Run Benchmark.Net

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

var pathInfoLight = new PathInfoLight(pathInfo);
if (!configuration.Helpers.TryGetValue(pathInfoLight, out var helper))
Expand All @@ -56,7 +101,7 @@
var lateBindHelperDescriptor = new LateBindHelperDescriptor(pathInfo);
helper = new Ref<IHelperDescriptor<HelperOptions>>(lateBindHelperDescriptor);
}
else if (configuration.Compatibility.RelaxedHelperNaming)

Check warning on line 104 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Build

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 104 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Build

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 104 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on ubuntu-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 104 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on macos-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 104 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 104 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 104 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / SonarCloud

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 104 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on windows-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 104 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Tests on windows-latest

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'

Check warning on line 104 in source/Handlebars/Compiler/Translation/Expression/PathBinder.cs

View workflow job for this annotation

GitHub Actions / Run Benchmark.Net

'Compatibility.RelaxedHelperNaming' is obsolete: 'Toggle will be removed in the next major release'
{
pathInfoLight = pathInfoLight.TagComparer();
if (!configuration.Helpers.ContainsKey(pathInfoLight))
Expand Down
Loading