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


The following commit(s) were added to refs/heads/master by this push:
     new 62f6edfd9 Keep chop from splitting a trailing surrogate pair (#1770)
62f6edfd9 is described below

commit 62f6edfd96008fd10cd22bf854cf4e8d2c008ae2
Author: alhuda <[email protected]>
AuthorDate: Wed Aug 12 21:11:19 2026 +0530

    Keep chop from splitting a trailing surrogate pair (#1770)
---
 src/main/java/org/apache/commons/lang3/StringUtils.java     | 4 ++++
 src/test/java/org/apache/commons/lang3/StringUtilsTest.java | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/src/main/java/org/apache/commons/lang3/StringUtils.java 
b/src/main/java/org/apache/commons/lang3/StringUtils.java
index 3feecd47a..aefc9aa4c 100644
--- a/src/main/java/org/apache/commons/lang3/StringUtils.java
+++ b/src/main/java/org/apache/commons/lang3/StringUtils.java
@@ -794,6 +794,10 @@ public static String chop(final String str) {
             return EMPTY;
         }
         final int lastIdx = strLen - 1;
+        // keep the cut off the middle of a surrogate pair so the result is 
never left holding a lone surrogate
+        if (splitsSurrogatePair(str, lastIdx)) {
+            return str.substring(0, lastIdx - 1);
+        }
         final String ret = str.substring(0, lastIdx);
         final char last = str.charAt(lastIdx);
         if (last == CharUtils.LF && ret.charAt(lastIdx - 1) == CharUtils.CR) {
diff --git a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java 
b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java
index 9bccaaf92..e27c9f90e 100644
--- a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java
@@ -399,6 +399,10 @@ void testChop() {
                 {null, null},
                 {"", ""},
                 {"a", ""},
+                // U+1F600: a trailing supplementary code point must be 
dropped whole, not split into a lone surrogate
+                {"\uD83D\uDE00", ""},
+                {"x\uD83D\uDE00", "x"},
+                {"\uD83D\uDE00x", "\uD83D\uDE00"},
         };
         for (final String[] chopCase : chopCases) {
             final String original = chopCase[0];

Reply via email to