This is an automated email from the ASF dual-hosted git repository. garydgregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-lang.git
commit ed29e9e2d76a7cc5cffc95ef45d8b10b6b665964 Author: Gary Gregory <[email protected]> AuthorDate: Thu Oct 15 19:25:09 2026 -0400 Expand JSON_STYLE CharSequence test coverage and documentation Cover map values, object-array elements, and CharBuffer values. Verify escaping of quotes, backslashes, and control characters in ordinary text. Document that CharSequence values are quoted and escaped even when they resemble JSON objects or arrays. --- .../commons/lang3/builder/ToStringStyle.java | 7 ++++++- .../lang3/builder/JsonToStringStyleTest.java | 24 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/lang3/builder/ToStringStyle.java b/src/main/java/org/apache/commons/lang3/builder/ToStringStyle.java index b2729381b..b1ed4c16d 100644 --- a/src/main/java/org/apache/commons/lang3/builder/ToStringStyle.java +++ b/src/main/java/org/apache/commons/lang3/builder/ToStringStyle.java @@ -565,10 +565,15 @@ private Object readResolve() { * <pre> * {"name": "John Doe", "age": 33, "smoker": true} * </pre> - * + * <p> + * Values implementing {@link CharSequence}, including {@link String}, {@link StringBuilder}, and {@link StringBuffer}, are quoted and escaped as JSON + * strings, even when their text resembles a JSON object or array. + * </p> + * <p> * <strong>Note:</strong> Since field names are mandatory in JSON, this ToStringStyle will throw an {@link UnsupportedOperationException} if no field name * is passed in while appending. Furthermore This ToStringStyle will only generate valid JSON if referenced objects also produce JSON when calling * {@code toString()} on them. + * </p> * * @since 3.4 * @see <a href="https://www.json.org/">json.org</a> diff --git a/src/test/java/org/apache/commons/lang3/builder/JsonToStringStyleTest.java b/src/test/java/org/apache/commons/lang3/builder/JsonToStringStyleTest.java index 702fdbf94..db9e32361 100644 --- a/src/test/java/org/apache/commons/lang3/builder/JsonToStringStyleTest.java +++ b/src/test/java/org/apache/commons/lang3/builder/JsonToStringStyleTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.nio.CharBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -272,9 +273,32 @@ void testCharSequenceIsEscaped() { assertEquals(expected, new ToStringBuilder(base).append("name", text).toString()); assertEquals(expected, new ToStringBuilder(base).append("name", new StringBuilder(text)).toString()); assertEquals(expected, new ToStringBuilder(base).append("name", new StringBuffer(text)).toString()); + assertEquals(expected, new ToStringBuilder(base).append("name", CharBuffer.wrap(text)).toString()); assertEquals("{\"name\":[\"[1]\"]}", new ToStringBuilder(base).append("name", Arrays.asList(new StringBuilder("[1]"))).toString()); } + @Test + void testCharSequenceMapValueIsEscaped() { + assertEquals("{\"name\":{\"key\":\"{},\\\"admin\\\":true,\\\"x\\\":{}\"}}", + new ToStringBuilder(base).append("name", Collections.singletonMap("key", new StringBuilder("{},\"admin\":true,\"x\":{}"))).toString()); + } + + @Test + void testCharSequenceObjectArrayElementIsEscaped() { + assertEquals("{\"name\":[\"{},\\\"admin\\\":true,\\\"x\\\":{}\"]}", + new ToStringBuilder(base).append("name", new Object[] { new StringBuilder("{},\"admin\":true,\"x\":{}") }).toString()); + } + + @Test + void testCharSequencePlainTextIsEscaped() { + final String text = "text\"\\\n\r\t\b\f"; + final String expected = "{\"name\":\"text\\\"\\\\\\n\\r\\t\\b\\f\"}"; + assertEquals(expected, new ToStringBuilder(base).append("name", text).toString()); + assertEquals(expected, new ToStringBuilder(base).append("name", new StringBuilder(text)).toString()); + assertEquals(expected, new ToStringBuilder(base).append("name", new StringBuffer(text)).toString()); + assertEquals(expected, new ToStringBuilder(base).append("name", CharBuffer.wrap(text)).toString()); + } + @Test void testCombineListAndEnum() { final Teacher teacher = new Teacher();
