Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InvalidOperationException in case when default form value length limit exceeded. #27585

Closed
Tratcher opened this issue Nov 6, 2020 · 1 comment · Fixed by #27586
Closed

InvalidOperationException in case when default form value length limit exceeded. #27585

Tratcher opened this issue Nov 6, 2020 · 1 comment · Fixed by #27586
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions bug This issue describes a behavior which is not expected - a bug.
Milestone

Comments

@Tratcher
Copy link
Member

Tratcher commented Nov 6, 2020

First reported at #27493

Make a 5 Mb x-www-form-urlencoded POST request with a pretty long field.

Result:

System.InvalidOperationException: The examined position cannot be less than the previously examined position.
   at System.IO.Pipelines.ThrowHelper.ThrowInvalidOperationException_InvalidExaminedPosition()
   at System.IO.Pipelines.Pipe.AdvanceReader(BufferSegment consumedSegment, Int32 consumedIndex, BufferSegment examinedSegment, Int32 examinedIndex)
   at System.IO.Pipelines.Pipe.AdvanceReader(SequencePosition& consumed, SequencePosition& examined)
   at System.IO.Pipelines.Pipe.DefaultPipeReader.AdvanceTo(SequencePosition consumed, SequencePosition examined)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2MessageBody.AdvanceTo(SequencePosition consumed, SequencePosition examined)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2MessageBody.AdvanceTo(SequencePosition consumed)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestPipeReader.AdvanceTo(SequencePosition consumed)
   at Microsoft.AspNetCore.WebUtilities.FormPipeReader.ReadFormAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Mvc.ModelBinding.FormValueProviderFactory.AddValueProviderAsync(ValueProviderFactoryContext context)
   at Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.CreateAsync(ActionContext actionContext, IList`1 factories)
   at Microsoft.AspNetCore.Mvc.ModelBinding.CompositeValueProvider.TryCreateAsync(ActionContext actionContext, IList`1 factories)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

If they change FormOptions.ValueLengthLimit to bigger value - everything works fine.

If they debugged via IIS Express they correctly see a model error like "Failed to read the request form. Form value length limit 4194304 exceeded."

Cause:
There's a disparity between these two calls to AdvanceTo:

_pipeReader.AdvanceTo(buffer.Start);
throw;
}
}
if (readResult.IsCompleted)
{
_pipeReader.AdvanceTo(buffer.End);
if (!buffer.IsEmpty)
{
throw new InvalidOperationException("End of body before form was fully parsed.");
}
break;
}
_pipeReader.AdvanceTo(buffer.Start, buffer.End);

If there's a large field that is under the limit in the first buffer, but then loops and exceeds the limit, the examined parameter is set back to Start instead of End.

Fix:
The fix seems to be to add buffer.End to the AdvanceTo in the catch block so it's greater or equal to the prior value. I'll prep a PR.

I don't know why there's different results on IIS Express, but it may just be a matter of different buffer alignments.

@Tratcher Tratcher added area-servers bug This issue describes a behavior which is not expected - a bug. labels Nov 6, 2020
Tratcher added a commit to Tratcher/aspnetcore that referenced this issue Nov 6, 2020
@Tratcher
Copy link
Member Author

Tratcher commented Nov 6, 2020

Versions: This was reported in both 3.1 and 5.0, but I don't currently recommend backporting the fix because it won't help the operation succeed, it will only help fail with a better error message. We'll see if we get more reports about this.

@ghost ghost closed this as completed in #27586 Nov 6, 2020
ghost pushed a commit that referenced this issue Nov 6, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 6, 2020
@Tratcher Tratcher added this to the 6.0-preview1 milestone Nov 17, 2021
@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Aug 24, 2023
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions bug This issue describes a behavior which is not expected - a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants