|
1 | 1 | /* |
2 | | - * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * |
4 | 4 | * This program and the accompanying materials are made available under the |
5 | 5 | * terms of the Eclipse Public License v. 2.0, which is available at |
|
16 | 16 |
|
17 | 17 | package jakarta.mail.internet; |
18 | 18 |
|
19 | | -import jakarta.mail.*; |
20 | | -import jakarta.activation.*; |
21 | | -import java.io.*; |
22 | | -import java.util.*; |
23 | | -import com.sun.mail.util.PropUtil; |
| 19 | +import jakarta.activation.DataHandler; |
| 20 | +import jakarta.activation.DataSource; |
| 21 | +import jakarta.activation.FileDataSource; |
| 22 | +import jakarta.mail.BodyPart; |
| 23 | +import jakarta.mail.EncodingAware; |
| 24 | +import jakarta.mail.FolderClosedException; |
| 25 | +import jakarta.mail.Header; |
| 26 | +import jakarta.mail.IllegalWriteException; |
| 27 | +import jakarta.mail.Message; |
| 28 | +import jakarta.mail.MessageContext; |
| 29 | +import jakarta.mail.MessageRemovedException; |
| 30 | +import jakarta.mail.MessagingException; |
| 31 | +import jakarta.mail.Multipart; |
| 32 | +import jakarta.mail.Part; |
| 33 | +import jakarta.mail.Session; |
| 34 | + |
| 35 | +import java.io.BufferedInputStream; |
| 36 | +import java.io.BufferedOutputStream; |
| 37 | +import java.io.ByteArrayInputStream; |
| 38 | +import java.io.File; |
| 39 | +import java.io.FileOutputStream; |
| 40 | +import java.io.IOException; |
| 41 | +import java.io.InputStream; |
| 42 | +import java.io.OutputStream; |
| 43 | +import java.io.UnsupportedEncodingException; |
| 44 | +import java.util.ArrayList; |
| 45 | +import java.util.Enumeration; |
| 46 | +import java.util.List; |
| 47 | +import java.util.Properties; |
| 48 | + |
24 | 49 | import com.sun.mail.util.ASCIIUtility; |
25 | | -import com.sun.mail.util.MimeUtil; |
26 | | -import com.sun.mail.util.MessageRemovedIOException; |
27 | 50 | import com.sun.mail.util.FolderClosedIOException; |
28 | 51 | import com.sun.mail.util.LineOutputStream; |
| 52 | +import com.sun.mail.util.MessageRemovedIOException; |
| 53 | +import com.sun.mail.util.MimeUtil; |
| 54 | +import com.sun.mail.util.PropUtil; |
29 | 55 |
|
30 | 56 | /** |
31 | 57 | * This class represents a MIME body part. It implements the |
@@ -63,29 +89,30 @@ public class MimeBodyPart extends BodyPart implements MimePart { |
63 | 89 |
|
64 | 90 | // Paranoia: |
65 | 91 | // allow this last minute change to be disabled if it causes problems |
66 | | - private static final boolean setDefaultTextCharset = |
67 | | - PropUtil.getBooleanSystemProperty( |
68 | | - "mail.mime.setdefaulttextcharset", true); |
69 | | - |
70 | | - private static final boolean setContentTypeFileName = |
71 | | - PropUtil.getBooleanSystemProperty( |
72 | | - "mail.mime.setcontenttypefilename", true); |
73 | | - |
74 | | - private static final boolean encodeFileName = |
75 | | - PropUtil.getBooleanSystemProperty("mail.mime.encodefilename", false); |
76 | | - private static final boolean decodeFileName = |
77 | | - PropUtil.getBooleanSystemProperty("mail.mime.decodefilename", false); |
78 | | - private static final boolean ignoreMultipartEncoding = |
79 | | - PropUtil.getBooleanSystemProperty( |
80 | | - "mail.mime.ignoremultipartencoding", true); |
81 | | - private static final boolean allowutf8 = |
82 | | - PropUtil.getBooleanSystemProperty("mail.mime.allowutf8", true); |
83 | | - |
| 92 | + static final boolean SET_DEFAULT_TEXT_CHARSET = |
| 93 | + PropUtil.getBooleanSystemProperty("mail.mime.setdefaulttextcharset", true); |
| 94 | + static final boolean SET_CONTENT_TYPE_FILE_NAME = |
| 95 | + PropUtil.getBooleanSystemProperty("mail.mime.setcontenttypefilename", true); |
| 96 | + static final boolean ENCODE_FILE_NAME = |
| 97 | + PropUtil.getBooleanSystemProperty("mail.mime.encodefilename", false); |
| 98 | + static final boolean DECODE_FILE_NAME = |
| 99 | + PropUtil.getBooleanSystemProperty("mail.mime.decodefilename", false); |
| 100 | + static final boolean IGNORE_MULTIPART_ENCODING = |
| 101 | + PropUtil.getBooleanSystemProperty("mail.mime.ignoremultipartencoding", true); |
| 102 | + static final boolean ALLOW_UTF8 = |
| 103 | + PropUtil.getBooleanSystemProperty("mail.mime.allowutf8", true); |
84 | 104 | // Paranoia: |
85 | 105 | // allow this last minute change to be disabled if it causes problems |
86 | | - static final boolean cacheMultipart = // accessed by MimeMessage |
87 | | - PropUtil.getBooleanSystemProperty("mail.mime.cachemultipart", true); |
| 106 | + static final boolean CACHE_MULTIPART = // accessed by MimeMessage |
| 107 | + PropUtil.getBooleanSystemProperty("mail.mime.cachemultipart", true); |
88 | 108 |
|
| 109 | + protected boolean setDefaultTextCharset = SET_DEFAULT_TEXT_CHARSET; |
| 110 | + protected boolean setContentTypeFileName = SET_CONTENT_TYPE_FILE_NAME; |
| 111 | + protected boolean encodeFileName = ENCODE_FILE_NAME; |
| 112 | + protected boolean decodeFileName = DECODE_FILE_NAME; |
| 113 | + protected boolean ignoreMultipartEncoding = IGNORE_MULTIPART_ENCODING; |
| 114 | + protected boolean allowutf8 = ALLOW_UTF8; |
| 115 | + protected boolean cacheMultipart = CACHE_MULTIPART; |
89 | 116 |
|
90 | 117 | /** |
91 | 118 | * The DataHandler object representing this Part's content. |
@@ -192,6 +219,34 @@ public MimeBodyPart(InternetHeaders headers, byte[] content) |
192 | 219 | this.content = content; |
193 | 220 | } |
194 | 221 |
|
| 222 | + /** |
| 223 | + * Initializes MimeBodyPart from the InputStream is and it overwrites |
| 224 | + * properties from session. |
| 225 | + * |
| 226 | + * @param session Session object for this message |
| 227 | + * @param is the message input stream |
| 228 | + * @exception MessagingException for failures |
| 229 | + */ |
| 230 | + public MimeBodyPart(Session session, InputStream is) throws MessagingException { |
| 231 | + this(is); |
| 232 | + initializeProperties(session); |
| 233 | + } |
| 234 | + |
| 235 | + /** |
| 236 | + * Set the values from session properties if exist, otherwise it keeps the previous value. |
| 237 | + * @param session the not null session |
| 238 | + */ |
| 239 | + private void initializeProperties(Session session) { |
| 240 | + Properties props = session.getProperties(); |
| 241 | + setDefaultTextCharset = PropUtil.getBooleanProperty(props, "mail.mime.setdefaulttextcharset", setDefaultTextCharset); |
| 242 | + setContentTypeFileName = PropUtil.getBooleanProperty(props, "mail.mime.setcontenttypefilename", setContentTypeFileName); |
| 243 | + encodeFileName = PropUtil.getBooleanProperty(props, "mail.mime.encodefilename", encodeFileName); |
| 244 | + decodeFileName = PropUtil.getBooleanProperty(props, "mail.mime.decodefilename", decodeFileName); |
| 245 | + ignoreMultipartEncoding = PropUtil.getBooleanProperty(props, "mail.mime.ignoremultipartencoding", ignoreMultipartEncoding); |
| 246 | + allowutf8 = PropUtil.getBooleanProperty(props, "mail.mime.allowutf8", allowutf8); |
| 247 | + cacheMultipart = PropUtil.getBooleanProperty(props, "mail.mime.cachemultipart", cacheMultipart); |
| 248 | + } |
| 249 | + |
195 | 250 | /** |
196 | 251 | * Return the size of the content of this body part in bytes. |
197 | 252 | * Return -1 if the size cannot be determined. <p> |
@@ -522,7 +577,7 @@ public void setDescription(String description, String charset) |
522 | 577 | */ |
523 | 578 | @Override |
524 | 579 | public String getFileName() throws MessagingException { |
525 | | - return getFileName(this); |
| 580 | + return getFileName(this, decodeFileName); |
526 | 581 | } |
527 | 582 |
|
528 | 583 | /** |
@@ -550,7 +605,7 @@ public String getFileName() throws MessagingException { |
550 | 605 | */ |
551 | 606 | @Override |
552 | 607 | public void setFileName(String filename) throws MessagingException { |
553 | | - setFileName(this, filename); |
| 608 | + setFileName(this, filename, encodeFileName, setContentTypeFileName); |
554 | 609 | } |
555 | 610 |
|
556 | 611 | /** |
@@ -969,7 +1024,7 @@ public void saveFile(String file) throws IOException, MessagingException { |
969 | 1024 | @Override |
970 | 1025 | public void writeTo(OutputStream os) |
971 | 1026 | throws IOException, MessagingException { |
972 | | - writeTo(this, os, null); |
| 1027 | + writeTo(this, os, null, allowutf8, ignoreMultipartEncoding); |
973 | 1028 | } |
974 | 1029 |
|
975 | 1030 | /** |
@@ -1145,7 +1200,7 @@ public Enumeration<String> getNonMatchingHeaderLines(String[] names) |
1145 | 1200 | * @exception MessagingException for failures |
1146 | 1201 | */ |
1147 | 1202 | protected void updateHeaders() throws MessagingException { |
1148 | | - updateHeaders(this); |
| 1203 | + updateHeaders(this, setDefaultTextCharset, setContentTypeFileName, encodeFileName); |
1149 | 1204 | /* |
1150 | 1205 | * If we've cached a Multipart or Message object then |
1151 | 1206 | * we're now committed to using this instance of the |
@@ -1261,7 +1316,7 @@ static String getDescription(MimePart part) |
1261 | 1316 | } |
1262 | 1317 | } |
1263 | 1318 |
|
1264 | | - static String getFileName(MimePart part) throws MessagingException { |
| 1319 | + static String getFileName(MimePart part, boolean decodeFileName) throws MessagingException { |
1265 | 1320 | String filename = null; |
1266 | 1321 | String s = part.getHeader("Content-Disposition", null); |
1267 | 1322 |
|
@@ -1291,7 +1346,8 @@ static String getFileName(MimePart part) throws MessagingException { |
1291 | 1346 | return filename; |
1292 | 1347 | } |
1293 | 1348 |
|
1294 | | - static void setFileName(MimePart part, String name) |
| 1349 | + static void setFileName(MimePart part, String name, boolean encodeFileName, |
| 1350 | + boolean setContentTypeFileName) |
1295 | 1351 | throws MessagingException { |
1296 | 1352 | if (encodeFileName && name != null) { |
1297 | 1353 | try { |
@@ -1440,7 +1496,7 @@ static void setEncoding(MimePart part, String encoding) |
1440 | 1496 | * Content-Type of the specified MimePart. Returns |
1441 | 1497 | * either the original encoding or null. |
1442 | 1498 | */ |
1443 | | - static String restrictEncoding(MimePart part, String encoding) |
| 1499 | + static String restrictEncoding(MimePart part, String encoding, boolean ignoreMultipartEncoding) |
1444 | 1500 | throws MessagingException { |
1445 | 1501 | if (!ignoreMultipartEncoding || encoding == null) |
1446 | 1502 | return encoding; |
@@ -1473,7 +1529,8 @@ static String restrictEncoding(MimePart part, String encoding) |
1473 | 1529 | return encoding; |
1474 | 1530 | } |
1475 | 1531 |
|
1476 | | - static void updateHeaders(MimePart part) throws MessagingException { |
| 1532 | + static void updateHeaders(MimePart part, boolean setDefaultTextCharset, boolean setContentTypeFileName, |
| 1533 | + boolean encodeFileName) throws MessagingException { |
1477 | 1534 | DataHandler dh = part.getDataHandler(); |
1478 | 1535 | if (dh == null) // Huh ? |
1479 | 1536 | return; |
@@ -1620,8 +1677,8 @@ static void invalidateContentHeaders(MimePart part) |
1620 | 1677 | part.removeHeader("Content-Transfer-Encoding"); |
1621 | 1678 | } |
1622 | 1679 |
|
1623 | | - static void writeTo(MimePart part, OutputStream os, String[] ignoreList) |
1624 | | - throws IOException, MessagingException { |
| 1680 | + static void writeTo(MimePart part, OutputStream os, String[] ignoreList, boolean allowutf8, |
| 1681 | + boolean ignoreMultipartEncoding) throws IOException, MessagingException { |
1625 | 1682 |
|
1626 | 1683 | // see if we already have a LOS |
1627 | 1684 | LineOutputStream los = null; |
@@ -1666,7 +1723,7 @@ static void writeTo(MimePart part, OutputStream os, String[] ignoreList) |
1666 | 1723 | os.write(buf, 0, len); |
1667 | 1724 | } else { |
1668 | 1725 | os = MimeUtility.encode(os, |
1669 | | - restrictEncoding(part, part.getEncoding())); |
| 1726 | + restrictEncoding(part, part.getEncoding(), ignoreMultipartEncoding)); |
1670 | 1727 | part.getDataHandler().writeTo(os); |
1671 | 1728 | } |
1672 | 1729 | } finally { |
|
0 commit comments