diff --git a/build.xml b/build.xml
index 54a10b60fd..a031db96f2 100644
--- a/build.xml
+++ b/build.xml
@@ -1811,6 +1811,8 @@ under the License.
+
+
-->
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
index 9646ba07ad..10174d54d8 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
@@ -659,9 +659,9 @@ public class SignatureInfo implements SignatureConfigurable {
* @param other the reference to wrap, if null
* @return if other is null, an empty lists is returned, otherwise other is returned
*/
- @SuppressWarnings("unchecked")
private static List safe(List other) {
- return other == null ? Collections.EMPTY_LIST : other;
+ List emptyList = Collections.emptyList();
+ return other == null ? emptyList : other;
}
private void brokenJvmWorkaround(XMLSignContext context) {
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java
index 06054c0576..05ebd4975e 100644
--- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java
+++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java
@@ -29,6 +29,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.HttpURLConnection;
+import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
@@ -121,7 +122,7 @@ public class TSPTimeStampService implements TimeStampService {
URL proxyUrl = new URL(signatureConfig.getProxyUrl());
String host = proxyUrl.getHost();
int port = proxyUrl.getPort();
- proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, (port == -1 ? 80 : port)));
+ proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(InetAddress.getByName(host), (port == -1 ? 80 : port)));
}
HttpURLConnection huc = (HttpURLConnection)new URL(signatureConfig.getTspUrl()).openConnection(proxy);
diff --git a/src/resources/devtools/forbidden-signatures-prod.txt b/src/resources/devtools/forbidden-signatures-prod.txt
new file mode 100644
index 0000000000..3dd98b2fbe
--- /dev/null
+++ b/src/resources/devtools/forbidden-signatures-prod.txt
@@ -0,0 +1,29 @@
+# (C) Copyright Uwe Schindler (Generics Policeman) and others.
+# Parts of this work are licensed to the Apache Software Foundation (ASF)
+# under one or more contributor license agreements.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This file contains API signatures which are specific to POI.
+# The goal is to minimize implicit defaults
+
+@defaultMessage POI forbidden APIs which are tolerated in non-production code, e.g. in tests and examples
+
+# We have applications which use this to return error codes on invalid commandline parameters...
+#@defaultMessage Please do not terminate the application
+#java.lang.System#exit(int)
+#java.lang.Runtime#exit(int)
+#java.lang.Runtime#halt(int)
+
+@defaultMessage Please do not try to stop the world
+java.lang.System#gc()
diff --git a/src/resources/devtools/forbidden-signatures.txt b/src/resources/devtools/forbidden-signatures.txt
index 1a506f3ffd..481c9b83f9 100644
--- a/src/resources/devtools/forbidden-signatures.txt
+++ b/src/resources/devtools/forbidden-signatures.txt
@@ -32,3 +32,84 @@ java.lang.reflect.AccessibleObject#setAccessible(boolean) @ Reflection usage fai
java.text.DecimalFormatSymbols#DecimalFormatSymbols() @ use DecimalFormatSymbols.getInstance()
java.text.DecimalFormatSymbols#DecimalFormatSymbols(Locale) @ use DecimalFormatSymbols.getInstance()
+
+# the following are taken from the Elasticsearch source at https://github.com/elastic/elasticsearch/tree/master/buildSrc/src/main/resources/forbidden
+
+@defaultMessage Convert to URI
+java.net.URL#getPath()
+java.net.URL#getFile()
+
+@defaultMessage Usage of getLocalHost is discouraged
+java.net.InetAddress#getLocalHost()
+
+@defaultMessage Specify a location for the temp file/directory instead.
+java.nio.file.Files#createTempDirectory(java.lang.String,java.nio.file.attribute.FileAttribute[])
+java.nio.file.Files#createTempFile(java.lang.String,java.lang.String,java.nio.file.attribute.FileAttribute[])
+
+@defaultMessage Specify a location for the temp file/directory instead.
+java.nio.file.Files#createTempDirectory(java.lang.String,java.nio.file.attribute.FileAttribute[])
+java.nio.file.Files#createTempFile(java.lang.String,java.lang.String,java.nio.file.attribute.FileAttribute[])
+
+@defaultMessage Don't use java serialization - this can break BWC without noticing it
+java.io.ObjectOutputStream
+java.io.ObjectOutput
+java.io.ObjectInputStream
+java.io.ObjectInput
+
+@defaultMessage Resolve hosts explicitly to the address(es) you want with InetAddress.
+java.net.InetSocketAddress#(java.lang.String,int)
+java.net.Socket#(java.lang.String,int)
+java.net.Socket#(java.lang.String,int,java.net.InetAddress,int)
+
+@defaultMessage Don't bind to wildcard addresses. Be specific.
+java.net.DatagramSocket#()
+java.net.DatagramSocket#(int)
+java.net.InetSocketAddress#(int)
+java.net.MulticastSocket#()
+java.net.MulticastSocket#(int)
+java.net.ServerSocket#(int)
+java.net.ServerSocket#(int,int)
+
+@defaultMessage use NetworkAddress format/formatAddress to print IP or IP+ports
+java.net.InetAddress#toString()
+java.net.InetAddress#getHostAddress()
+java.net.Inet4Address#getHostAddress()
+java.net.Inet6Address#getHostAddress()
+java.net.InetSocketAddress#toString()
+
+@defaultMessage avoid DNS lookups by accident: if you have a valid reason, then @SuppressWarnings with that reason so its completely clear
+java.net.InetAddress#getHostName()
+java.net.InetAddress#getCanonicalHostName()
+
+java.net.InetSocketAddress#getHostName() @ Use getHostString() instead, which avoids a DNS lookup
+
+@defaultMessage this method needs special permission
+java.lang.Thread#getAllStackTraces()
+
+@defaultMessage Avoid unchecked warnings by using Collections#empty(List|Map|Set) methods
+java.util.Collections#EMPTY_LIST
+java.util.Collections#EMPTY_MAP
+java.util.Collections#EMPTY_SET
+
+
+@defaultMessage spawns threads with vague names; use a custom thread factory and name threads so that you can tell (by its name) which executor it is associated with
+java.util.concurrent.Executors#newFixedThreadPool(int)
+java.util.concurrent.Executors#newSingleThreadExecutor()
+java.util.concurrent.Executors#newCachedThreadPool()
+java.util.concurrent.Executors#newSingleThreadScheduledExecutor()
+java.util.concurrent.Executors#newScheduledThreadPool(int)
+java.util.concurrent.Executors#defaultThreadFactory()
+java.util.concurrent.Executors#privilegedThreadFactory()
+
+java.lang.Character#codePointBefore(char[],int) @ Implicit start offset is error-prone when the char[] is a buffer and the first chars are random chars
+java.lang.Character#codePointAt(char[],int) @ Implicit end offset is error-prone when the char[] is a buffer and the last chars are random chars
+
+@defaultMessage Only use wait / notify when really needed try to use concurrency primitives, latches or callbacks instead.
+java.lang.Object#wait()
+java.lang.Object#wait(long)
+java.lang.Object#wait(long,int)
+java.lang.Object#notify()
+java.lang.Object#notifyAll()
+
+@defaultMessage Don't interrupt threads use FutureUtils#cancel(Future) instead
+java.util.concurrent.Future#cancel(boolean)