Search in sources :

Example 6 with ByteBuilder

use of com.zimbra.common.zmime.ZMimeUtility.ByteBuilder in project zm-mailbox by Zimbra.

the class ZMimeParserTest method multipleContentTypes.

@Test
public void multipleContentTypes() throws Exception {
    ByteBuilder bb = new ByteBuilder(CharsetUtil.UTF_8);
    bb.append("Content-Type: text/plain\r\n");
    bb.append("From: <foo@example.com\r\n");
    bb.append("Subject: sample\r\n");
    bb.append("Content-Type: multipart/alternative; boundary=").append(BOUNDARY1).append("\r\n");
    bb.append("\r\n");
    bb.append("--").append(BOUNDARY1).append("\r\n");
    bb.append("Content-Type: text/plain\r\n");
    bb.append("\r\n");
    bb.append("foo!  bar!  loud noises\r\n\r\n");
    bb.append("--").append(BOUNDARY1).append("--\r\n");
    try {
        MimeMessage mm = new ZMimeMessage(getSession(), new SharedByteArrayInputStream(bb.toByteArray()));
        Assert.assertFalse("content isn't multipart", mm.getContent() instanceof MimeMultipart);
        Assert.assertEquals("text/plain", "text/plain", new ZContentType(mm.getContentType()).getBaseType());
    } catch (ClassCastException e) {
        Assert.fail("mishandled double Content-Type headers");
    }
}
Also used : ByteBuilder(com.zimbra.common.zmime.ZMimeUtility.ByteBuilder) MimeMessage(javax.mail.internet.MimeMessage) MimeMultipart(javax.mail.internet.MimeMultipart) SharedByteArrayInputStream(javax.mail.util.SharedByteArrayInputStream) Test(org.junit.Test)

Example 7 with ByteBuilder

use of com.zimbra.common.zmime.ZMimeUtility.ByteBuilder in project zm-mailbox by Zimbra.

the class ZMimeParserTest method repetition.

@Test
public void repetition() throws Exception {
    ByteBuilder bb = new ByteBuilder(CharsetUtil.UTF_8);
    String boundary = BOUNDARY1;
    bb.append("From: <foo@example.com\r\n");
    bb.append("Subject: sample\r\n");
    bb.append("Content-Type: multipart/mixed; boundary=").append(boundary).append("\r\n");
    for (int i = 0; i < 100; i++) {
        bb.append("--").append(boundary).append("\r\n");
        bb.append("Content-Type: text/plain\r\n");
        bb.append("\r\n");
        bb.append("foo!  bar!  loud noises\r\n\r\n");
    }
    bb.append("--").append(boundary).append("--\r\n");
    try {
        MimeMessage mm = ZMimeParser.parse(getSession(), new SharedByteArrayInputStream(bb.toByteArray()));
        Object content = mm.getContent();
        Assert.assertTrue("content is multipart", content instanceof MimeMultipart);
        MimeMultipart mp = (MimeMultipart) content;
        Assert.assertEquals("count reduced??", 100, mp.getCount());
    } catch (ClassCastException e) {
        Assert.fail("mishandled double Content-Type headers");
    }
}
Also used : ByteBuilder(com.zimbra.common.zmime.ZMimeUtility.ByteBuilder) MimeMessage(javax.mail.internet.MimeMessage) MimeMultipart(javax.mail.internet.MimeMultipart) SharedByteArrayInputStream(javax.mail.util.SharedByteArrayInputStream) Test(org.junit.Test)

Example 8 with ByteBuilder

use of com.zimbra.common.zmime.ZMimeUtility.ByteBuilder in project zm-mailbox by Zimbra.

the class ZInternetHeaders method addHeaderLine.

