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

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


The following commit(s) were added to refs/heads/master by this push:
     new ff415b3a MIME4J-328 Fix DecoderUtil split point (#101)
ff415b3a is described below

commit ff415b3a664066818b7e9ed1ad65f36d9e1fd0f2
Author: Benoit TELLIER <btell...@linagora.com>
AuthorDate: Mon Apr 29 14:29:19 2024 +0200

    MIME4J-328 Fix DecoderUtil split point (#101)
    
    Huge thanks to Chung dae hyun
---
 .../org/apache/james/mime4j/codec/DecoderUtil.java | 62 ++++++++++++++++++----
 .../apache/james/mime4j/codec/DecoderUtilTest.java |  7 +++
 2 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/core/src/main/java/org/apache/james/mime4j/codec/DecoderUtil.java 
b/core/src/main/java/org/apache/james/mime4j/codec/DecoderUtil.java
index 14a981dd..5526b8fc 100644
--- a/core/src/main/java/org/apache/james/mime4j/codec/DecoderUtil.java
+++ b/core/src/main/java/org/apache/james/mime4j/codec/DecoderUtil.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.mime4j.codec;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.lang.ref.SoftReference;
@@ -28,7 +29,6 @@ import java.util.Map;
 
 import org.apache.james.mime4j.io.InputStreams;
 import org.apache.james.mime4j.util.BufferRecycler;
-import org.apache.james.mime4j.util.ByteArrayBuffer;
 import org.apache.james.mime4j.util.CharsetUtil;
 import org.apache.james.mime4j.util.RecycledByteArrayBuffer;
 
@@ -122,6 +122,10 @@ public class DecoderUtil {
         return new String(decodedBytes, charset);
     }
 
+    static byte[] decodeByteAryB(String encodedText, DecodeMonitor monitor) 
throws UnsupportedEncodingException {
+        return decodeBase64(encodedText, monitor);
+    }
+
     /**
      * Decodes an encoded text encoded with the 'Q' encoding (described in
      * RFC 2047) found in a header field body.
@@ -140,6 +144,10 @@ public class DecoderUtil {
         return new String(decodedBytes, charset);
     }
 
+    static byte[] decodeByteAryQ(String encodedText, DecodeMonitor monitor) 
throws UnsupportedEncodingException {
+        return decodeQuotedPrintable(replaceUnderscores(encodedText), monitor);
+    }
+
     static String decodeEncodedWords(String body)  {
         return decodeEncodedWords(body, DecodeMonitor.SILENT);
     }
@@ -208,8 +216,11 @@ public class DecoderUtil {
             Map<Charset, Charset> charsetOverrides)
             throws IllegalArgumentException {
 
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
         StringBuilder sb = new StringBuilder();
         int position = 0;
+        String mimeCharset ="";
+        String encoding ="";
 
         while (position < body.length()) {
             int startPattern = body.indexOf("=?", position);
@@ -217,6 +228,7 @@ public class DecoderUtil {
                 if (position == 0) {
                     return body;
                 }
+                appendStringBuffer(fallback, charsetOverrides, out, sb, 
mimeCharset);
                 sb.append(body, position, body.length());
                 break;
             }
@@ -227,29 +239,48 @@ public class DecoderUtil {
 
             if (charsetEnd < 0 || encodingEnd < 0 || encodedTextEnd < 0) {
                 // Invalid pattern
+                appendStringBuffer(fallback, charsetOverrides, out, sb, 
mimeCharset);
                 sb.append(body, position, startPattern + 2);
                 position = startPattern + 2;
             } else if (encodingEnd == encodedTextEnd) {
+                appendStringBuffer(fallback, charsetOverrides, out, sb, 
mimeCharset);
                 sb.append(body, position, Math.min(encodedTextEnd + 2, 
body.length()));
                 position = encodedTextEnd +2;
             } else {
                 String separator = body.substring(position, startPattern);
                 if ((!CharsetUtil.isWhitespace(separator) || position == 0) && 
!separator.isEmpty()) {
+                    appendStringBuffer(fallback, charsetOverrides, out, sb, 
mimeCharset);
                     sb.append(separator);
                 }
-                String mimeCharset = body.substring(startPattern + 2, 
charsetEnd);
-                String encoding = body.substring(charsetEnd + 1, encodingEnd);
+                String mimeCurCharset = body.substring(startPattern + 2, 
charsetEnd);
+                String curEncoding = body.substring(charsetEnd + 1, 
encodingEnd);
                 String encodedText = body.substring(encodingEnd + 1, 
encodedTextEnd);
 
+                if (!mimeCharset.isEmpty() && 
!mimeCurCharset.equals(mimeCharset)){
+                    appendStringBuffer(fallback, charsetOverrides, out, sb, 
mimeCharset);
+                }
+
+                if (!encoding.isEmpty() && !curEncoding.equals(encoding)){
+                    appendStringBuffer(fallback, charsetOverrides, out, sb, 
mimeCharset);
+                }
+
+                mimeCharset=mimeCurCharset;
+                encoding=curEncoding;
+
                 if (encodedText.isEmpty()) {
                     position = encodedTextEnd + 2;
                     continue;
                 }
-                String decoded;
-                decoded = tryDecodeEncodedWord(mimeCharset, encoding, 
encodedText, monitor, fallback, charsetOverrides);
+                byte []decoded;
+
+                decoded = tryDecodeEncodedWord(mimeCurCharset, curEncoding, 
encodedText, monitor, fallback, charsetOverrides);
                 if (decoded != null) {
-                    if (!CharsetUtil.isWhitespace(decoded) && 
!decoded.isEmpty()) {
-                        sb.append(decoded);
+                    if (0 < decoded.length) {
+                        try {
+                            out.write(decoded);
+                        } catch (IOException e) {
+                            throw new RuntimeException(e);
+                        }
                     }
                 } else {
                     sb.append(body, startPattern, encodedTextEnd + 2);
@@ -257,11 +288,22 @@ public class DecoderUtil {
                 position = encodedTextEnd + 2;
             }
         }
+        appendStringBuffer(fallback, charsetOverrides, out, sb,mimeCharset);
+
         return sb.toString();
     }
 
+    private static void appendStringBuffer(Charset fallback, Map<Charset, 
Charset> charsetOverrides, ByteArrayOutputStream out, StringBuilder sb, String 
mimeCharset) {
+        if (0 < out.size()) {
+            byte[] byTemp = out.toByteArray();
+            Charset charset = lookupCharset(mimeCharset, fallback, 
charsetOverrides);
+            sb.append(new String(byTemp, charset));
+            out.reset();
+        }
+    }
+
     // return null on error
-    private static String tryDecodeEncodedWord(
+    private static byte[] tryDecodeEncodedWord(
             final String mimeCharset,
             final String encoding,
             final String encodedText,
@@ -283,9 +325,9 @@ public class DecoderUtil {
 
         try {
             if (encoding.equalsIgnoreCase("Q")) {
-                return DecoderUtil.decodeQ(encodedText, charset.name(), 
monitor);
+                return decodeByteAryQ(encodedText, monitor);
             } else if (encoding.equalsIgnoreCase("B")) {
-                return DecoderUtil.decodeB(encodedText, charset.name(), 
monitor);
+                return decodeByteAryB(encodedText, monitor);
             } else {
                 monitor(monitor, mimeCharset, encoding, encodedText, "leaving 
word encoded",
                         "Warning: Unknown encoding in encoded word");
diff --git 
a/core/src/test/java/org/apache/james/mime4j/codec/DecoderUtilTest.java 
b/core/src/test/java/org/apache/james/mime4j/codec/DecoderUtilTest.java
index 6a76d99d..e4f5c644 100644
--- a/core/src/test/java/org/apache/james/mime4j/codec/DecoderUtilTest.java
+++ b/core/src/test/java/org/apache/james/mime4j/codec/DecoderUtilTest.java
@@ -35,6 +35,13 @@ public class DecoderUtilTest {
         Assert.assertEquals("This is the plain text message!", s);
     }
 
+    @Test
+    public void testDoubleLineBEncoding() {
+        String s = 
DecoderUtil.decodeEncodedWords("=?utf-8?B?W1NQQU1dIFJlOiBbbWNsb3VkLWJhcmlzdGFdIO2BtOudvOyasOuTnOuwlOumrOyKpO2DgCA37LCoIO2WieyCrC3rsJztkQ==?=\n"
 +
+            "=?utf-8?B?nOyekOujjCDtj6zrqacg6rO17Jyg?= ", DecodeMonitor.STRICT);
+        Assert.assertEquals("[SPAM] Re: [mcloud-barista] 클라우드바리스타 7차 행사-발표자료 
포멧 공유 ", s);
+    }
+
     @Test
     public void testDecodeQ() throws UnsupportedEncodingException {
         String s = DecoderUtil.decodeQ("=e1_=e2=09=E3_=E4_", "ISO8859-1", 
DecodeMonitor.STRICT);


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org
For additional commands, e-mail: server-dev-h...@james.apache.org

Reply via email to