Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Unable to parse Multipart HTTPRequest when Boundary is Terminated with LF #17814

@sd-charris

Description

@sd-charris

Steps to Reproduce

  1. Build MonoMultiPartRepro.csproj
  2. Run MonoMultiPartRepro.exe
    MonoMultiPartBug.zip

Current Behavior

While self hosting a api and sending a http multipart request where the body boundary is not terminated by a CRLF pair the first part contains the body of the entire request. I have pulled out the System.Web code that is performing the boundary parsing in mono:

long MoveToNextBoundary ()
{
long retval = 0;
bool got_cr = false;
int state = 0;
int c = data.ReadByte ();
while (true) {
if (c == -1)
return -1;
if (state == 0 && c == LF) {
retval = data.Position - 1;
if (got_cr)
retval--;
state = 1;
c = data.ReadByte ();
} else if (state == 0) {
got_cr = (c == CR);
c = data.ReadByte ();
} else if (state == 1 && c == '-') {
c = data.ReadByte ();
if (c == -1)
return -1;
if (c != '-') {
state = 0;
got_cr = false;
continue; // no ReadByte() here
}
int nread = data.Read (buffer, 0, buffer.Length);
int bl = buffer.Length;
if (nread != bl)
return -1;
if (!CompareBytes (boundary_bytes, buffer)) {
state = 0;
data.Position = retval + 2;
if (got_cr) {
data.Position++;
got_cr = false;
}
c = data.ReadByte ();
continue;
}
if (buffer [bl - 2] == '-' && buffer [bl - 1] == '-') {
at_eof = true;
} else if (buffer [bl - 2] != CR || buffer [bl - 1] != LF) {
state = 0;
data.Position = retval + 2;
if (got_cr) {
data.Position++;
got_cr = false;
}
c = data.ReadByte ();
continue;
}
data.Position = retval + 2;
if (got_cr)
data.Position++;
break;
} else {
// state == 1
state = 0; // no ReadByte() here
}
}
return retval;
}

The First part of the Program outputs:

Part Length: 321
 Value:text default
--9051914041544843365972754266
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain

Content of a.txt.

--9051914041544843365972754266
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html

<!DOCTYPE html><title>Content of a.html.</title>

Expected Behavior

I have identified the fix and have included it in the program as shown below:

Fixed MONO Implementation

Part Length: 12
 Value:text default
Part Length: 18
 Value:Content of a.txt.

Part Length: 49
 Value:<!DOCTYPE html><title>Content of a.html.</title>

Here is the working .NET implementation which is also included in the program.
https://github.com/mono/mono/blob/c5b88ec4f323f2bdb7c7d0a595ece28dae66579c/mcs/class/referencesource/System.Web/MultipartContentParser.cs

NET Implementation

Part Length: 12
 Value:text default
Part Length: 18
 Value:Content of a.txt.

Part Length: 49
 Value:<!DOCTYPE html><title>Content of a.html.</title>

On which platforms did you notice this

[x] macOS
[x] Linux
[ ] Windows

Version Used:

Mono JIT compiler version 6.4.0.208 (2019-06/07c23f2ca43 Wed Oct  2 04:52:23 EDT 2019)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:
	SIGSEGV:       altstack
	Notification:  kqueue
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug
	Interpreter:   yes
	LLVM:          yes(610)
	Suspend:       hybrid
	GC:            sgen (concurrent by default)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions