This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new eeeb762269 Improve case-insenstive comparisons.
eeeb762269 is described below
commit eeeb76226932390e5a47031dfa03c4f891dfc4ab
Author: Mark Thomas <[email protected]>
AuthorDate: Fri May 22 18:38:50 2026 +0100
Improve case-insenstive comparisons.
Update documentation to expand supported range from 0x00-0x7F to
0x00-0xFF where appropriate.
Based on PR #1010 by Chenjp
---
java/org/apache/catalina/mapper/Mapper.java | 16 ++++++++++++++--
java/org/apache/tomcat/util/buf/ByteChunk.java | 10 ++++++----
java/org/apache/tomcat/util/buf/CharChunk.java | 18 ++++++++++++++++--
java/org/apache/tomcat/util/buf/MessageBytes.java | 10 +++++++++-
test/org/apache/tomcat/util/buf/TestByteChunk.java | 10 ++++++++++
test/org/apache/tomcat/util/http/TestMimeHeaders.java | 13 ++++++++++++-
6 files changed, 67 insertions(+), 10 deletions(-)
diff --git a/java/org/apache/catalina/mapper/Mapper.java
b/java/org/apache/catalina/mapper/Mapper.java
index df258eaa8c..9042292cb4 100644
--- a/java/org/apache/catalina/mapper/Mapper.java
+++ b/java/org/apache/catalina/mapper/Mapper.java
@@ -1373,8 +1373,20 @@ public final class Mapper {
len = end - start;
}
for (int i = 0; (i < len) && (result == 0); i++) {
- int nameLower = Ascii.toLower(c[i + start]);
- int compareLower = Ascii.toLower(compareTo.charAt(i));
+ char cName = c[i + start];
+ char cCompare = compareTo.charAt(i);
+ int nameLower;
+ int compareLower;
+ if (cName > 0xFF) {
+ nameLower = Character.toLowerCase(cName);
+ } else {
+ nameLower = Ascii.toLower(cName);
+ }
+ if (cCompare > 0xFF) {
+ compareLower = Character.toLowerCase(cCompare);
+ } else {
+ compareLower = Ascii.toLower(compareTo.charAt(i));
+ }
if (nameLower > compareLower) {
result = 1;
} else if (nameLower < compareLower) {
diff --git a/java/org/apache/tomcat/util/buf/ByteChunk.java
b/java/org/apache/tomcat/util/buf/ByteChunk.java
index 9d1a418c22..5733a6857a 100644
--- a/java/org/apache/tomcat/util/buf/ByteChunk.java
+++ b/java/org/apache/tomcat/util/buf/ByteChunk.java
@@ -705,7 +705,7 @@ public final class ByteChunk extends AbstractChunk {
/**
* Compares the message bytes to the specified String object.
* <p>
- * NOTE: This only works for characters in the range 0-127.
+ * NOTE: This only works for characters in the range 0-255.
*
* @param s the String to compare
*
@@ -719,7 +719,8 @@ public final class ByteChunk extends AbstractChunk {
}
int off = start;
for (int i = 0; i < len; i++) {
- if (Ascii.toLower(b[off++]) != Ascii.toLower(s.charAt(i))) {
+ char c = s.charAt(i);
+ if (c > 0xFF || Ascii.toLower(b[off++]) != Ascii.toLower(c)) {
return false;
}
}
@@ -874,7 +875,7 @@ public final class ByteChunk extends AbstractChunk {
/**
* Returns true if the buffer starts with the specified string when tested
in a case-insensitive manner.
* <p>
- * NOTE: This only works for characters in the range 0-127.
+ * NOTE: This only works for characters in the range 0-255.
*
* @param s the string
* @param pos The position
@@ -889,7 +890,8 @@ public final class ByteChunk extends AbstractChunk {
}
int off = start + pos;
for (int i = 0; i < len; i++) {
- if (Ascii.toLower(b[off++]) != Ascii.toLower(s.charAt(i))) {
+ char c = s.charAt(i);
+ if (c > 0xFF || Ascii.toLower(b[off++]) != Ascii.toLower(c)) {
return false;
}
}
diff --git a/java/org/apache/tomcat/util/buf/CharChunk.java
b/java/org/apache/tomcat/util/buf/CharChunk.java
index f4b50aa3e4..4c1ea17193 100644
--- a/java/org/apache/tomcat/util/buf/CharChunk.java
+++ b/java/org/apache/tomcat/util/buf/CharChunk.java
@@ -500,7 +500,14 @@ public final class CharChunk extends AbstractChunk
implements CharSequence {
}
int off = start;
for (int i = 0; i < len; i++) {
- if (Ascii.toLower(c[off++]) != Ascii.toLower(s.charAt(i))) {
+ char c1 = c[off++];
+ char c2 = s.charAt(i);
+ // Use ASCII short-cut if possible
+ if (c1 > 0xFF || c2 > 0xFF) {
+ if (Character.toLowerCase(c1) != Character.toLowerCase(c2)) {
+ return false;
+ }
+ } else if (Ascii.toLower(c1) != Ascii.toLower(c2)) {
return false;
}
}
@@ -590,7 +597,14 @@ public final class CharChunk extends AbstractChunk
implements CharSequence {
}
int off = start + pos;
for (int i = 0; i < len; i++) {
- if (Ascii.toLower(c[off++]) != Ascii.toLower(s.charAt(i))) {
+ char c1 = c[off++];
+ char c2 = s.charAt(i);
+ // Use ASCII short-cut if possible
+ if (c1 > 0xFF || c2 > 0xFF) {
+ if (Character.toLowerCase(c1) != Character.toLowerCase(c2)) {
+ return false;
+ }
+ } else if (Ascii.toLower(c1) != Ascii.toLower(c2)) {
return false;
}
}
diff --git a/java/org/apache/tomcat/util/buf/MessageBytes.java
b/java/org/apache/tomcat/util/buf/MessageBytes.java
index 31dd69a90e..6e91c7ddb7 100644
--- a/java/org/apache/tomcat/util/buf/MessageBytes.java
+++ b/java/org/apache/tomcat/util/buf/MessageBytes.java
@@ -511,9 +511,17 @@ public final class MessageBytes implements Cloneable,
Serializable {
}
for (int i = 0; i < s.length(); i++) {
- if (Ascii.toLower(s.charAt(i)) !=
Ascii.toLower(strValue.charAt(pos + i))) {
+ char c1 = s.charAt(i);
+ char c2 = strValue.charAt(pos + i);
+ // Use ASCII short-cut if possible
+ if (c1 > 0xFF || c2 > 0xFF) {
+ if (Character.toLowerCase(c1) !=
Character.toLowerCase(c2)) {
+ return false;
+ }
+ } else if (Ascii.toLower(c1) != Ascii.toLower(c2)) {
return false;
}
+
}
return true;
case T_CHARS:
diff --git a/test/org/apache/tomcat/util/buf/TestByteChunk.java
b/test/org/apache/tomcat/util/buf/TestByteChunk.java
index ce8234230e..23f5e7e0ef 100644
--- a/test/org/apache/tomcat/util/buf/TestByteChunk.java
+++ b/test/org/apache/tomcat/util/buf/TestByteChunk.java
@@ -179,4 +179,14 @@ public class TestByteChunk {
// immediately after a call to recycle().
Assert.assertNull(bc.toString());
}
+
+
+ @Test
+ public void testEqualsIgnoreCase() {
+ byte[] bytes = "Hello".getBytes();
+ ByteChunk bc = new ByteChunk();
+ bc.setBytes(bytes, 0, bytes.length);
+ Assert.assertTrue(bc.equalsIgnoreCase("heLLo"));
+
Assert.assertFalse(bc.equalsIgnoreCase("\u8a48\u8a65\u8a6c\u8a6c\u8a6f"));
+ }
}
diff --git a/test/org/apache/tomcat/util/http/TestMimeHeaders.java
b/test/org/apache/tomcat/util/http/TestMimeHeaders.java
index efc7832bf7..7136ab1ce0 100644
--- a/test/org/apache/tomcat/util/http/TestMimeHeaders.java
+++ b/test/org/apache/tomcat/util/http/TestMimeHeaders.java
@@ -16,6 +16,7 @@
*/
package org.apache.tomcat.util.http;
+import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
@@ -107,4 +108,14 @@ public class TestMimeHeaders {
}
Assert.assertFalse(names.hasMoreElements());
}
-}
+
+
+ @Test
+ public void testSetValueBytesIgnoresCase01() throws
UnsupportedEncodingException {
+ MimeHeaders mh = new MimeHeaders();
+
+ byte[] bytes = HEADER_NAME_UC_STRING.getBytes("utf-8");
+ mh.setValue(HEADER_NAME_UC_STRING).setBytes(bytes, 0, bytes.length);
+
Assert.assertTrue(mh.getValue(HEADER_NAME_UC_STRING).equalsIgnoreCase(HEADER_NAME_MIXED_STRING));
+
Assert.assertFalse(mh.getValue(HEADER_NAME_UC_STRING).equalsIgnoreCase("\u8a54\u8a45\u8a53\u8a54"));
+ }}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]