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 bdd674f7c fix CharSequenceUtils.lastIndexOf for supplementary code 
points (#1684)
bdd674f7c is described below

commit bdd674f7c64dbc2c8ff043ee995fcd9f6f59a13b
Author: alhuda <[email protected]>
AuthorDate: Wed Jun 3 05:18:33 2026 +0530

    fix CharSequenceUtils.lastIndexOf for supplementary code points (#1684)
    
    Co-authored-by: alhudz <[email protected]>
---
 src/main/java/org/apache/commons/lang3/CharSequenceUtils.java     | 8 +++-----
 .../org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java    | 7 +++++++
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java 
b/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java
index 9fc1fd84a..4fd9445b1 100644
--- a/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java
+++ b/src/main/java/org/apache/commons/lang3/CharSequenceUtils.java
@@ -262,11 +262,9 @@ static int lastIndexOf(final CharSequence cs, final int 
searchChar, int start) {
         //NOTE - we must do a forward traversal for this to avoid duplicating 
code points
         if (searchChar <= Character.MAX_CODE_POINT) {
             final char[] chars = Character.toChars(searchChar);
-            //make sure it's not the last index
-            if (start == sz - 1) {
-                return NOT_FOUND;
-            }
-            for (int i = start; i >= 0; i--) {
+            // A supplementary code point spans two chars, so its high 
surrogate can start no later
+            // than sz - 2; clamp the search origin instead of bailing out 
when start is the last index.
+            for (int i = Math.min(start, sz - 2); i >= 0; i--) {
                 final char high = cs.charAt(i);
                 final char low = cs.charAt(i + 1);
                 if (chars[0] == high && chars[1] == low) {
diff --git 
a/src/test/java/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java 
b/src/test/java/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java
index 98a292e9e..4c0d827c8 100644
--- a/src/test/java/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java
+++ b/src/test/java/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java
@@ -610,6 +610,13 @@ void testLastIndexOf_char() {
         assertEquals(5, StringUtils.lastIndexOf("aabaabaa", 'b'));
 
         assertEquals(5, StringUtils.lastIndexOf(new StringBuilder("aabaabaa"), 
'b'));
+
+        // LANG-1300: supplementary code points searched in a non-String 
CharSequence must agree with String
+        final int supp = 0x2070E;
+        final String suppStr = new String(Character.toChars(supp));
+        assertEquals(suppStr.lastIndexOf(supp), StringUtils.lastIndexOf(new 
StringBuilder(suppStr), supp));
+        assertEquals(("x" + suppStr).lastIndexOf(supp), 
StringUtils.lastIndexOf(new StringBuilder("x" + suppStr), supp));
+        assertEquals((suppStr + "y").lastIndexOf(supp), 
StringUtils.lastIndexOf(new StringBuilder(suppStr + "y"), supp));
     }
 
     @Test

Reply via email to