From 69df22c2c0b17fb30e8b7afc7f17f5b7131d35a8 Mon Sep 17 00:00:00 2001 From: ThrawnCA Date: Sat, 17 Jan 2026 10:41:37 +1000 Subject: [PATCH 1/4] add unit tests showing mishandling of null abbrevMarker --- .../apache/commons/lang3/StringUtilsAbbreviateTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java b/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java index 49a188d06de..8ef0cfc855c 100644 --- a/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java +++ b/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java @@ -107,7 +107,7 @@ void testAbbreviate_StringIntInt() { void testAbbreviate_StringStringInt() { assertNull(StringUtils.abbreviate(null, null, 10)); assertNull(StringUtils.abbreviate(null, "...", 10)); - assertEquals("paranaguacu", StringUtils.abbreviate("paranaguacu", null, 10)); + assertEquals("paranaguac", StringUtils.abbreviate("paranaguacu", null, 10)); assertEquals("", StringUtils.abbreviate("", "...", 2)); assertEquals("wai**", StringUtils.abbreviate("waiheke", "**", 5)); assertEquals("And af,,,,", StringUtils.abbreviate("And after a long time, he finally met his son.", ",,,,", 10)); @@ -130,6 +130,12 @@ void testAbbreviate_StringStringIntInt() { assertNull(StringUtils.abbreviate(null, "...", 10, 12)); assertEquals("", StringUtils.abbreviate("", null, 0, 10)); assertEquals("", StringUtils.abbreviate("", "...", 2, 10)); + assertEquals("abcdefg", StringUtils.abbreviate("abcdefg", null, 2, 10)); + assertEquals("abcdefg", StringUtils.abbreviate("abcdefg", "", 2, 10)); + assertEquals("abc", StringUtils.abbreviate("abcdefg", null, 0, 3)); + assertEquals("cde", StringUtils.abbreviate("abcdefg", null, 2, 3)); + assertEquals("abc", StringUtils.abbreviate("abcdefg", "", 0, 3)); + assertEquals("cde", StringUtils.abbreviate("abcdefg", "", 2, 3)); assertIllegalArgumentException(() -> StringUtils.abbreviate("abcdefghij", "::", 0, 2), "StringUtils.abbreviate expecting IllegalArgumentException"); assertIllegalArgumentException(() -> StringUtils.abbreviate("abcdefghij", "!!!", 5, 6), From 1ca5aeb57703b314d2d3ea6bd33ac85bf92e8e60 Mon Sep 17 00:00:00 2001 From: ThrawnCA Date: Sat, 17 Jan 2026 10:43:16 +1000 Subject: [PATCH 2/4] fix handling of null abbrevMarker - treat null marker as empty string - ensure offset and maxWidth are applied as usual (simple 'substring' won't cut it) --- .../java/org/apache/commons/lang3/StringUtils.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/apache/commons/lang3/StringUtils.java b/src/main/java/org/apache/commons/lang3/StringUtils.java index 1ae37530616..4616abfc024 100644 --- a/src/main/java/org/apache/commons/lang3/StringUtils.java +++ b/src/main/java/org/apache/commons/lang3/StringUtils.java @@ -350,13 +350,13 @@ public static String abbreviate(final String str, final String abbrevMarker, fin * @throws IllegalArgumentException if the width is too small. * @since 3.6 */ - public static String abbreviate(final String str, final String abbrevMarker, int offset, final int maxWidth) { - if (isNotEmpty(str) && EMPTY.equals(abbrevMarker) && maxWidth > 0) { - return substring(str, 0, maxWidth); - } - if (isAnyEmpty(str, abbrevMarker)) { + public static String abbreviate(final String str, String abbrevMarker, int offset, final int maxWidth) { + if (isEmpty(str)) { return str; } + if (abbrevMarker == null) { + abbrevMarker = EMPTY; + } final int abbrevMarkerLength = abbrevMarker.length(); final int minAbbrevWidth = abbrevMarkerLength + 1; final int minAbbrevWidthOffset = abbrevMarkerLength + abbrevMarkerLength + 1; From 45a2f607b8f6039c197d0e8a8da24f407754bbb8 Mon Sep 17 00:00:00 2001 From: ThrawnCA Date: Mon, 19 Jan 2026 22:01:10 +1000 Subject: [PATCH 3/4] add unit tests showing 'abbreviate' contract violations - Abbreviated strings should always retain the 'offset' character --- .../apache/commons/lang3/StringUtilsAbbreviateTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java b/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java index 8ef0cfc855c..ccd2ad21168 100644 --- a/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java +++ b/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java @@ -101,6 +101,9 @@ void testAbbreviate_StringIntInt() { assertAbbreviateWithOffset("...ijklmno", 15, 10); assertAbbreviateWithOffset("...ijklmno", 16, 10); assertAbbreviateWithOffset("...ijklmno", Integer.MAX_VALUE, 10); + + // abbreviating a shorter string allows maxWidth < 7 + assertEquals("...efg", StringUtils.abbreviate("abcdefg", 5, 6)); } @Test @@ -163,6 +166,10 @@ void testAbbreviate_StringStringIntInt() { assertAbbreviateWithAbbrevMarkerAndOffset("999ijklmno", "999", 15, 10); assertAbbreviateWithAbbrevMarkerAndOffset("_ghijklmno", "_", 16, 10); assertAbbreviateWithAbbrevMarkerAndOffset("+ghijklmno", "+", Integer.MAX_VALUE, 10); + + // abbreviating a shorter string allows maxWidth < abbrevMarker.length * 2 + 1 + assertEquals("..de", StringUtils.abbreviate("abcde", "..", 4, 4)); + assertEquals("....fg", StringUtils.abbreviate("abcdefg", "....", 5, 6)); } // Fixed LANG-1463 From fab93ea5457e5edbc286aaf46902be82e190c3f9 Mon Sep 17 00:00:00 2001 From: ThrawnCA Date: Mon, 19 Jan 2026 22:24:59 +1000 Subject: [PATCH 4/4] remove surplus blank lines from tests --- .../org/apache/commons/lang3/StringUtilsAbbreviateTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java b/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java index ccd2ad21168..cf947ee111c 100644 --- a/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java +++ b/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java @@ -101,7 +101,6 @@ void testAbbreviate_StringIntInt() { assertAbbreviateWithOffset("...ijklmno", 15, 10); assertAbbreviateWithOffset("...ijklmno", 16, 10); assertAbbreviateWithOffset("...ijklmno", Integer.MAX_VALUE, 10); - // abbreviating a shorter string allows maxWidth < 7 assertEquals("...efg", StringUtils.abbreviate("abcdefg", 5, 6)); } @@ -166,7 +165,6 @@ void testAbbreviate_StringStringIntInt() { assertAbbreviateWithAbbrevMarkerAndOffset("999ijklmno", "999", 15, 10); assertAbbreviateWithAbbrevMarkerAndOffset("_ghijklmno", "_", 16, 10); assertAbbreviateWithAbbrevMarkerAndOffset("+ghijklmno", "+", Integer.MAX_VALUE, 10); - // abbreviating a shorter string allows maxWidth < abbrevMarker.length * 2 + 1 assertEquals("..de", StringUtils.abbreviate("abcde", "..", 4, 4)); assertEquals("....fg", StringUtils.abbreviate("abcdefg", "....", 5, 6));