fix(JsonStringLocalizer): add type check prevent endless loop (#4653)
Some checks failed
Build project / build (push) Has been cancelled

* fix(JsonStringLocalizer):Endless loop bug

* chore: bump version 9.0.0-beta01

---------

Co-authored-by: Argo Zhang <argo@live.ca>
This commit is contained in:
Amos 2024-11-14 14:33:03 +08:00 committed by GitHub
parent a8fa755d1c
commit b73c3ec300
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 54 additions and 3 deletions

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<Version>9.0.0</Version>
<Version>9.0.0-beta01</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -82,7 +82,7 @@ internal class JsonStringLocalizer(Assembly assembly, string typeName, string ba
{
string? ret = null;
var localizer = Utility.GetStringLocalizerFromService(Assembly, typeName);
if (localizer != null)
if (localizer != null && localizer is not JsonStringLocalizer)
{
ret = GetLocalizerValueFromCache(localizer, name);
}
@ -177,7 +177,7 @@ internal class JsonStringLocalizer(Assembly assembly, string typeName, string ba
{
IEnumerable<LocalizedString>? ret = null;
var localizer = Utility.GetStringLocalizerFromService(Assembly, typeName);
if (localizer != null)
if (localizer != null && localizer is not JsonStringLocalizer)
{
ret = localizer.GetAllStrings(includeParentCultures);
}

View File

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
@ -306,6 +307,25 @@ public class JsonStringLocalizerTest : BootstrapBlazorTestBase
Assert.Equal("Test", result[0].ErrorMessage);
}
[Fact]
public void ValidateFixEndlessLoop()
{
var sc = new ServiceCollection();
sc.AddConfiguration();
sc.AddBootstrapBlazor();
sc.AddSingleton<IStringLocalizerFactory, MockLocalizerFactory>();
sc.AddSingleton<IStringLocalizerFactory, MockLocalizerFactory2>();
var provider = sc.BuildServiceProvider();
var localizer = provider.GetRequiredService<IStringLocalizer<Foo>>();
Assert.Equal("姓名", localizer["Name"]);
var items = localizer.GetAllStrings(false);
Assert.Equal("姓名", items.First(i => i.Name == "Name").Value);
Assert.DoesNotContain("Test-JsonName", items.Select(i => i.Name));
}
private class MockTypeInfo : TypeDelegator
{
public override string? FullName => null;
@ -318,6 +338,37 @@ public class JsonStringLocalizerTest : BootstrapBlazorTestBase
public IStringLocalizer Create(string baseName, string location) => new MockStringLocalizer();
}
private class MockLocalizerFactory2 : IStringLocalizerFactory
{
private readonly IServiceProvider _serviceProvider;
public MockLocalizerFactory2(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IStringLocalizer Create(Type resourceSource)
{
var stringLocalizerFactorys = _serviceProvider.GetServices<IStringLocalizerFactory>();
IStringLocalizerFactory stringLocalizerFactory;
if (resourceSource == typeof(Foo))
{
stringLocalizerFactory = stringLocalizerFactorys.Single(s => s.GetType().Name == "JsonStringLocalizerFactory");
}
else
{
stringLocalizerFactory = _serviceProvider.GetServices<IStringLocalizerFactory>().Single(s => s is MockLocalizerFactory);
}
return stringLocalizerFactory.Create(resourceSource);
}
public IStringLocalizer Create(string baseName, string location)
{
var stringLocalizerFactory = _serviceProvider.GetServices<IStringLocalizerFactory>().Single(s => s is MockLocalizerFactory);
return stringLocalizerFactory.Create(baseName, location);
}
}
private class MockStringLocalizer : IStringLocalizer
{
public LocalizedString this[string name] => GetAllStrings(true).FirstOrDefault(l => l.Name == name) ?? new LocalizedString(name, name, true);