From e3a4d522b1a9f3a3d2081a30c49f4eb01497e745 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 24 Mar 2026 09:57:30 +0800 Subject: [PATCH 1/2] Set default MaxDepth for all AutoMapper maps to mitigate GHSA-rvv3-g6hj-g44x --- .../Abp/AutoMapper/AbpAutoMapperModule.cs | 8 +++ .../AbpAutoMapperModule_MaxDepth_Tests.cs | 65 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs diff --git a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs index f1e266b745..fbc80d20b5 100644 --- a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs +++ b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs @@ -40,6 +40,14 @@ public class AbpAutoMapperModule : AbpModule configurator(autoMapperConfigurationContext); } + mapperConfigurationExpression.Internal().ForAllMaps((typeMap, _) => + { + if (typeMap.MaxDepth == 0) + { + typeMap.MaxDepth = 64; + } + }); + var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression); foreach (var profileType in options.ValidatingProfiles) diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs new file mode 100644 index 0000000000..ad24430cbd --- /dev/null +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs @@ -0,0 +1,65 @@ +using AutoMapper; +using AutoMapper.Internal; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.AutoMapper.SampleClasses; +using Volo.Abp.Modularity; +using Volo.Abp.ObjectExtending; +using Volo.Abp.Testing; +using Xunit; + +namespace Volo.Abp.AutoMapper; + +public class AbpAutoMapperModule_MaxDepth_Tests : AbpIntegratedTest +{ + private readonly IConfigurationProvider _configurationProvider; + + public AbpAutoMapperModule_MaxDepth_Tests() + { + _configurationProvider = ServiceProvider.GetRequiredService(); + } + + [Fact] + public void Should_Set_Default_MaxDepth_For_All_Maps() + { + var typeMap = _configurationProvider.Internal().FindTypeMapFor(); + typeMap.ShouldNotBeNull(); + typeMap.MaxDepth.ShouldBe(64); + } +} + +public class AbpAutoMapperModule_CustomMaxDepth_Tests : AbpIntegratedTest +{ + private readonly IConfigurationProvider _configurationProvider; + + public AbpAutoMapperModule_CustomMaxDepth_Tests() + { + _configurationProvider = ServiceProvider.GetRequiredService(); + } + + [Fact] + public void Should_Not_Override_Custom_MaxDepth() + { + var typeMap = _configurationProvider.Internal().FindTypeMapFor(); + typeMap.ShouldNotBeNull(); + typeMap.MaxDepth.ShouldBe(10); + } + + [DependsOn( + typeof(AbpAutoMapperModule), + typeof(AbpObjectExtendingTestModule) + )] + public class TestModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Configurators.Add(ctx => + { + ctx.MapperConfiguration.CreateMap().MaxDepth(10); + }); + }); + } + } +} From 85df08dc2ce47659953cd3f641479100b133d4e3 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 24 Mar 2026 10:03:04 +0800 Subject: [PATCH 2/2] Extract DefaultMaxDepth to AbpAutoMapperOptions for configurability --- .../Abp/AutoMapper/AbpAutoMapperModule.cs | 13 ++++--- .../Abp/AutoMapper/AbpAutoMapperOptions.cs | 7 ++++ .../AbpAutoMapperModule_MaxDepth_Tests.cs | 37 +++++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs index fbc80d20b5..71dd37d259 100644 --- a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs +++ b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs @@ -40,13 +40,16 @@ public class AbpAutoMapperModule : AbpModule configurator(autoMapperConfigurationContext); } - mapperConfigurationExpression.Internal().ForAllMaps((typeMap, _) => + if (options.DefaultMaxDepth.HasValue) { - if (typeMap.MaxDepth == 0) + mapperConfigurationExpression.Internal().ForAllMaps((typeMap, _) => { - typeMap.MaxDepth = 64; - } - }); + if (typeMap.MaxDepth == 0) + { + typeMap.MaxDepth = options.DefaultMaxDepth.Value; + } + }); + } var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression); diff --git a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperOptions.cs b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperOptions.cs index e5cf1a0556..f6ab5a5408 100644 --- a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperOptions.cs +++ b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperOptions.cs @@ -12,6 +12,13 @@ public class AbpAutoMapperOptions public ITypeList ValidatingProfiles { get; set; } + /// + /// Default MaxDepth applied to all maps that don't have an explicit MaxDepth configured. + /// Set to null to disable the default MaxDepth behavior. + /// Default: 64. + /// + public int? DefaultMaxDepth { get; set; } = 64; + public AbpAutoMapperOptions() { Configurators = new List>(); diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs index ad24430cbd..d7cf32913b 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs @@ -63,3 +63,40 @@ public class AbpAutoMapperModule_CustomMaxDepth_Tests : AbpIntegratedTest +{ + private readonly IConfigurationProvider _configurationProvider; + + public AbpAutoMapperModule_DisabledMaxDepth_Tests() + { + _configurationProvider = ServiceProvider.GetRequiredService(); + } + + [Fact] + public void Should_Not_Set_MaxDepth_When_Disabled() + { + var typeMap = _configurationProvider.Internal().FindTypeMapFor(); + typeMap.ShouldNotBeNull(); + typeMap.MaxDepth.ShouldBe(0); + } + + [DependsOn( + typeof(AbpAutoMapperModule), + typeof(AbpObjectExtendingTestModule) + )] + public class TestModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.DefaultMaxDepth = null; + options.Configurators.Add(ctx => + { + ctx.MapperConfiguration.CreateMap(); + }); + }); + } + } +}