From f3cadb38dcc5b20e515706fae68dce533ad6c737 Mon Sep 17 00:00:00 2001
From: Maxim Nesen <24524084+senivam@users.noreply.github.com>
Date: Thu, 4 Mar 2021 11:36:50 +0100
Subject: [PATCH] switching to NIO tmp file creation approach (#4712)

Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
---
 .../jersey/message/internal/Utils.java        | 26 +++++++++--
 .../jersey/message/internal/UtilsTest.java    | 45 +++++++++++++++++++
 .../src/test/resources/surefire.policy        |  4 +-
 3 files changed, 70 insertions(+), 5 deletions(-)
 create mode 100644 core-common/src/test/java/org/glassfish/jersey/message/internal/UtilsTest.java

diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/Utils.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/Utils.java
index c4f035ee1..dcae91950 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/Utils.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/Utils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -18,6 +18,10 @@ package org.glassfish.jersey.message.internal;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Utility class.
@@ -46,9 +50,23 @@ public final class Utils {
      * @throws IOException if a file could not be created.
      */
     public static File createTempFile() throws IOException {
-        final File file = File.createTempFile("rep", "tmp");
-        // Make sure the file is deleted when JVM is shutdown at last.
-        file.deleteOnExit();
+        final AtomicReference<IOException> exceptionReference = new AtomicReference<>();
+        final File file = AccessController.doPrivileged(new PrivilegedAction<File>() {
+            public File run() {
+                File tempFile = null;
+                try {
+                    tempFile = Files.createTempFile("rep", "tmp").toFile();
+                    // Make sure the file is deleted when JVM is shutdown at last.
+                    tempFile.deleteOnExit();
+                } catch (IOException e) {
+                    exceptionReference.set(e);
+                }
+                return tempFile;
+            }
+        });
+        if (exceptionReference.get() != null) {
+            throw exceptionReference.get();
+        }
         return file;
     }
 
diff --git a/core-common/src/test/java/org/glassfish/jersey/message/internal/UtilsTest.java b/core-common/src/test/java/org/glassfish/jersey/message/internal/UtilsTest.java
new file mode 100644
index 000000000..e6baf4c40
--- /dev/null
+++ b/core-common/src/test/java/org/glassfish/jersey/message/internal/UtilsTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 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
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.message.internal;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class UtilsTest {
+
+    @Test
+    public void createTempFile() throws IOException {
+        final File file = Utils.createTempFile();
+        final OutputStream stream = new BufferedOutputStream(new FileOutputStream(file));
+
+        try {
+            final ByteArrayInputStream entityStream = new ByteArrayInputStream("Test stream byte input".getBytes());
+            ReaderWriter.writeTo(entityStream, stream);
+        } finally {
+            stream.close();
+        }
+        Assert.assertTrue(file.exists());
+    }
+
+}
diff --git a/core-common/src/test/resources/surefire.policy b/core-common/src/test/resources/surefire.policy
index 77fa02af3..27602ae4c 100644
--- a/core-common/src/test/resources/surefire.policy
+++ b/core-common/src/test/resources/surefire.policy
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -30,6 +30,7 @@ grant codebase "file:${project.build.directory}/test-classes/-" {
   permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
   permission java.lang.RuntimePermission "modifyThread";
   permission java.util.PropertyPermission "*", "write";
+  permission java.io.FilePermission "${java.io.tmpdir}/-", "read,write,delete";
   permission java.lang.RuntimePermission "getClassLoader";
   permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
   permission java.lang.RuntimePermission "accessClassInPackage.sun.misc.*";
@@ -43,6 +44,7 @@ grant codebase "file:${project.build.directory}/classes/-" {
   permission java.lang.RuntimePermission "modifyThread";
   permission java.util.PropertyPermission "*", "read";
   permission java.io.FilePermission "<<ALL FILES>>", "read";
+  permission java.io.FilePermission "${java.io.tmpdir}/-", "read,write,delete";
   permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
   permission java.lang.RuntimePermission "accessClassInPackage.sun.misc.*";
   permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
-- 
2.42.0.windows.2

