From 1519ce67883ac8adf9822b0e4adbc7552b3632ec Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Sat, 14 Dec 2024 23:31:54 +0530 Subject: [PATCH] Fix: Mimetype application/x-zip-compressed interpreted as a text field (#3203) * Fix: Treat unrecognized MIME types as binary in MediaType * Fix: Ensure wildcard MIME types in Accept header default to non-binary * Update unsafeParseCustomMediaType to set binary for unrecognized MIME types --------- Co-authored-by: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> --- .../jvm/src/test/scala/zio/http/MediaTypeSpec.scala | 10 +++++++++- .../shared/src/main/scala/zio/http/MediaType.scala | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/zio-http/jvm/src/test/scala/zio/http/MediaTypeSpec.scala b/zio-http/jvm/src/test/scala/zio/http/MediaTypeSpec.scala index fd0780fa22..ce43b84d41 100644 --- a/zio-http/jvm/src/test/scala/zio/http/MediaTypeSpec.scala +++ b/zio-http/jvm/src/test/scala/zio/http/MediaTypeSpec.scala @@ -37,7 +37,7 @@ object MediaTypeSpec extends ZIOHttpSpec { } }, test("custom mime type parsing") { - assertTrue(MediaType.parseCustomMediaType("custom/mime").contains(MediaType("custom", "mime"))) + assertTrue(MediaType.parseCustomMediaType("custom/mime").contains(MediaType("custom", "mime", binary = true))) }, test("optional parameter parsing") { assertTrue( @@ -48,5 +48,13 @@ object MediaTypeSpec extends ZIOHttpSpec { ), ) }, + test("application/x-zip-compressed should be binary") { + val mediaType = MediaType.forContentType("application/x-zip-compressed") + assertTrue(mediaType.exists(_.binary)) + }, + test("text/plain should not be binary") { + val mediaType = MediaType.forContentType("text/plain") + assertTrue(mediaType.exists(!_.binary)) + }, ) } diff --git a/zio-http/shared/src/main/scala/zio/http/MediaType.scala b/zio-http/shared/src/main/scala/zio/http/MediaType.scala index 8a38bf9ac0..b98c22322e 100644 --- a/zio-http/shared/src/main/scala/zio/http/MediaType.scala +++ b/zio-http/shared/src/main/scala/zio/http/MediaType.scala @@ -64,11 +64,14 @@ object MediaType extends MediaTypes { val contentTypeParts = customMediaType.split('/') if (contentTypeParts.length == 2) { val subtypeParts = contentTypeParts(1).split(';') + // Default binary to true for unknown types unless they belong to text families + val isBinary = customMediaType != "*/*" && customMediaType != "text/*" && !customMediaType.startsWith("text/") if (subtypeParts.length >= 1) { Some( MediaType( mainType = contentTypeParts.head, subType = subtypeParts.head, + binary = isBinary, parameters = if (subtypeParts.length >= 2) parseOptionalParameters(subtypeParts.tail) else Map.empty, ), ) @@ -80,10 +83,12 @@ object MediaType extends MediaTypes { val contentTypeParts = customMediaType.split('/') if (contentTypeParts.length == 2) { val subtypeParts = contentTypeParts(1).split(';') + val isBinary = customMediaType != "*/*" && customMediaType != "text/*" && !customMediaType.startsWith("text/") if (subtypeParts.length >= 1) { MediaType( mainType = contentTypeParts.head, subType = subtypeParts.head, + binary = isBinary, parameters = if (subtypeParts.length >= 2) parseOptionalParameters(subtypeParts.tail) else Map.empty, ) } else throw new IllegalArgumentException(s"Invalid media type $customMediaType")