Skip to content

Commit 1c8cf7c

Browse files
committed
(GH-123) Improve the boundary check logic to handle the scenario where boundary legitimately ends with '--'
1 parent e775a1a commit 1c8cf7c

1 file changed

Lines changed: 53 additions & 6 deletions

File tree

Source/HttpMultipartParser/StreamingBinaryMultipartFormDataParser.cs

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,12 @@ private static string DetectBoundary(RebufferableBinaryReader reader)
277277
// Remove the two dashes
278278
string boundary = line.Substring(2);
279279

280-
// If the string ends with '--' it means that we found the "end" boundary and we
281-
// need to trim the two dashes to get the actual boundary
282-
if (boundary.EndsWith("--"))
280+
// If the string ends with '--' and it's not followed by content, we can safely assume that we
281+
// found the "end" boundary. In this scenario, we must trim the two dashes to get the actual boundary.
282+
// Otherwise, the boundary must be accepted as-is. The reason we check for "additional content" is to
283+
// resolve the problem explained in GH-123.
284+
var moreContentAvailable = MoreContentAvailable(reader);
285+
if (boundary.EndsWith("--") && !moreContentAvailable)
283286
{
284287
boundary = boundary.Substring(0, boundary.Length - 2);
285288
reader.Buffer($"--{boundary}--\n");
@@ -333,9 +336,12 @@ private static async Task<string> DetectBoundaryAsync(RebufferableBinaryReader r
333336
// Remove the two dashes
334337
string boundary = line.Substring(2);
335338

336-
// If the string ends with '--' it means that we found the "end" boundary and we
337-
// need to trim the two dashes to get the actual boundary.
338-
if (boundary.EndsWith("--"))
339+
// If the string ends with '--' and it's not followed by content, we can safely assume that we
340+
// found the "end" boundary. In this scenario, we must trim the two dashes to get the actual boundary.
341+
// Otherwise, the boundary must be accepted as-is. The reason we check for "additional content" is to
342+
// resolve the problem explained in GH-123.
343+
var moreContentAvailable = await MoreContentAvailableAsync(reader).ConfigureAwait(false);
344+
if (boundary.EndsWith("--") && !moreContentAvailable)
339345
{
340346
boundary = boundary.Substring(0, boundary.Length - 2);
341347
reader.Buffer($"--{boundary}--\n");
@@ -348,6 +354,47 @@ private static async Task<string> DetectBoundaryAsync(RebufferableBinaryReader r
348354
return boundary;
349355
}
350356

357+
/// <summary>
358+
/// Determine if there is more content.
359+
/// </summary>
360+
/// <param name="reader">
361+
/// The binary reader to parse.
362+
/// </param>
363+
/// <returns>
364+
/// A boolean indicating whether more content is available in the binary reader.
365+
/// </returns>
366+
private static bool MoreContentAvailable(RebufferableBinaryReader reader)
367+
{
368+
var line = reader.ReadLine();
369+
370+
if (line == null) return false;
371+
else reader.Buffer($"{line}\n");
372+
373+
return true;
374+
}
375+
376+
/// <summary>
377+
/// Determine if there is more content.
378+
/// </summary>
379+
/// <param name="reader">
380+
/// The binary reader to parse.
381+
/// </param>
382+
/// <param name="cancellationToken">
383+
/// The cancellation token.
384+
/// </param>
385+
/// <returns>
386+
/// A boolean indicating whether more content is available in the binary reader.
387+
/// </returns>
388+
private static async Task<bool> MoreContentAvailableAsync(RebufferableBinaryReader reader, CancellationToken cancellationToken = default)
389+
{
390+
var line = await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false);
391+
392+
if (line == null) return false;
393+
else reader.Buffer($"{line}\n");
394+
395+
return true;
396+
}
397+
351398
/// <summary>
352399
/// Use a few assumptions to determine if a section contains a file.
353400
/// </summary>

0 commit comments

Comments
 (0)