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");
}
}
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");
}
}
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);
}
}
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);
}
Aggregations