From 03ea87921eb674115382e5f13659c8df6d0d22cd Mon Sep 17 00:00:00 2001 From: Hardik Kaurani Date: Sat, 7 Nov 2026 11:21:20 +0530 Subject: [PATCH 1/2] fix(serialization): support content-type parameters and case-insensitivity in form factories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FormParseNodeFactory and FormSerializationWriterFactory previously checked content types with strict string equality against application/x-www-form-urlencoded. As a result, content types with MIME parameters (such as charset=utf-8) or case variations (such as APPLICATION/X-WWW-FORM-URLENCODED) were rejected with IllegalArgumentException. Strip MIME parameters and compare against the valid content type case-insensitively, aligning with RFC 2045 ยง5.1 and matching TextParseNodeFactory and MultipartSerializationWriterFactory. Signed-off-by: Hardik Kaurani --- .../com/microsoft/kiota/serialization/FormParseNodeFactory.java | 2 +- .../kiota/serialization/FormSerializationWriterFactory.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/serialization/form/src/main/java/com/microsoft/kiota/serialization/FormParseNodeFactory.java b/components/serialization/form/src/main/java/com/microsoft/kiota/serialization/FormParseNodeFactory.java index adb97018..39151393 100644 --- a/components/serialization/form/src/main/java/com/microsoft/kiota/serialization/FormParseNodeFactory.java +++ b/components/serialization/form/src/main/java/com/microsoft/kiota/serialization/FormParseNodeFactory.java @@ -28,7 +28,7 @@ public FormParseNodeFactory() {} Objects.requireNonNull(rawResponse, "parameter rawResponse cannot be null"); if (contentType.isEmpty()) { throw new NullPointerException("contentType cannot be empty"); - } else if (!contentType.equals(validContentType)) { + } else if (!contentType.split(";", 2)[0].trim().equalsIgnoreCase(validContentType)) { throw new IllegalArgumentException("expected a " + validContentType + " content type"); } String rawText; diff --git a/components/serialization/form/src/main/java/com/microsoft/kiota/serialization/FormSerializationWriterFactory.java b/components/serialization/form/src/main/java/com/microsoft/kiota/serialization/FormSerializationWriterFactory.java index 3cb27ce2..030529e7 100644 --- a/components/serialization/form/src/main/java/com/microsoft/kiota/serialization/FormSerializationWriterFactory.java +++ b/components/serialization/form/src/main/java/com/microsoft/kiota/serialization/FormSerializationWriterFactory.java @@ -20,7 +20,7 @@ public FormSerializationWriterFactory() {} Objects.requireNonNull(contentType, "parameter contentType cannot be null"); if (contentType.isEmpty()) { throw new NullPointerException("contentType cannot be empty"); - } else if (!contentType.equals(validContentType)) { + } else if (!contentType.split(";", 2)[0].trim().equalsIgnoreCase(validContentType)) { throw new IllegalArgumentException("expected a " + validContentType + " content type"); } return new FormSerializationWriter(); From a33eb7c4324e00e062a3eef3171da5341b27de5e Mon Sep 17 00:00:00 2001 From: Hardik Kaurani Date: Sat, 7 Nov 2026 11:25:06 +0530 Subject: [PATCH 2/2] test(serialization): add regression tests for form factories with MIME parameters and case variants Add parameterized tests in ParseNodeFactoryTests and SerializationWriterFactoryTests asserting that FormParseNodeFactory and FormSerializationWriterFactory properly accept content types with MIME parameters (such as charset=utf-8), uppercase, and mixed-case variants, while continuing to reject delimiter-only and invalid media types. Signed-off-by: Hardik Kaurani --- .../serialization/ParseNodeFactoryTests.java | 38 +++++++++++++++++++ .../SerializationWriterFactoryTests.java | 34 +++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/components/serialization/form/src/test/java/com/microsoft/kiota/serialization/ParseNodeFactoryTests.java b/components/serialization/form/src/test/java/com/microsoft/kiota/serialization/ParseNodeFactoryTests.java index c91e7eea..d1033f55 100644 --- a/components/serialization/form/src/test/java/com/microsoft/kiota/serialization/ParseNodeFactoryTests.java +++ b/components/serialization/form/src/test/java/com/microsoft/kiota/serialization/ParseNodeFactoryTests.java @@ -4,6 +4,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; @@ -37,4 +39,40 @@ public void throwsArgumentNullExceptionForNoContentType() throws UnsupportedEnco assertThrows( NullPointerException.class, () -> _parseNodeFactory.getParseNode("", rawResponse)); } + + @ParameterizedTest + @ValueSource( + strings = { + "application/x-www-form-urlencoded; charset=utf-8", + "application/x-www-form-urlencoded; charset=UTF-8", + "application/x-www-form-urlencoded; charset=us-ascii", + "APPLICATION/X-WWW-FORM-URLENCODED", + "APPLICATION/X-WWW-FORM-URLENCODED; CHARSET=UTF-8", + "Application/x-www-form-urlencoded", + "Application/x-www-form-urlencoded; charset=utf-8", + }) + public void getsParseNodeForContentTypeWithParametersOrCaseVariants(final String inputType) + throws UnsupportedEncodingException { + final var initialString = "key1=value1&key2=value2"; + final var rawResponse = new ByteArrayInputStream(initialString.getBytes("UTF-8")); + final var parseNode = _parseNodeFactory.getParseNode(inputType, rawResponse); + assertNotNull(parseNode); + } + + @ParameterizedTest + @ValueSource( + strings = { + ";", + ";;", + "; charset=utf-8", + " ; charset=utf-8", + }) + public void throwsIllegalArgumentExceptionForDelimiterOnlyOrMissingMediaType( + final String inputType) throws UnsupportedEncodingException { + final var initialString = "key1=value1&key2=value2"; + final var rawResponse = new ByteArrayInputStream(initialString.getBytes("UTF-8")); + assertThrows( + IllegalArgumentException.class, + () -> _parseNodeFactory.getParseNode(inputType, rawResponse)); + } } diff --git a/components/serialization/form/src/test/java/com/microsoft/kiota/serialization/SerializationWriterFactoryTests.java b/components/serialization/form/src/test/java/com/microsoft/kiota/serialization/SerializationWriterFactoryTests.java index fdbb3797..154fa938 100644 --- a/components/serialization/form/src/test/java/com/microsoft/kiota/serialization/SerializationWriterFactoryTests.java +++ b/components/serialization/form/src/test/java/com/microsoft/kiota/serialization/SerializationWriterFactoryTests.java @@ -4,6 +4,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; public class SerializationWriterFactoryTests { private static final FormSerializationWriterFactory _serializationWriterFactory = @@ -30,4 +32,36 @@ public void throwsArgumentNullExceptionForNoContentType() { NullPointerException.class, () -> _serializationWriterFactory.getSerializationWriter("")); } + + @ParameterizedTest + @ValueSource( + strings = { + "application/x-www-form-urlencoded; charset=utf-8", + "application/x-www-form-urlencoded; charset=UTF-8", + "application/x-www-form-urlencoded; charset=us-ascii", + "APPLICATION/X-WWW-FORM-URLENCODED", + "APPLICATION/X-WWW-FORM-URLENCODED; CHARSET=UTF-8", + "Application/x-www-form-urlencoded", + "Application/x-www-form-urlencoded; charset=utf-8", + }) + public void getsWriterForContentTypeWithParametersOrCaseVariants(final String inputType) { + final var serializationWriter = + _serializationWriterFactory.getSerializationWriter(inputType); + assertNotNull(serializationWriter); + } + + @ParameterizedTest + @ValueSource( + strings = { + ";", + ";;", + "; charset=utf-8", + " ; charset=utf-8", + }) + public void throwsIllegalArgumentExceptionForDelimiterOnlyOrMissingMediaType( + final String inputType) { + assertThrows( + IllegalArgumentException.class, + () -> _serializationWriterFactory.getSerializationWriter(inputType)); + } }