Skip to content

Commit 534ceef

Browse files
committed
Updating to use MaxValidationDepth
1 parent a9a8a07 commit 534ceef

File tree

4 files changed

+23
-12
lines changed

4 files changed

+23
-12
lines changed

src/Mvc/Mvc.Abstractions/ref/Microsoft.AspNetCore.Mvc.Abstractions.Manual.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
1313
{
1414
public partial class ModelStateDictionary
1515
{
16-
internal int MaxRecursionDepth { get; set; }
16+
internal int? MaxValidationDepth { get; set; }
1717
}
1818
}

src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelStateDictionary.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class ModelStateDictionary : IReadOnlyDictionary<string, ModelStateEntry>
3030

3131
private readonly ModelStateNode _root;
3232
private int _maxAllowedErrors;
33-
private int _maxRecursionDepth;
33+
private int? _maxValidationDepth;
3434

3535
/// <summary>
3636
/// Initializes a new instance of the <see cref="ModelStateDictionary"/> class.
@@ -44,9 +44,17 @@ public ModelStateDictionary()
4444
/// Initializes a new instance of the <see cref="ModelStateDictionary"/> class.
4545
/// </summary>
4646
public ModelStateDictionary(int maxAllowedErrors)
47+
: this (maxAllowedErrors, DefaultMaxRecursionDepth)
48+
{
49+
}
50+
51+
/// <summary>
52+
/// Initializes a new instance of the <see cref="ModelStateDictionary"/> class.
53+
/// </summary>
54+
private ModelStateDictionary(int maxAllowedErrors, int maxValidationDepth)
4755
{
4856
MaxAllowedErrors = maxAllowedErrors;
49-
MaxRecursionDepth = DefaultMaxRecursionDepth;
57+
MaxValidationDepth = maxValidationDepth;
5058
var emptySegment = new StringSegment(buffer: string.Empty);
5159
_root = new ModelStateNode(subKey: emptySegment)
5260
{
@@ -60,7 +68,7 @@ public ModelStateDictionary(int maxAllowedErrors)
6068
/// </summary>
6169
/// <param name="dictionary">The <see cref="ModelStateDictionary"/> to copy values from.</param>
6270
public ModelStateDictionary(ModelStateDictionary dictionary)
63-
: this(dictionary?.MaxAllowedErrors ?? DefaultMaxAllowedErrors)
71+
: this(dictionary?.MaxAllowedErrors ?? DefaultMaxAllowedErrors, dictionary?.MaxValidationDepth ?? DefaultMaxRecursionDepth)
6472
{
6573
if (dictionary == null)
6674
{
@@ -176,19 +184,19 @@ public ModelStateEntry this[string key]
176184
// Flag that indicates if TooManyModelErrorException has already been added to this dictionary.
177185
private bool HasRecordedMaxModelError { get; set; }
178186

179-
internal int MaxRecursionDepth
187+
internal int? MaxValidationDepth
180188
{
181189
get
182190
{
183-
return _maxRecursionDepth;
191+
return _maxValidationDepth;
184192
}
185193
set
186194
{
187195
if (value < 0)
188196
{
189197
throw new ArgumentOutOfRangeException(nameof(value));
190198
}
191-
_maxRecursionDepth = value;
199+
_maxValidationDepth = value;
192200
}
193201
}
194202

@@ -682,7 +690,8 @@ private static StringSegment FindNext(string key, ref MatchResult currentMatch)
682690

683691
private ModelValidationState? GetValidity(ModelStateNode node, int currentDepth)
684692
{
685-
if (node == null || currentDepth >= MaxRecursionDepth)
693+
if (node == null ||
694+
(MaxValidationDepth != null && currentDepth >= MaxValidationDepth))
686695
{
687696
return null;
688697
}

src/Mvc/Mvc.Abstractions/test/ModelBinding/ModelStateDictionaryTest.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,9 @@ public void GetFieldValidity_ReturnsUnvalidated_IfTreeHeightIsGreaterThanLimit()
699699
{
700700
// Arrange
701701
var dictionary = new ModelStateDictionary();
702-
var key = string.Join(".", Enumerable.Repeat("foo", dictionary.MaxRecursionDepth + 1));
702+
var stackLimit = 32;
703+
var key = string.Join(".", Enumerable.Repeat("foo", stackLimit + 1));
704+
dictionary.MaxValidationDepth = stackLimit;
703705
dictionary.MarkFieldValid(key);
704706

705707
// Act

src/Mvc/Mvc.Core/src/Infrastructure/ControllerActionInvokerProvider.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ internal class ControllerActionInvokerProvider : IActionInvokerProvider
1818
private readonly ControllerActionInvokerCache _controllerActionInvokerCache;
1919
private readonly IReadOnlyList<IValueProviderFactory> _valueProviderFactories;
2020
private readonly int _maxModelValidationErrors;
21-
private readonly int _maxModelBindingRecursionDepth;
21+
private readonly int? _maxValidationDepth;
2222
private readonly ILogger _logger;
2323
private readonly DiagnosticListener _diagnosticListener;
2424
private readonly IActionResultTypeMapper _mapper;
@@ -45,7 +45,7 @@ public ControllerActionInvokerProvider(
4545
_controllerActionInvokerCache = controllerActionInvokerCache;
4646
_valueProviderFactories = optionsAccessor.Value.ValueProviderFactories.ToArray();
4747
_maxModelValidationErrors = optionsAccessor.Value.MaxModelValidationErrors;
48-
_maxModelBindingRecursionDepth = optionsAccessor.Value.MaxModelBindingRecursionDepth;
48+
_maxValidationDepth = optionsAccessor.Value.MaxValidationDepth;
4949
_logger = loggerFactory.CreateLogger<ControllerActionInvoker>();
5050
_diagnosticListener = diagnosticListener;
5151
_mapper = mapper;
@@ -70,7 +70,7 @@ public void OnProvidersExecuting(ActionInvokerProviderContext context)
7070
ValueProviderFactories = new CopyOnWriteList<IValueProviderFactory>(_valueProviderFactories)
7171
};
7272
controllerContext.ModelState.MaxAllowedErrors = _maxModelValidationErrors;
73-
controllerContext.ModelState.MaxRecursionDepth = _maxModelBindingRecursionDepth;
73+
controllerContext.ModelState.MaxValidationDepth = _maxValidationDepth;
7474

7575
var (cacheEntry, filters) = _controllerActionInvokerCache.GetCachedResult(controllerContext);
7676

0 commit comments

Comments
 (0)