This is an automated email from the ASF dual-hosted git repository.

Arsnael pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-mime4j.git

commit c2198afe29a738af7b10ead64f2357998eed7d8b
Author: Benoit TELLIER <[email protected]>
AuthorDate: Fri Sep 11 11:46:22 2026 +0200

    [PERF] Collection of Field enhancements
---
 .../org/apache/james/mime4j/JMHFieldBench.java     | 13 +++++
 .../mime4j/field/DateTimeFieldLenientImpl.java     | 21 ++++++--
 .../mime4j/field/address/LenientAddressParser.java | 63 ++++++++++++++--------
 3 files changed, 71 insertions(+), 26 deletions(-)

diff --git a/benchmark/src/main/java/org/apache/james/mime4j/JMHFieldBench.java 
b/benchmark/src/main/java/org/apache/james/mime4j/JMHFieldBench.java
index df211b94..cf2d2180 100644
--- a/benchmark/src/main/java/org/apache/james/mime4j/JMHFieldBench.java
+++ b/benchmark/src/main/java/org/apache/james/mime4j/JMHFieldBench.java
@@ -30,6 +30,7 @@ import org.apache.james.mime4j.field.ContentTypeFieldImpl;
 import org.apache.james.mime4j.field.ContentTypeFieldLenientImpl;
 import org.apache.james.mime4j.field.DateTimeFieldImpl;
 import org.apache.james.mime4j.field.DateTimeFieldLenientImpl;
+import org.apache.james.mime4j.field.UnstructuredFieldImpl;
 import org.apache.james.mime4j.stream.RawField;
 import org.junit.Test;
 import org.openjdk.jmh.annotations.Benchmark;
@@ -66,6 +67,18 @@ public class JMHFieldBench {
             .getDate());
     }
 
