From fc552037ca992235b5fa72ea167a8e0d01d33b9d Mon Sep 17 00:00:00 2001 From: jmehrens Date: Sun, 24 Jan 2021 19:50:20 -0600 Subject: [PATCH] UniqueValue should use UUID::randomUUID for boundary and messageid #460 Signed-off-by: jmehrens --- .../main/java/com/sun/mail/util/PropUtil.java | 33 ++- .../jakarta/mail/internet/MimeMessage.java | 1 + .../jakarta/mail/internet/UniqueValue.java | 65 ++++-- .../java/jakarta/mail/internet/package.html | 29 ++- .../mail/util/logging/MailHandlerTest.java | 2 +- .../mail/internet/UniqueValueTest.java | 198 ++++++++++++++++++ 6 files changed, 307 insertions(+), 21 deletions(-) create mode 100644 mail/src/test/java/jakarta/mail/internet/UniqueValueTest.java diff --git a/mail/src/main/java/com/sun/mail/util/PropUtil.java b/mail/src/main/java/com/sun/mail/util/PropUtil.java index 1ff431d3..23a06ea3 100644 --- a/mail/src/main/java/com/sun/mail/util/PropUtil.java +++ b/mail/src/main/java/com/sun/mail/util/PropUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -115,6 +115,37 @@ public static boolean getBooleanSystemProperty(String name, boolean def) { } } + /** + * Get a string valued System property. + * + * @param name the property name + * @param def default value if property not found + * @return the property value + */ + public static String getSystemProperty(String name, String def) { + try { + Object v = getProp(System.getProperties(), name); + if (v != null) { //found entry + return v instanceof String ? (String) v : def; + } + } catch (ClassCastException useDefault) { + return def; + } catch (SecurityException sex) { + // fall through... + } + + /* + * If we can't get the entire System Properties object because + * of a SecurityException, just ask for the specific property. + */ + try { + String value = System.getProperty(name); + return value == null ? def : value; + } catch (ClassCastException | SecurityException useDefault) { + return def; + } + } + /** * Get the value of the specified property. * If the "get" method returns null, use the getProperty method, diff --git a/mail/src/main/java/jakarta/mail/internet/MimeMessage.java b/mail/src/main/java/jakarta/mail/internet/MimeMessage.java index f987ec1e..e3a770ea 100644 --- a/mail/src/main/java/jakarta/mail/internet/MimeMessage.java +++ b/mail/src/main/java/jakarta/mail/internet/MimeMessage.java @@ -2213,6 +2213,7 @@ public void saveChanges() throws MessagingException { * * @exception MessagingException for failures * @since JavaMail 1.4 + * @see jakarta.mail.internet.InternetAddress#getLocalAddress */ protected void updateMessageID() throws MessagingException { setHeader("Message-ID", diff --git a/mail/src/main/java/jakarta/mail/internet/UniqueValue.java b/mail/src/main/java/jakarta/mail/internet/UniqueValue.java index 01a6da33..8f73c0a4 100644 --- a/mail/src/main/java/jakarta/mail/internet/UniqueValue.java +++ b/mail/src/main/java/jakarta/mail/internet/UniqueValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -16,7 +16,8 @@ package jakarta.mail.internet; -import java.net.*; +import com.sun.mail.util.PropUtil; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import jakarta.mail.Session; @@ -36,7 +37,7 @@ class UniqueValue { /** * A global unique number, to ensure uniqueness of generated strings. */ - private static AtomicInteger id = new AtomicInteger(); + private static final AtomicInteger id = new AtomicInteger(); /** * Get a unique value for use in a multipart boundary string. @@ -47,12 +48,19 @@ class UniqueValue { */ public static String getUniqueBoundaryValue() { StringBuilder s = new StringBuilder(); - long hash = s.hashCode(); - + s.append("----=_Part_"); + String p = PropUtil.getSystemProperty( + "mail.mime.multipart.boundary.factory", null); + if (UniqueValue.class.getName().equals(p)) { // Unique string is ----=_Part__. - s.append("----=_Part_").append(id.getAndIncrement()).append("_"). - append(hash).append('.'). + s.append(id.getAndIncrement()).append("_"). + append(System.identityHashCode(s)).append('.'). append(System.currentTimeMillis()); + } else if (UUID.class.getName().equals(p)) { + s.append(UUID.randomUUID()); + } else { //Not defined or malformed property. + s.append(UUID.randomUUID()); + } return s.toString(); } @@ -71,25 +79,46 @@ public static String getUniqueBoundaryValue() { * @see jakarta.mail.internet.InternetAddress */ public static String getUniqueMessageIDValue(Session ssn) { - String suffix = null; + StringBuilder s = new StringBuilder(); + String p = messageIdSupplier(ssn); + if (UniqueValue.class.getName().equals(p)) { + // Unique string is .. + s.append(System.identityHashCode(s)).append('.'). + append(id.getAndIncrement()).append('.'). + append(System.currentTimeMillis()); + } else if (UUID.class.getName().equals(p)) { + s.append(UUID.randomUUID()); + } else { //Not defined or malformed property. + s.append(UUID.randomUUID()); + } + String suffix; InternetAddress addr = InternetAddress.getLocalAddress(ssn); if (addr != null) suffix = addr.getAddress(); else { suffix = "jakartamailuser@localhost"; // worst-case default } - int at = suffix.lastIndexOf('@'); - if (at >= 0) - suffix = suffix.substring(at); - - StringBuilder s = new StringBuilder(); - // Unique string is .. - s.append(s.hashCode()).append('.'). - append(id.getAndIncrement()).append('.'). - append(System.currentTimeMillis()). - append(suffix); + int at = suffix.lastIndexOf('@'); + if (at >= 0) { + s.append(suffix, at, suffix.length()); + } else { + s.append(suffix); + } return s.toString(); } + + private static String messageIdSupplier(Session ssn) { + String k = "mail.mime.messageid.factory"; + if (ssn != null) { + return ssn.getProperty(k); + } else {//Act like default default session without creating it. + return PropUtil.getSystemProperty(k, null); + } + } + + private UniqueValue() throws IllegalAccessException { + throw new IllegalAccessException(UniqueValue.class.getName()); + } } diff --git a/mail/src/main/java/jakarta/mail/internet/package.html b/mail/src/main/java/jakarta/mail/internet/package.html index d3412d9f..d87121e7 100644 --- a/mail/src/main/java/jakarta/mail/internet/package.html +++ b/mail/src/main/java/jakarta/mail/internet/package.html @@ -4,7 +4,7 @@