@Override
public void addHeaderLine(String line) {
    if (ZPARSER) {
        if (!line.endsWith("\r\n")) {
            line += "\r\n";
        }
        byte[] content = line.getBytes(ZInternetHeader.decodingCharset(defaultCharset()));
        if (!line.isEmpty() && Character.isWhitespace(line.charAt(0)) && !headers.isEmpty()) {
            ZInternetHeader last = (ZInternetHeader) headers.remove(headers.size() - 1);
            content = new ByteBuilder(last.content).append(content).toByteArray();
        }
        appendHeader(new ZInternetHeader(content));
    } else {
        super.addHeaderLine(line);
    }
}
Also used : ByteBuilder(com.zimbra.common.zmime.ZMimeUtility.ByteBuilder)

Example 9 with ByteBuilder

use of com.zimbra.common.zmime.ZMimeUtility.ByteBuilder in project zm-mailbox by Zimbra.

the class ZInternetHeader method decode.

@SuppressWarnings("null")
static String decode(final byte[] content, final int start, final int length, final Charset charset) {
    // short-circuit if there are only ASCII characters and no "=?"
    final int end = start + length;
    boolean complicated = false;
    for (int pos = start; pos < end && !complicated; pos++) {
        byte c = content[pos];
        if (c <= 0 || c >= 0x7F || (c == '=' && pos < end - 1 && content[pos + 1] == '?')) {
            complicated = true;
        }
    }
    if (!complicated) {
        return unfold(createString(content, start, length, charset));
    }
    ByteBuilder builder = new ByteBuilder(length, decodingCharset(charset));
    List<ZByteString> byteStrings = new ArrayList<ZByteString>();
    boolean encoded = false;
    int questions = 0;
    for (int pos = start; pos < end; pos++) {
        byte c = content[pos];
        if (c == '\r' || c == '\n') {
        // ignore folding
        } else if ((c == ' ' || c == '\t') && pos < end - 3 && content[pos + 1] == '=' && content[pos + 2] == '?' && (!encoded || content[pos + 3] != '=')) {
        // omit one linear whitespace before beginning of encoded word (RFC's 2047, 822)
        } else if (c == '=' && pos < end - 2 && content[pos + 1] == '?' && (!encoded || content[pos + 2] != '=')) {
            // "=?" marks the beginning of an encoded-word
            if (!builder.isEmpty()) {
                byteStrings.add(new ZByteString(builder));
            }
            builder.reset();
            builder.write('=');
            encoded = true;
            questions = 0;
        } else if (c == '?' && encoded && ++questions > 3 && pos < end - 1 && content[pos + 1] == '=') {
            // "?=" may mean the end of an encoded-word, so see if it decodes correctly
            builder.write('?');
            builder.write('=');
            ZByteString decoded = ZMimeUtility.decodeWordBytes(builder.toByteArray());
            boolean valid = decoded != null;
            if (valid) {
                pos++;
                // consume one linear whitespace after end of encoded word (RFC's 2047, 822)
                while (pos < end - 1 && (content[pos + 1] == '\r' || content[pos + 1] == '\n')) {
                    pos += 1;
                }
                if (pos < end - 1 && (content[pos + 1] == ' ' || content[pos + 1] == '\t')) {
                    pos++;
                }
            } else {
                decoded = new ZByteString(builder.pop());
            }
            byteStrings.add(decoded);
            encoded = false;
            builder.reset();
        } else {
            builder.write(c);
        }
    }
    if (!builder.isEmpty()) {
        byteStrings.add(new ZByteString(builder));
    }
    return ZByteString.makeString(byteStrings);
}
Also used : ByteBuilder(com.zimbra.common.zmime.ZMimeUtility.ByteBuilder) ArrayList(java.util.ArrayList)

Aggregations

ByteBuilder (com.zimbra.common.zmime.ZMimeUtility.ByteBuilder)9 SharedByteArrayInputStream (javax.mail.util.SharedByteArrayInputStream)6 Test (org.junit.Test)6 MimeMessage (javax.mail.internet.MimeMessage)5 MimeMultipart (javax.mail.internet.MimeMultipart)3 Base64EncoderStream (com.zimbra.common.zmime.ZTransferEncoding.Base64EncoderStream)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 Properties (java.util.Properties)1 TreeMap (java.util.TreeMap)1 Session (javax.mail.Session)1