Merge pull request #17112 from spray/wip-17110-mathias

=htc #17110 disallow zero body parts in MIME content
This commit is contained in:
Roland Kuhn 2015-04-09 16:27:18 +02:00
commit 6b9ca731cc
2 changed files with 14 additions and 17 deletions

View file

@ -56,7 +56,6 @@ private[http] final class BodyPartParser(defaultContentType: ContentType,
private[this] var output = collection.immutable.Queue.empty[Output] // FIXME this probably is too wasteful private[this] var output = collection.immutable.Queue.empty[Output] // FIXME this probably is too wasteful
private[this] var state: ByteString StateResult = tryParseInitialBoundary private[this] var state: ByteString StateResult = tryParseInitialBoundary
private[this] var receivedInitialBoundary = false
private[this] var terminated = false private[this] var terminated = false
def warnOnIllegalHeader(errorInfo: ErrorInfo): Unit = def warnOnIllegalHeader(errorInfo: ErrorInfo): Unit =
@ -79,10 +78,8 @@ private[http] final class BodyPartParser(defaultContentType: ContentType,
if (output.nonEmpty) if (output.nonEmpty)
ctx.push(dequeue()) ctx.push(dequeue())
else if (ctx.isFinishing) { else if (ctx.isFinishing) {
if (terminated || !receivedInitialBoundary) if (terminated) ctx.finish()
ctx.finish() else ctx.pushAndFinish(ParseError(ErrorInfo("Unexpected end of multipart entity")))
else
ctx.pushAndFinish(ParseError(ErrorInfo("Unexpected end of multipart entity")))
} else } else
ctx.pull() ctx.pull()
} }
@ -95,10 +92,8 @@ private[http] final class BodyPartParser(defaultContentType: ContentType,
try { try {
if (boundary(input, 0)) { if (boundary(input, 0)) {
val ix = boundaryLength val ix = boundaryLength
if (crlf(input, ix)) { if (crlf(input, ix)) parseHeaderLines(input, ix + 2)
receivedInitialBoundary = true else if (doubleDash(input, ix)) terminate()
parseHeaderLines(input, ix + 2)
} else if (doubleDash(input, ix)) terminate()
else parsePreamble(input, 0) else parsePreamble(input, 0)
} else parsePreamble(input, 0) } else parsePreamble(input, 0)
} catch { } catch {

View file

@ -37,14 +37,6 @@ class UnmarshallingSpec extends FreeSpec with Matchers with BeforeAndAfterAll wi
"The MultipartUnmarshallers." - { "The MultipartUnmarshallers." - {
"multipartGeneralUnmarshaller should correctly unmarshal 'multipart/*' content with" - { "multipartGeneralUnmarshaller should correctly unmarshal 'multipart/*' content with" - {
"an empty entity" in {
Unmarshal(HttpEntity(`multipart/mixed` withBoundary "XYZABC", ByteString.empty)).to[Multipart.General] should haveParts()
}
"an entity without initial boundary" in {
Unmarshal(HttpEntity(`multipart/mixed` withBoundary "XYZABC",
"""this is
|just preamble text""".stripMarginWithNewline("\r\n"))).to[Multipart.General] should haveParts()
}
"an empty part" in { "an empty part" in {
Unmarshal(HttpEntity(`multipart/mixed` withBoundary "XYZABC", Unmarshal(HttpEntity(`multipart/mixed` withBoundary "XYZABC",
"""--XYZABC """--XYZABC
@ -111,6 +103,16 @@ class UnmarshallingSpec extends FreeSpec with Matchers with BeforeAndAfterAll wi
} }
"multipartGeneralUnmarshaller should reject illegal multipart content with" - { "multipartGeneralUnmarshaller should reject illegal multipart content with" - {
"an empty entity" in {
Await.result(Unmarshal(HttpEntity(`multipart/mixed` withBoundary "XYZABC", ByteString.empty))
.to[Multipart.General].failed, 1.second).getMessage shouldEqual "Unexpected end of multipart entity"
}
"an entity without initial boundary" in {
Await.result(Unmarshal(HttpEntity(`multipart/mixed` withBoundary "XYZABC",
"""this is
|just preamble text""".stripMarginWithNewline("\r\n")))
.to[Multipart.General].failed, 1.second).getMessage shouldEqual "Unexpected end of multipart entity"
}
"a stray boundary" in { "a stray boundary" in {
Await.result(Unmarshal(HttpEntity(`multipart/form-data` withBoundary "ABC", Await.result(Unmarshal(HttpEntity(`multipart/form-data` withBoundary "ABC",
"""--ABC """--ABC