From c50ea995eb50cf30b6e5e3f49e9eab6ee8c4660a Mon Sep 17 00:00:00 2001 From: Nico Piel Date: Wed, 28 Oct 2026 14:22:16 +0100 Subject: [PATCH] Close leaked resources flagged by SonarQube (S2095) MirthWebServer never closed the downloaded file's stream on success, so each download leaked a file handle. Also close the Statement in DefaultDatabaseTaskController.executeUpdate, and close the socket, connection or file when setup fails after creation in SocketUtil, DisabledConnectionPool and UnzipEngine. The extension manager and PDF viewer now use try-with-resources. Signed-off-by: Nico Piel --- .../client/ui/extensionmanager/ExtensionUtil.java | 6 +----- .../mirth/connect/plugins/pdfviewer/PDFViewer.java | 6 +++--- .../server/data/jdbc/DisabledConnectionPool.java | 13 ++++++++++--- .../mirth/connect/connectors/tcp/SocketUtil.java | 9 +++++++-- .../com/mirth/connect/server/MirthWebServer.java | 3 ++- .../controllers/DefaultDatabaseTaskController.java | 5 +++-- .../java/net/lingala/zip4j/unzip/UnzipEngine.java | 13 +++++++++---- 7 files changed, 35 insertions(+), 20 deletions(-) diff --git a/client/src/main/java/com/mirth/connect/client/ui/extensionmanager/ExtensionUtil.java b/client/src/main/java/com/mirth/connect/client/ui/extensionmanager/ExtensionUtil.java index a245b833c7..4efd88969e 100644 --- a/client/src/main/java/com/mirth/connect/client/ui/extensionmanager/ExtensionUtil.java +++ b/client/src/main/java/com/mirth/connect/client/ui/extensionmanager/ExtensionUtil.java @@ -32,17 +32,13 @@ public class ExtensionUtil { public String getURLContents(String address) { StringBuilder builder = new StringBuilder(); - try { - URL url = new URL(address); - BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); + try (BufferedReader in = new BufferedReader(new InputStreamReader(new URL(address).openStream()))) { String str = null; while ((str = in.readLine()) != null) { builder.append(str); builder.append("\r\n"); } - - in.close(); } catch (Exception e) { // could not load page contents } diff --git a/client/src/main/java/com/mirth/connect/plugins/pdfviewer/PDFViewer.java b/client/src/main/java/com/mirth/connect/plugins/pdfviewer/PDFViewer.java index 7c731c8efe..705856147d 100644 --- a/client/src/main/java/com/mirth/connect/plugins/pdfviewer/PDFViewer.java +++ b/client/src/main/java/com/mirth/connect/plugins/pdfviewer/PDFViewer.java @@ -41,9 +41,9 @@ public void viewAttachments(String channelId, Long messageId, String attachmentI File temp = File.createTempFile(attachment.getId(), ".pdf"); temp.deleteOnExit(); - OutputStream out = new FileOutputStream(temp); - IOUtils.copy(in, out); - out.close(); + try (OutputStream out = new FileOutputStream(temp)) { + IOUtils.copy(in, out); + } new MirthPDFViewer(true, temp); diff --git a/donkey/src/main/java/com/mirth/connect/donkey/server/data/jdbc/DisabledConnectionPool.java b/donkey/src/main/java/com/mirth/connect/donkey/server/data/jdbc/DisabledConnectionPool.java index d823de620c..68aca99d7a 100644 --- a/donkey/src/main/java/com/mirth/connect/donkey/server/data/jdbc/DisabledConnectionPool.java +++ b/donkey/src/main/java/com/mirth/connect/donkey/server/data/jdbc/DisabledConnectionPool.java @@ -15,6 +15,8 @@ import javax.sql.DataSource; +import org.apache.commons.dbutils.DbUtils; + public class DisabledConnectionPool implements ConnectionPool { private String url; private String username; @@ -31,9 +33,14 @@ public DisabledConnectionPool(String url, String username, String password, bool @Override public PooledConnection getConnection() throws SQLException { Connection connection = DriverManager.getConnection(url, username, password); - connection.setAutoCommit(false); - if (readOnly) { - connection.setReadOnly(true); + try { + connection.setAutoCommit(false); + if (readOnly) { + connection.setReadOnly(true); + } + } catch (Exception e) { + DbUtils.closeQuietly(connection); + throw e; } return new PooledConnection(connection, connection); } diff --git a/server/src/main/java/com/mirth/connect/connectors/tcp/SocketUtil.java b/server/src/main/java/com/mirth/connect/connectors/tcp/SocketUtil.java index 5f31ec71d9..4fab7a8590 100644 --- a/server/src/main/java/com/mirth/connect/connectors/tcp/SocketUtil.java +++ b/server/src/main/java/com/mirth/connect/connectors/tcp/SocketUtil.java @@ -66,8 +66,13 @@ public static Socket createSocket(TcpConfiguration configuration, String localAd Socket socket = configuration.createSocket(); if (StringUtils.isNotEmpty(localAddr)) { - InetAddress localAddress = InetAddress.getByName(TcpUtil.getFixedHost(localAddr)); - socket.bind(new InetSocketAddress(localAddress, localPort)); + try { + InetAddress localAddress = InetAddress.getByName(TcpUtil.getFixedHost(localAddr)); + socket.bind(new InetSocketAddress(localAddress, localPort)); + } catch (Exception e) { + socket.close(); + throw e; + } } return socket; diff --git a/server/src/main/java/com/mirth/connect/server/MirthWebServer.java b/server/src/main/java/com/mirth/connect/server/MirthWebServer.java index 4c9820dcb5..dadef1bfa2 100644 --- a/server/src/main/java/com/mirth/connect/server/MirthWebServer.java +++ b/server/src/main/java/com/mirth/connect/server/MirthWebServer.java @@ -839,9 +839,10 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques ((GZIPOutputStream) responseOutputStream).finish(); } } catch (Throwable t) { - IOUtils.closeQuietly(fis); response.reset(); response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); + } finally { + IOUtils.closeQuietly(fis); } } } else { diff --git a/server/src/main/java/com/mirth/connect/server/controllers/DefaultDatabaseTaskController.java b/server/src/main/java/com/mirth/connect/server/controllers/DefaultDatabaseTaskController.java index d765ccadc6..85b0cde203 100644 --- a/server/src/main/java/com/mirth/connect/server/controllers/DefaultDatabaseTaskController.java +++ b/server/src/main/java/com/mirth/connect/server/controllers/DefaultDatabaseTaskController.java @@ -11,6 +11,7 @@ import java.sql.Connection; import java.sql.SQLException; +import java.sql.Statement; import java.util.Calendar; import java.util.HashMap; import java.util.List; @@ -394,8 +395,8 @@ private boolean isCancelled() { private void executeUpdate(String sql) throws SQLException { SqlSession session = SqlConfig.getInstance().getSqlSessionManager().openSession(); - try { - session.getConnection().createStatement().executeUpdate(sql); + try (Statement statement = session.getConnection().createStatement()) { + statement.executeUpdate(sql); } finally { session.close(); } diff --git a/server/src/main/java/net/lingala/zip4j/unzip/UnzipEngine.java b/server/src/main/java/net/lingala/zip4j/unzip/UnzipEngine.java index 6679536779..fe63a29162 100644 --- a/server/src/main/java/net/lingala/zip4j/unzip/UnzipEngine.java +++ b/server/src/main/java/net/lingala/zip4j/unzip/UnzipEngine.java @@ -377,10 +377,15 @@ private RandomAccessFile checkSplitFile() throws ZipException { RandomAccessFile raf = new RandomAccessFile(partFile, InternalZipConstants.READ_MODE); if (currSplitFileCounter == 1) { - byte[] splitSig = new byte[4]; - raf.read(splitSig); - if (Raw.readIntLittleEndian(splitSig, 0) != InternalZipConstants.SPLITSIG) { - throw new ZipException("invalid first part split file signature"); + try { + byte[] splitSig = new byte[4]; + raf.read(splitSig); + if (Raw.readIntLittleEndian(splitSig, 0) != InternalZipConstants.SPLITSIG) { + throw new ZipException("invalid first part split file signature"); + } + } catch (Exception e) { + raf.close(); + throw e; } } return raf;