+    @Benchmark
+    public void dateLenientInvalid(Blackhole bh) {
+        bh.consume(DateTimeFieldLenientImpl.PARSER.parse(new RawField("Date", 
"unknown"), DecodeMonitor.SILENT)
+            .getDate());
+    }
+
+    @Benchmark
+    public void unstructuredPlain(Blackhole bh) {
+        bh.consume(UnstructuredFieldImpl.PARSER.parse(new RawField("Subject", 
"A plain subject without encoded words"), DecodeMonitor.SILENT)
+            .getValue());
+    }
+
     @Benchmark
     public void dateStrict(Blackhole bh) {
         bh.consume(DateTimeFieldImpl.PARSER.parse(new RawField("Date", "Tue, 
26 Apr 2022 02:27:54 +0000"), DecodeMonitor.SILENT)
diff --git 
a/dom/src/main/java/org/apache/james/mime4j/field/DateTimeFieldLenientImpl.java 
b/dom/src/main/java/org/apache/james/mime4j/field/DateTimeFieldLenientImpl.java
index c29e67e6..c19cf4b9 100644
--- 
a/dom/src/main/java/org/apache/james/mime4j/field/DateTimeFieldLenientImpl.java
+++ 
b/dom/src/main/java/org/apache/james/mime4j/field/DateTimeFieldLenientImpl.java
@@ -136,16 +136,29 @@ public class DateTimeFieldLenientImpl extends 
AbstractField implements DateTimeF
         parsed = true;
         date = null;
         String body = getBody();
-        if (body != null) {
-            body = body.trim();
+        if (body == null) {
+            return;
+        }
+        String text = body.trim();
+        if (!mayBeRfc5322(text)) {
+            return;
         }
         try {
-            date = Date.from(Instant.from(RFC_5322.parse(body, new 
ParsePosition(0))));
+            date = Date.from(Instant.from(RFC_5322.parse(text, new 
ParsePosition(0))));
         } catch (Exception e) {
-            // Ignore
+            // Ignore: invalid date
         }
     }
 
+    /**
+     * Cheap pre-check that rejects obviously invalid values such as 
<code>unknown</code> or an
+     * empty string without paying for a parse exception. A RFC 5322 date 
always carries a
+     * <code>HH:MM</code> time, hence a colon.
+     */
+    private static boolean mayBeRfc5322(final String text) {
+        return text.indexOf(':') > 0;
+    }
+
     public static final FieldParser<DateTimeField> PARSER = new 
FieldParser<DateTimeField>() {
 
         public DateTimeField parse(final Field rawField, final DecodeMonitor 
monitor) {
diff --git 
a/dom/src/main/java/org/apache/james/mime4j/field/address/LenientAddressParser.java
 
b/dom/src/main/java/org/apache/james/mime4j/field/address/LenientAddressParser.java
index b809ed14..5e9ea3da 100644
--- 
a/dom/src/main/java/org/apache/james/mime4j/field/address/LenientAddressParser.java
+++ 
b/dom/src/main/java/org/apache/james/mime4j/field/address/LenientAddressParser.java
@@ -55,6 +55,25 @@ public class LenientAddressParser implements AddressParser {
     private static final BitSet COMMA_ONLY             = 
RawFieldParser.INIT_BITSET(COMMA);
     private static final BitSet COLON_ONLY             = 
RawFieldParser.INIT_BITSET(COLON);
     private static final BitSet SEMICOLON_ONLY         = 
RawFieldParser.INIT_BITSET(SEMICOLON);
+    private static final BitSet ROUTE_STOP             = 
RawFieldParser.INIT_BITSET(COMMA, COLON);
+    private static final BitSet MAILBOX_STOP           = 
RawFieldParser.INIT_BITSET(AT, OPENING_BRACKET);
+    private static final BitSet ADDRESS_STOP           = 
RawFieldParser.INIT_BITSET(COLON, AT, OPENING_BRACKET);
+    private static final BitSet BRACKETED_ROUTE_STOP   = union(ROUTE_STOP, 
CLOSING_BRACKET_ONLY);
+    private static final BitSet ADDRESS_IN_LIST_STOP   = union(ADDRESS_STOP, 
COMMA_ONLY);
+
+    /**
+     * Returns the union of a stop set with optional extra delimiters, sharing 
the
+     * base set when there is nothing to add. Callers must not mutate the 
result.
+     */
+    private static BitSet union(final BitSet base, final BitSet delimiters) {
+        if (delimiters == null) {
+            return base;
+        }
+        BitSet result = new BitSet();
+        result.or(base);
+        result.or(delimiters);
+        return result;
+    }
 
     public static final LenientAddressParser DEFAULT = new 
LenientAddressParser(DecodeMonitor.SILENT);
 
@@ -85,10 +104,10 @@ public class LenientAddressParser implements AddressParser 
{
     }
 
     DomainList parseRoute(final ByteSequence buf, final ParserCursor cursor, 
final BitSet delimiters) {
-        BitSet bitset = RawFieldParser.INIT_BITSET(COMMA, COLON);
-        if (delimiters != null) {
-            bitset.or(delimiters);
-        }
+        return parseRouteUntil(buf, cursor, union(ROUTE_STOP, delimiters));
+    }
+
+    private DomainList parseRouteUntil(final ByteSequence buf, final 
ParserCursor cursor, final BitSet stopSet) {
         List<String> domains = null;
         for (;;) {
             this.parser.skipAllWhiteSpace(buf, cursor);
@@ -102,7 +121,7 @@ public class LenientAddressParser implements AddressParser {
             } else {
                 break;
             }
-            String s = parseDomain(buf, cursor, bitset);
+            String s = parseDomain(buf, cursor, stopSet);
             if (s != null && s.length() > 0) {
                 if (domains == null) {
                     domains = new ArrayList<String>();
@@ -145,7 +164,7 @@ public class LenientAddressParser implements AddressParser {
         } else {
             return createMailbox(null, null, openingText, null);
         }
-        DomainList domainList = parseRoute(buf, cursor, CLOSING_BRACKET_ONLY);
+        DomainList domainList = parseRouteUntil(buf, cursor, 
BRACKETED_ROUTE_STOP);
         String localPart = this.parser.parseValue(buf, cursor, 
AT_AND_CLOSING_BRACKET);
         if (cursor.atEnd()) {
             return createMailbox(openingText, domainList, localPart, null);
@@ -192,11 +211,12 @@ public class LenientAddressParser implements 
AddressParser {
 
     public Mailbox parseMailbox(
             final ByteSequence buf, final ParserCursor cursor, final BitSet 
delimiters) {
-        BitSet bitset = RawFieldParser.INIT_BITSET(AT, OPENING_BRACKET);
-        if (delimiters != null) {
-            bitset.or(delimiters);
-        }
-        String openingText = this.parser.parseValue(buf, cursor, bitset);
+        return parseMailbox(buf, cursor, delimiters, union(MAILBOX_STOP, 
delimiters));
+    }
+
+    private Mailbox parseMailbox(
+            final ByteSequence buf, final ParserCursor cursor, final BitSet 
delimiters, final BitSet stopSet) {
+        String openingText = this.parser.parseValue(buf, cursor, stopSet);
         if (cursor.atEnd()) {
             return createMailbox(openingText);
         }
@@ -223,10 +243,8 @@ public class LenientAddressParser implements AddressParser 
{
 
     List<Mailbox> parseMailboxes(
             final ByteSequence buf, final ParserCursor cursor, final BitSet 
delimiters) {
-        BitSet bitset = RawFieldParser.INIT_BITSET(COMMA);
-        if (delimiters != null) {
-            bitset.or(delimiters);
-        }
+        BitSet bitset = union(COMMA_ONLY, delimiters);
+        BitSet mailboxStop = union(MAILBOX_STOP, bitset);
         List<Mailbox> mboxes = new ArrayList<Mailbox>();
         while (!cursor.atEnd()) {
             int pos = cursor.getPos();
@@ -236,7 +254,7 @@ public class LenientAddressParser implements AddressParser {
             } else if (current == COMMA) {
                 cursor.updatePos(pos + 1);
             } else {
-                Mailbox mbox = parseMailbox(buf, cursor, bitset);
+                Mailbox mbox = parseMailbox(buf, cursor, bitset, mailboxStop);
                 if (mbox != null) {
                     mboxes.add(mbox);
                 }
@@ -267,11 +285,12 @@ public class LenientAddressParser implements 
AddressParser {
 
     public Address parseAddress(
             final ByteSequence buf, final ParserCursor cursor, final BitSet 
delimiters) {
-        BitSet bitset = RawFieldParser.INIT_BITSET(COLON, AT, OPENING_BRACKET);
-        if (delimiters != null) {
-            bitset.or(delimiters);
-        }
-        String openingText = this.parser.parseValue(buf, cursor, bitset);
+        return parseAddress(buf, cursor, delimiters, union(ADDRESS_STOP, 
delimiters));
+    }
+
+    private Address parseAddress(
+            final ByteSequence buf, final ParserCursor cursor, final BitSet 
delimiters, final BitSet stopSet) {
+        String openingText = this.parser.parseValue(buf, cursor, stopSet);
         if (cursor.atEnd()) {
             return createMailbox(openingText);
         }
@@ -316,7 +335,7 @@ public class LenientAddressParser implements AddressParser {
             if (current == COMMA) {
                 cursor.updatePos(pos + 1);
             } else {
-                Address address = parseAddress(buf, cursor, COMMA_ONLY);
+                Address address = parseAddress(buf, cursor, COMMA_ONLY, 
ADDRESS_IN_LIST_STOP);
                 if (address != null) {
                     addresses.add(address);
                 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to