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 2011ce3ba Stop ExtendedMessageFormat seekNonWs reading past the 
pattern end (#1740)
2011ce3ba is described below

commit 2011ce3ba2386669086882182dc41d76148e5489
Author: Javid Khan <[email protected]>
AuthorDate: Sat Jul 4 00:24:06 2026 +0530

    Stop ExtendedMessageFormat seekNonWs reading past the pattern end (#1740)
---
 src/changes/changes.xml                                   |  1 +
 .../apache/commons/lang3/text/ExtendedMessageFormat.java  | 10 ++++++----
 .../commons/lang3/text/ExtendedMessageFormatTest.java     | 15 +++++++++++++++
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 01a71beba..8696e5e9e 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -46,6 +46,7 @@ The <action> type attribute can be add,update,fix,remove.
   <body>
   <release version="3.21.0" date="YYY-MM-DD" description="This is a feature 
and maintenance release. Java 8 or later is required.">
     <!-- FIX -->
+    <action                   type="fix" dev="ggregory" due-to="Javid Khan, 
Gary Gregory">Stop ExtendedMessageFormat seekNonWs reading past the pattern 
end.</action>
     <action                   type="fix" dev="ggregory" due-to="ThrawnCA">Fix 
spelling and grammar in StringUtils #1486.</action>
     <action                   type="fix" dev="ggregory" due-to="Michael 
Hausegger, Gary Gregory">Add ConversionTest assertions to increase coverage 
#1489.</action>
     <action                   type="fix" dev="ggregory" due-to="Boda65665, 
Gary Gregory">Use Class&lt;?&gt; instead of Class&lt;? extends Object&gt; in 
MethodUtils #1491.</action>
diff --git 
a/src/main/java/org/apache/commons/lang3/text/ExtendedMessageFormat.java 
b/src/main/java/org/apache/commons/lang3/text/ExtendedMessageFormat.java
index ef5c97c7b..353303bdc 100644
--- a/src/main/java/org/apache/commons/lang3/text/ExtendedMessageFormat.java
+++ b/src/main/java/org/apache/commons/lang3/text/ExtendedMessageFormat.java
@@ -453,12 +453,14 @@ private int readArgumentIndex(final String pattern, final 
ParsePosition pos) {
      * @param pos current position
      */
     private void seekNonWs(final String pattern, final ParsePosition pos) {
-        int len;
         final char[] buffer = pattern.toCharArray();
-        do {
-            len = StrMatcher.splitMatcher().isMatch(buffer, pos.getIndex());
+        while (pos.getIndex() < buffer.length) {
+            final int len = StrMatcher.splitMatcher().isMatch(buffer, 
pos.getIndex());
+            if (len == 0) {
+                break;
+            }
             pos.setIndex(pos.getIndex() + len);
-        } while (len > 0 && pos.getIndex() < pattern.length());
+        }
     }
 
     /**
diff --git 
a/src/test/java/org/apache/commons/lang3/text/ExtendedMessageFormatTest.java 
b/src/test/java/org/apache/commons/lang3/text/ExtendedMessageFormatTest.java
index f07dde051..6ea31dcce 100644
--- a/src/test/java/org/apache/commons/lang3/text/ExtendedMessageFormatTest.java
+++ b/src/test/java/org/apache/commons/lang3/text/ExtendedMessageFormatTest.java
@@ -294,6 +294,21 @@ void testArgumentIndexTrailingWhitespaceAtEnd() {
         assertThrowsExactly(IllegalArgumentException.class, () -> new 
ExtendedMessageFormat("{0 ", new HashMap<>()));
     }
 
+    @Test
+    void testTruncatedFormatElementWithRegistry() {
+        // Sanity check to match JRE
+        assertThrowsExactly(IllegalArgumentException.class, () -> new 
MessageFormat("{"));
+        assertThrowsExactly(IllegalArgumentException.class, () -> new 
MessageFormat("{0,"));
+        assertThrowsExactly(IllegalArgumentException.class, () -> new 
MessageFormat("{0}extra{"));
+        // A format element left unterminated at the end of the pattern used 
to make the
+        // registry-based constructor seek one past the buffer and throw
+        // ArrayIndexOutOfBoundsException; it should report the documented
+        // IllegalArgumentException, as the plain constructor already does.
+        assertThrowsExactly(IllegalArgumentException.class, () -> new 
ExtendedMessageFormat("{", new HashMap<>()));
+        assertThrowsExactly(IllegalArgumentException.class, () -> new 
ExtendedMessageFormat("{0,", new HashMap<>()));
+        assertThrowsExactly(IllegalArgumentException.class, () -> new 
ExtendedMessageFormat("{0}extra{", new HashMap<>()));
+    }
+
     /**
      * Test the built-in choice format.
      */

Reply via email to