This is an automated email from the ASF dual-hosted git repository.
rmaucher pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new 30360f4b90 Redo parsing since not fully accurate with tokenizer
30360f4b90 is described below
commit 30360f4b9062024d954e63f242a72e7be9c79e62
Author: remm <[email protected]>
AuthorDate: Thu Jul 16 15:04:37 2026 +0200
Redo parsing since not fully accurate with tokenizer
Co authored by OpenCode.
Excellent code coverage form existing tests.
---
.../catalina/valves/rewrite/ResolverImpl.java | 68 +++++++++++++++++++---
1 file changed, 61 insertions(+), 7 deletions(-)
diff --git a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
index 3bbe96aca8..296caab8a1 100644
--- a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
+++ b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
@@ -28,7 +28,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Set;
-import java.util.StringTokenizer;
import java.util.concurrent.TimeUnit;
import org.apache.catalina.WebResource;
@@ -298,17 +297,72 @@ public class ResolverImpl extends Resolver {
private String resolveComponent(String fullDN, String component) {
HashMap<String,String> components = new HashMap<>();
- StringTokenizer tokenizer = new StringTokenizer(fullDN, ",");
- while (tokenizer.hasMoreElements()) {
- String token = tokenizer.nextToken().trim();
- int pos = token.indexOf('=');
- if (pos > 0 && (pos + 1) < token.length()) {
- components.put(token.substring(0, pos), token.substring(pos +
1));
+ int len = fullDN.length();
+ int start = 0;
+ while (start < len) {
+ // Skip leading whitespace
+ while (start < len &&
Character.isWhitespace(fullDN.charAt(start))) {
+ start++;
}
+ if (start >= len) {
+ break;
+ }
+
+ // Find the unescaped '=' that separates key from value
+ int eqPos = -1;
+ for (int i = start; i < len; i++) {
+ char c = fullDN.charAt(i);
+ if (c == '\\' && i + 1 < len) {
+ i++; // Skip escaped character
+ } else if (c == '=') {
+ eqPos = i;
+ break;
+ }
+ }
+ if (eqPos < 0) {
+ break;
+ }
+
+ String key = unescape(fullDN.substring(start, eqPos)).trim();
+ int valStart = eqPos + 1;
+
+ // Find the unescaped ',' that ends this RDN, or end of string
+ int commaPos = len;
+ for (int i = valStart; i < len; i++) {
+ char c = fullDN.charAt(i);
+ if (c == '\\' && i + 1 < len) {
+ i++; // Skip escaped character
+ } else if (c == ',') {
+ commaPos = i;
+ break;
+ }
+ }
+
+ String value = unescape(fullDN.substring(valStart,
commaPos)).trim();
+ if (!key.isEmpty()) {
+ components.put(key, value);
+ }
+
+ start = commaPos + 1;
}
return components.get(component);
}
+ private String unescape(String s) {
+ StringBuilder sb = new StringBuilder(s.length());
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '\\' && i + 1 < s.length()) {
+ char next = s.charAt(i + 1);
+ sb.append(next);
+ i++;
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
private String resolveAlternateName(X509Certificate certificate, int type,
int n) {
try {
Collection<List<?>> alternateNames =
certificate.getSubjectAlternativeNames();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]