From 3c901de06f86d776f95d793587ca8dcbe53839c1 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Tue, 17 Mar 2026 11:02:32 -0700 Subject: [PATCH 01/10] fixing semi colon support --- .../JsonConfigurationParser.java | 22 +++++-- .../JsonConfigurationParserTest.java | 58 +++++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java index 824f111ae238..8bd820ba3f6c 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java @@ -30,14 +30,28 @@ static boolean isJsonContentType(String contentType) { return false; } - if (contentType.contains("/")) { - String mainType = contentType.split("/")[0]; - String subType = contentType.split("/")[1]; + // Remove parameters like "; charset=utf-8" if present + String cleanContentType = contentType.split(";")[0].trim(); + + if (cleanContentType.contains("/")) { + String[] parts = cleanContentType.split("/", 2); + if (parts.length < 2) { + return false; + } + + String mainType = parts[0].trim(); + String subType = parts[1].trim(); if (mainType.equalsIgnoreCase(acceptedMainType)) { if (subType.contains("+")) { + // Handle structured syntax suffixes like "application/vnd.api+json" List subtypes = Arrays.asList(subType.split("\\+")); - return subtypes.contains(acceptedSubType); + for (String sub : subtypes) { + if (sub.trim().equalsIgnoreCase(acceptedSubType)) { + return true; + } + } + return false; } else { return subType.equalsIgnoreCase(acceptedSubType); } diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java index 51cc010bb88a..d52aebeecfd6 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java @@ -25,11 +25,14 @@ public class JsonConfigurationParserTest { @Test public void isJsonContentType() { + // Basic valid JSON content types assertTrue(JsonConfigurationParser.isJsonContentType("application/json")); assertTrue(JsonConfigurationParser.isJsonContentType("application/api+json")); assertTrue(JsonConfigurationParser.isJsonContentType("application/json+activity")); assertTrue(JsonConfigurationParser.isJsonContentType("application/vnd.xxxx+json")); assertTrue(JsonConfigurationParser.isJsonContentType("application/vnd.microsoft.appconfig.document+json")); + + // Invalid content types assertFalse(JsonConfigurationParser.isJsonContentType("application")); assertFalse(JsonConfigurationParser.isJsonContentType("app/json")); assertFalse(JsonConfigurationParser.isJsonContentType("app/config")); @@ -38,6 +41,61 @@ public void isJsonContentType() { assertFalse(JsonConfigurationParser.isJsonContentType(null)); } + @Test + public void isJsonContentTypeWithParameters() { + // Content types with charset and other parameters + assertTrue(JsonConfigurationParser.isJsonContentType("application/json; charset=utf-8")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/json;charset=utf-8")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/json ; charset=utf-8")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/vnd.api+json; charset=utf-8")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/json; charset=ISO-8859-1")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/json;boundary=something")); + } + + @Test + public void isJsonContentTypeWithWhitespace() { + // Content types with various whitespace + assertTrue(JsonConfigurationParser.isJsonContentType(" application/json")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/json ")); + assertTrue(JsonConfigurationParser.isJsonContentType(" application/json ")); + assertTrue(JsonConfigurationParser.isJsonContentType("application / json")); // Note: This might fail if strict parsing is needed + assertTrue(JsonConfigurationParser.isJsonContentType("application/vnd.api + json")); // Whitespace around + + } + + @Test + public void isJsonContentTypeCaseInsensitive() { + // Case variations + assertTrue(JsonConfigurationParser.isJsonContentType("Application/Json")); + assertTrue(JsonConfigurationParser.isJsonContentType("APPLICATION/JSON")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/JSON")); + assertTrue(JsonConfigurationParser.isJsonContentType("Application/vnd.api+JSON")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/API+JSON")); + } + + @Test + public void isJsonContentTypeEdgeCases() { + // Edge cases and boundary conditions + assertFalse(JsonConfigurationParser.isJsonContentType("application/")); // Empty subtype + assertFalse(JsonConfigurationParser.isJsonContentType("/json")); // Empty main type + assertFalse(JsonConfigurationParser.isJsonContentType("/")); // Both empty + assertFalse(JsonConfigurationParser.isJsonContentType("application/xml")); + assertFalse(JsonConfigurationParser.isJsonContentType("text/json")); // Wrong main type + assertFalse(JsonConfigurationParser.isJsonContentType("application/json+xml")); // json not as suffix + assertFalse(JsonConfigurationParser.isJsonContentType("application/xml+html")); // No json at all + assertFalse(JsonConfigurationParser.isJsonContentType(" ")); // Only whitespace + } + + @Test + public void isJsonContentTypeComplexStructuredSyntax() { + // Complex structured syntax suffixes (RFC 6839) + assertTrue(JsonConfigurationParser.isJsonContentType("application/problem+json")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/merge-patch+json")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/json-patch+json")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/ld+json")); // JSON-LD + assertTrue(JsonConfigurationParser.isJsonContentType("application/hal+json")); + assertTrue(JsonConfigurationParser.isJsonContentType("application/vnd.geo+json")); + } + @Test public void parseJsonSettingTest() throws IOException { String key = "config.object"; From 6d76862f5be5d1a825b220c0aee6cdad4198d9ca Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Tue, 17 Mar 2026 11:12:36 -0700 Subject: [PATCH 02/10] Update CHANGELOG.md --- .../spring-cloud-azure-appconfiguration-config/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/CHANGELOG.md b/sdk/spring/spring-cloud-azure-appconfiguration-config/CHANGELOG.md index 16944b197b61..f65414f14330 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/CHANGELOG.md +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs Fixed +- Fixes a bug where ';' was ignored in json content type checking. + ### Other Changes ## 7.1.0 (2026-03-11) From d4bfd388876f9700fb075ea1fe2b7602f508a304 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Tue, 17 Mar 2026 11:48:34 -0700 Subject: [PATCH 03/10] bug fix --- .../implementation/JsonConfigurationParser.java | 11 ++++------- .../implementation/JsonConfigurationParserTest.java | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java index 8bd820ba3f6c..238cf0ff2752 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java @@ -45,13 +45,10 @@ static boolean isJsonContentType(String contentType) { if (mainType.equalsIgnoreCase(acceptedMainType)) { if (subType.contains("+")) { // Handle structured syntax suffixes like "application/vnd.api+json" - List subtypes = Arrays.asList(subType.split("\\+")); - for (String sub : subtypes) { - if (sub.trim().equalsIgnoreCase(acceptedSubType)) { - return true; - } - } - return false; + // According to RFC 6839, the suffix is the part after the last + + String[] subtypes = subType.split("\\+"); + String suffix = subtypes[subtypes.length - 1].trim(); + return suffix.equalsIgnoreCase(acceptedSubType); } else { return subType.equalsIgnoreCase(acceptedSubType); } diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java index d52aebeecfd6..a49a5af94f70 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java @@ -28,7 +28,6 @@ public void isJsonContentType() { // Basic valid JSON content types assertTrue(JsonConfigurationParser.isJsonContentType("application/json")); assertTrue(JsonConfigurationParser.isJsonContentType("application/api+json")); - assertTrue(JsonConfigurationParser.isJsonContentType("application/json+activity")); assertTrue(JsonConfigurationParser.isJsonContentType("application/vnd.xxxx+json")); assertTrue(JsonConfigurationParser.isJsonContentType("application/vnd.microsoft.appconfig.document+json")); @@ -39,6 +38,7 @@ public void isJsonContentType() { assertFalse(JsonConfigurationParser.isJsonContentType("application/config")); assertFalse(JsonConfigurationParser.isJsonContentType("")); assertFalse(JsonConfigurationParser.isJsonContentType(null)); + assertFalse(JsonConfigurationParser.isJsonContentType("application/json+activity")); // activity is the suffix, not json } @Test From 9a5c5aefdb4871620d73862f87428048ab278eb6 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Tue, 17 Mar 2026 14:23:02 -0700 Subject: [PATCH 04/10] review comments --- .../spring-cloud-azure-appconfiguration-config/CHANGELOG.md | 2 +- .../config/implementation/JsonConfigurationParser.java | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/CHANGELOG.md b/sdk/spring/spring-cloud-azure-appconfiguration-config/CHANGELOG.md index f65414f14330..c7b463921ac1 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/CHANGELOG.md +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/CHANGELOG.md @@ -8,7 +8,7 @@ ### Bugs Fixed -- Fixes a bug where ';' was ignored in json content type checking. +- Fixes a bug where ';' was ignored in JSON content type checking. ### Other Changes diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java index 238cf0ff2752..af88abd87be0 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java @@ -2,10 +2,8 @@ // Licensed under the MIT License. package com.azure.spring.cloud.appconfiguration.config.implementation; -import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; From 7ebf9a0893198d9e5dcffaab631f3f821da4417d Mon Sep 17 00:00:00 2001 From: Matthew Metcalf Date: Tue, 17 Mar 2026 14:27:58 -0700 Subject: [PATCH 05/10] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../JsonConfigurationParser.java | 57 +++++++++++-------- .../JsonConfigurationParserTest.java | 8 ++- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java index af88abd87be0..1082bf8cb599 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java @@ -28,32 +28,41 @@ static boolean isJsonContentType(String contentType) { return false; } - // Remove parameters like "; charset=utf-8" if present - String cleanContentType = contentType.split(";")[0].trim(); - - if (cleanContentType.contains("/")) { - String[] parts = cleanContentType.split("/", 2); - if (parts.length < 2) { - return false; - } - - String mainType = parts[0].trim(); - String subType = parts[1].trim(); - - if (mainType.equalsIgnoreCase(acceptedMainType)) { - if (subType.contains("+")) { - // Handle structured syntax suffixes like "application/vnd.api+json" - // According to RFC 6839, the suffix is the part after the last + - String[] subtypes = subType.split("\\+"); - String suffix = subtypes[subtypes.length - 1].trim(); - return suffix.equalsIgnoreCase(acceptedSubType); - } else { - return subType.equalsIgnoreCase(acceptedSubType); - } - } + // Remove parameters like "; charset=utf-8" if present, without using regex-based split + String cleanContentType; + int semicolonIndex = contentType.indexOf(';'); + if (semicolonIndex >= 0) { + cleanContentType = contentType.substring(0, semicolonIndex).trim(); + } else { + cleanContentType = contentType.trim(); + } + + if (cleanContentType.isEmpty()) { + return false; + } + + int slashIndex = cleanContentType.indexOf('/'); + if (slashIndex <= 0 || slashIndex == cleanContentType.length() - 1) { + // No slash, slash at start, or no subtype + return false; + } + + String mainType = cleanContentType.substring(0, slashIndex).trim(); + String subType = cleanContentType.substring(slashIndex + 1).trim(); + + if (!mainType.equalsIgnoreCase(acceptedMainType) || subType.isEmpty()) { + return false; } - return false; + // Handle structured syntax suffixes like "application/vnd.api+json". + // According to RFC 6839, the suffix is the part after the last '+'. + int plusIndex = subType.lastIndexOf('+'); + if (plusIndex >= 0 && plusIndex < subType.length() - 1) { + String suffix = subType.substring(plusIndex + 1).trim(); + return suffix.equalsIgnoreCase(acceptedSubType); + } else { + return subType.equalsIgnoreCase(acceptedSubType); + } } static Map parseJsonSetting(ConfigurationSetting setting) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java index a49a5af94f70..52641e43abc7 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java @@ -54,12 +54,14 @@ public void isJsonContentTypeWithParameters() { @Test public void isJsonContentTypeWithWhitespace() { - // Content types with various whitespace + // Content types with various whitespace at the boundaries assertTrue(JsonConfigurationParser.isJsonContentType(" application/json")); assertTrue(JsonConfigurationParser.isJsonContentType("application/json ")); assertTrue(JsonConfigurationParser.isJsonContentType(" application/json ")); - assertTrue(JsonConfigurationParser.isJsonContentType("application / json")); // Note: This might fail if strict parsing is needed - assertTrue(JsonConfigurationParser.isJsonContentType("application/vnd.api + json")); // Whitespace around + + + // Internal whitespace around '/' or '+' is not allowed by RFC 7231/6838 token rules + assertFalse(JsonConfigurationParser.isJsonContentType("application / json")); + assertFalse(JsonConfigurationParser.isJsonContentType("application/vnd.api + json")); } @Test From e3b64f9a960b5be640572e60dc2a7744c21d5fd7 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Tue, 17 Mar 2026 15:17:37 -0700 Subject: [PATCH 06/10] remove release notes --- .../implementation/JsonConfigurationParser.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java index 1082bf8cb599..4e3fa41f15be 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java @@ -47,8 +47,15 @@ static boolean isJsonContentType(String contentType) { return false; } - String mainType = cleanContentType.substring(0, slashIndex).trim(); - String subType = cleanContentType.substring(slashIndex + 1).trim(); + String mainType = cleanContentType.substring(0, slashIndex); + String subType = cleanContentType.substring(slashIndex + 1); + + // RFC 7231/6838: tokens cannot contain whitespace + // Check for internal whitespace (after initial trim of the whole content type) + if (mainType.contains(" ") || mainType.contains("\t") || + subType.contains(" ") || subType.contains("\t")) { + return false; + } if (!mainType.equalsIgnoreCase(acceptedMainType) || subType.isEmpty()) { return false; @@ -58,7 +65,7 @@ static boolean isJsonContentType(String contentType) { // According to RFC 6839, the suffix is the part after the last '+'. int plusIndex = subType.lastIndexOf('+'); if (plusIndex >= 0 && plusIndex < subType.length() - 1) { - String suffix = subType.substring(plusIndex + 1).trim(); + String suffix = subType.substring(plusIndex + 1); return suffix.equalsIgnoreCase(acceptedSubType); } else { return subType.equalsIgnoreCase(acceptedSubType); From b55a875eeddd2e2562ff5130cc9a26b2e81d5cb9 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Wed, 18 Mar 2026 09:30:40 -0700 Subject: [PATCH 07/10] Update JsonConfigurationParser.java --- .../config/implementation/JsonConfigurationParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java index 4e3fa41f15be..7136f6fcc9a9 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java @@ -52,7 +52,7 @@ static boolean isJsonContentType(String contentType) { // RFC 7231/6838: tokens cannot contain whitespace // Check for internal whitespace (after initial trim of the whole content type) - if (mainType.contains(" ") || mainType.contains("\t") || + if (mainType.contains(" ") || mainType.contains("\t") || subType.contains(" ") || subType.contains("\t")) { return false; } From d19123fb46d1deb115714eb1c3f8895cfd619a4f Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Wed, 18 Mar 2026 09:31:29 -0700 Subject: [PATCH 08/10] Update JsonConfigurationParser.java --- .../config/implementation/JsonConfigurationParser.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java index 7136f6fcc9a9..9a9ae1a44300 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java @@ -52,8 +52,7 @@ static boolean isJsonContentType(String contentType) { // RFC 7231/6838: tokens cannot contain whitespace // Check for internal whitespace (after initial trim of the whole content type) - if (mainType.contains(" ") || mainType.contains("\t") || - subType.contains(" ") || subType.contains("\t")) { + if (mainType.contains(" ") || mainType.contains("\t") || subType.contains(" ") || subType.contains("\t")) { return false; } From ba4877f4e309eb0e209531f7eec7b18dcd1ad7d3 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Thu, 19 Mar 2026 09:47:24 -0700 Subject: [PATCH 09/10] Update JsonConfigurationParser.java --- .../JsonConfigurationParser.java | 48 +++++-------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java index 9a9ae1a44300..9668b51b6d11 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java @@ -21,54 +21,32 @@ final class JsonConfigurationParser { private static final ObjectMapper MAPPER = JsonMapper.builder().enable(JsonReadFeature.ALLOW_JAVA_COMMENTS).build(); static boolean isJsonContentType(String contentType) { - String acceptedMainType = "application"; - String acceptedSubType = "json"; - if (!StringUtils.hasText(contentType)) { return false; } - // Remove parameters like "; charset=utf-8" if present, without using regex-based split - String cleanContentType; - int semicolonIndex = contentType.indexOf(';'); - if (semicolonIndex >= 0) { - cleanContentType = contentType.substring(0, semicolonIndex).trim(); - } else { - cleanContentType = contentType.trim(); - } - - if (cleanContentType.isEmpty()) { - return false; - } + contentType = contentType.strip().toLowerCase(); + String mimeType = contentType.split(";")[0].strip(); - int slashIndex = cleanContentType.indexOf('/'); - if (slashIndex <= 0 || slashIndex == cleanContentType.length() - 1) { - // No slash, slash at start, or no subtype + String[] typeParts = mimeType.split("/"); + if (typeParts.length != 2) { return false; } - String mainType = cleanContentType.substring(0, slashIndex); - String subType = cleanContentType.substring(slashIndex + 1); - - // RFC 7231/6838: tokens cannot contain whitespace - // Check for internal whitespace (after initial trim of the whole content type) - if (mainType.contains(" ") || mainType.contains("\t") || subType.contains(" ") || subType.contains("\t")) { + String mainType = typeParts[0]; + String subType = typeParts[1]; + + if (!mainType.equals("application")) { return false; } - if (!mainType.equalsIgnoreCase(acceptedMainType) || subType.isEmpty()) { - return false; + String[] subTypes = subType.split("\\+"); + // Check if the last part (suffix) is "json" + if (subTypes.length > 0 && subTypes[subTypes.length - 1].equals("json")) { + return true; } - // Handle structured syntax suffixes like "application/vnd.api+json". - // According to RFC 6839, the suffix is the part after the last '+'. - int plusIndex = subType.lastIndexOf('+'); - if (plusIndex >= 0 && plusIndex < subType.length() - 1) { - String suffix = subType.substring(plusIndex + 1); - return suffix.equalsIgnoreCase(acceptedSubType); - } else { - return subType.equalsIgnoreCase(acceptedSubType); - } + return false; } static Map parseJsonSetting(ConfigurationSetting setting) From f7186d11096cdca6f46039571e069d1098a68be5 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Thu, 19 Mar 2026 13:33:27 -0700 Subject: [PATCH 10/10] Update JsonConfigurationParser.java --- .../config/implementation/JsonConfigurationParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java index 9668b51b6d11..a7d1a00a0748 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java @@ -36,7 +36,7 @@ static boolean isJsonContentType(String contentType) { String mainType = typeParts[0]; String subType = typeParts[1]; - if (!mainType.equals("application")) { + if (!"application".equals(mainType)) { return false; }