diff --git a/source/Handlebars.Test/BasicIntegrationTests.cs b/source/Handlebars.Test/BasicIntegrationTests.cs index d5211f82..5890f4cb 100644 --- a/source/Handlebars.Test/BasicIntegrationTests.cs +++ b/source/Handlebars.Test/BasicIntegrationTests.cs @@ -991,6 +991,21 @@ public void DictionaryEnumeratorWithBlockParams(IHandlebars handlebars) Assert.Equal("hello foo world bar ", result); } + [Theory, ClassData(typeof(HandlebarsEnvGenerator))] + public void BlockParamsNamedLikeContextVariables(IHandlebars handlebars) + { + // Block params sharing a name with @-variables used to be looked up by the @-variable's slot in a + // different dictionary, so whether they resolved depended on the process's string hash seed. + var data = new { items = new List { "a", "b" } }; + + foreach (var name in new[] { "index", "key", "first", "last", "root", "parent" }) + { + var template = handlebars.Compile($"{{{{#each items as |item {name}|}}}}{{{{{name}}}}}:{{{{item}}}};{{{{/each}}}}"); + + Assert.Equal("0:a;1:b;", template(data)); + } + } + [Theory, ClassData(typeof(HandlebarsEnvGenerator))] public void DictionaryWithLastEnumerator(IHandlebars handlebars) { diff --git a/source/Handlebars/BindingContext.cs b/source/Handlebars/BindingContext.cs index 42b1b38b..0240f1e7 100644 --- a/source/Handlebars/BindingContext.cs +++ b/source/Handlebars/BindingContext.cs @@ -147,14 +147,9 @@ out WellKnownVariables[(int) WellKnownVariable.Parent] internal bool TryGetVariable(ChainSegment segment, [MaybeNullWhen(false)] out object value) { - if (segment.WellKnownVariable != WellKnownVariable.None) - { - var wellKnownVariable = WellKnownVariables[(int) segment.WellKnownVariable]; - return BlockParamsObject.TryGetValue(wellKnownVariable, out value) - || (Descriptor.Value.MemberAccessor?.TryGetValue(Value!, segment, out value) ?? false); - } - - return BlockParamsObject.TryGetValue(segment, out value) + // Block params are looked up by segment even for well-known names (e.g. `as |item index|`): + // WellKnownVariables holds entry indexes into ContextDataObject, not BlockParamsObject. + return BlockParamsObject.TryGetValue(segment, out value) || (Descriptor.Value.MemberAccessor?.TryGetValue(Value!, segment, out value) ?? false); }