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

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

commit 62d87a7a693288ad543de93f9e65ee2b579115c1
Author: Benoit TELLIER <[email protected]>
AuthorDate: Wed Nov 4 21:52:17 2026 +0100

    [FIX] SignatureRecordImpl: decode only the value of a z= copy
    
    The UTF-8 check decoded the whole copy, hdr-name included, although
    only qp-hdr-value is quoted-printable and hdr-name may hold "=". A copy
    like "xb=x:X" threw IllegalArgumentException out of validate(), and
    "x=80:y" was refused as ill-formed UTF-8: signatures valid per the
    grammar got PERMFAIL.
    
    The check now decodes the text after the first colon, and a decoding
    error is reported as the IllegalStateException validate() declares.
---
 .../org/apache/james/jdkim/tagvalue/SignatureRecordImpl.java  | 11 ++++++++++-
 .../java/org/apache/james/jdkim/SignatureRecordImplTest.java  |  9 +++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git 
a/main/src/main/java/org/apache/james/jdkim/tagvalue/SignatureRecordImpl.java 
b/main/src/main/java/org/apache/james/jdkim/tagvalue/SignatureRecordImpl.java
index 2e727c2..1c49856 100644
--- 
a/main/src/main/java/org/apache/james/jdkim/tagvalue/SignatureRecordImpl.java
+++ 
b/main/src/main/java/org/apache/james/jdkim/tagvalue/SignatureRecordImpl.java
@@ -178,7 +178,16 @@ public class SignatureRecordImpl extends TagValue 
implements SignatureRecord {
                 throw new IllegalStateException("Invalid z= [" + z + "]: copy 
[" + copy
                         + "] is not hdr-name [FWS] \":\" qp-hdr-value (RFC 
6376 section 3.5)");
             }
-            if (!isWellFormedUtf8(dkimQuotedPrintableDecode(trimmed))) {
+            // only the qp-hdr-value is quoted-printable: hdr-name may hold 
"=", and is ASCII
+            String value = trimmed.substring(trimmed.indexOf(':') + 1);
+            boolean wellFormed;
+            try {
+                wellFormed = 
isWellFormedUtf8(dkimQuotedPrintableDecode(value));
+            } catch (IllegalArgumentException e) {
+                throw new IllegalStateException("Invalid z= [" + z + "]: copy 
[" + copy
+                        + "] cannot be decoded: " + e.getMessage(), e);
+            }
+            if (!wellFormed) {
                 throw new IllegalStateException("Invalid z= [" + z + "]: copy 
[" + copy
                         + "] is not well-formed UTF-8 (RFC 8616 section 4)");
             }
diff --git 
a/main/src/test/java/org/apache/james/jdkim/SignatureRecordImplTest.java 
b/main/src/test/java/org/apache/james/jdkim/SignatureRecordImplTest.java
index c7c98c2..18420b7 100644
--- a/main/src/test/java/org/apache/james/jdkim/SignatureRecordImplTest.java
+++ b/main/src/test/java/org/apache/james/jdkim/SignatureRecordImplTest.java
@@ -27,6 +27,7 @@ import org.apache.james.jdkim.tagvalue.SignatureRecordImpl;
 import org.apache.james.jdkim.tagvalue.TagValue;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.util.Arrays;
@@ -516,6 +517,14 @@ public class SignatureRecordImplTest {
         }
     }
 
+    @Test
+    public void equalsInCopiedFieldNameIsNotQuotedPrintable() {
+        for (String z : new String[] {"xb=x:X", "x=:y", "x=80:y", "=:", 
"z:|=:|!:|T:"}) {
+            assertThatCode(() -> recordWithCopiedFields(z)).as("z=%s", z)
+                    .doesNotThrowAnyException();
+        }
+    }
+
     @Test
     public void wellFormedUtf8IdentityIsStillAccepted() {
         // "\u03b4" = CE B4


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

Reply via email to