You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2026/02/12 00:01:28 UTC

(commons-lang) branch master updated: StringUtils.abbreviate(String, String, int) contract violations (#1572)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new 4a6a98432 StringUtils.abbreviate(String, String, int) contract violations (#1572)
4a6a98432 is described below

commit 4a6a98432f57e6286ba48777268a26b68dfd9547
Author: ThrawnCA <ca...@smartservice.qld.gov.au>
AuthorDate: Thu Feb 12 10:01:22 2026 +1000

    StringUtils.abbreviate(String, String, int) contract violations (#1572)
    
    * add unit tests showing mishandling of null abbrevMarker
    
    * 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)
    
    * add unit tests showing 'abbreviate' contract violations
    
    - Abbreviated strings should always retain the 'offset' character
    
    * remove surplus blank lines from tests
    
    * fix StringUtils.abbreviate for short strings
    
    Adjust logic so it doesn't overwrite the offset value and get confused about which character to preserve.
    Instead, just return immediately if the offset is so close to the end that no ending abbrevMarker is possible.
---
 src/main/java/org/apache/commons/lang3/StringUtils.java      | 12 +++---------
 .../org/apache/commons/lang3/StringUtilsAbbreviateTest.java  |  5 +++++
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/src/main/java/org/apache/commons/lang3/StringUtils.java b/src/main/java/org/apache/commons/lang3/StringUtils.java
index 162724af0..bcc26aaf6 100644
--- a/src/main/java/org/apache/commons/lang3/StringUtils.java
+++ b/src/main/java/org/apache/commons/lang3/StringUtils.java
@@ -369,11 +369,8 @@ public static String abbreviate(final String str, String abbrevMarker, int offse
         if (strLen <= maxWidth) {
             return str;
         }
-        if (offset > strLen) {
-            offset = strLen;
-        }
-        if (strLen - offset < maxWidth - abbrevMarkerLength) {
-            offset = strLen - (maxWidth - abbrevMarkerLength);
+        if (strLen - offset <= maxWidth - abbrevMarkerLength) {
+            return abbrevMarker + str.substring(strLen - (maxWidth - abbrevMarkerLength));
         }
         if (offset <= abbrevMarkerLength + 1) {
             return str.substring(0, maxWidth - abbrevMarkerLength) + abbrevMarker;
@@ -381,10 +378,7 @@ public static String abbreviate(final String str, String abbrevMarker, int offse
         if (maxWidth < minAbbrevWidthOffset) {
             throw new IllegalArgumentException(String.format("Minimum abbreviation width with offset is %d", minAbbrevWidthOffset));
         }
-        if (offset + maxWidth - abbrevMarkerLength < strLen) {
-            return abbrevMarker + abbreviate(str.substring(offset), abbrevMarker, maxWidth - abbrevMarkerLength);
-        }
-        return abbrevMarker + str.substring(strLen - (maxWidth - abbrevMarkerLength));
+        return abbrevMarker + abbreviate(str.substring(offset), abbrevMarker, maxWidth - abbrevMarkerLength);
     }
 
     /**
diff --git a/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java b/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java
index 8ef0cfc85..cf947ee11 100644
--- a/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java
+++ b/src/test/java/org/apache/commons/lang3/StringUtilsAbbreviateTest.java
@@ -101,6 +101,8 @@ 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 +165,9 @@ 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