From fbc39bdac53ef34b9a5fffbba9ef7d3575198211 Mon Sep 17 00:00:00 2001 From: Dmitrii Beliakov Date: Mon, 19 Aug 2024 11:35:19 +0200 Subject: [PATCH] Replace old Hashtable with modern data structures. --- .../java/com/jcraft/jsch/ChannelSession.java | 24 +++++++--------- .../java/com/jcraft/jsch/ChannelSftp.java | 7 +++-- src/main/java/com/jcraft/jsch/ChannelX11.java | 12 ++++---- src/main/java/com/jcraft/jsch/JSch.java | 16 ++++------- .../java/com/jcraft/jsch/OpenSSHConfig.java | 9 +++--- src/main/java/com/jcraft/jsch/Session.java | 28 ++++++++++++++++--- src/test/java/com/jcraft/jsch/JSchTest.java | 8 ++++-- .../java/com/jcraft/jsch/KnownHostsTest.java | 7 +++-- 8 files changed, 63 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/jcraft/jsch/ChannelSession.java b/src/main/java/com/jcraft/jsch/ChannelSession.java index dbb8be5d..fa88fa23 100644 --- a/src/main/java/com/jcraft/jsch/ChannelSession.java +++ b/src/main/java/com/jcraft/jsch/ChannelSession.java @@ -26,15 +26,16 @@ package com.jcraft.jsch; -import java.util.Enumeration; import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; class ChannelSession extends Channel { private static byte[] _session = Util.str2byte("session"); protected boolean agent_forwarding = false; protected boolean xforwading = false; - protected Hashtable env = null; + protected Map env = null; protected boolean pty = false; @@ -78,7 +79,7 @@ public void setXForwarding(boolean enable) { @Deprecated public void setEnv(Hashtable env) { synchronized (this) { - this.env = env; + this.env = new ConcurrentHashMap<>(env); } } @@ -103,16 +104,13 @@ public void setEnv(String name, String value) { */ public void setEnv(byte[] name, byte[] value) { synchronized (this) { - getEnv().put(name, value); + if (env == null) { + env = new ConcurrentHashMap<>(); + } + env.put(name, value); } } - private Hashtable getEnv() { - if (env == null) - env = new Hashtable<>(); - return env; - } - /** * Allocate a Pseudo-Terminal. Refer to RFC4254 6.2. Requesting a Pseudo-Terminal. * @@ -205,11 +203,9 @@ protected void sendRequests() throws Exception { } if (env != null) { - for (Enumeration _env = env.keys(); _env.hasMoreElements();) { - byte[] name = _env.nextElement(); - byte[] value = env.get(name); + for (Map.Entry e : env.entrySet()) { request = new RequestEnv(); - ((RequestEnv) request).setEnv(toByteArray(name), toByteArray(value)); + ((RequestEnv) request).setEnv(toByteArray(e.getKey()), toByteArray(e.getValue())); request.request(_session, this); } } diff --git a/src/main/java/com/jcraft/jsch/ChannelSftp.java b/src/main/java/com/jcraft/jsch/ChannelSftp.java index 6c7b6e3b..2604687d 100644 --- a/src/main/java/com/jcraft/jsch/ChannelSftp.java +++ b/src/main/java/com/jcraft/jsch/ChannelSftp.java @@ -36,7 +36,8 @@ import java.io.PipedOutputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.Hashtable; +import java.util.HashMap; +import java.util.Map; import java.util.Vector; public class ChannelSftp extends ChannelSession { @@ -135,7 +136,7 @@ public class ChannelSftp extends ChannelSession { private int server_version = 3; private String version = String.valueOf(client_version); - private Hashtable extensions = null; + private Map extensions = null; private InputStream io_in = null; private boolean extension_posix_rename = false; @@ -255,7 +256,7 @@ public void start() throws JSchException { type = header.type; // 2 -> SSH_FXP_VERSION server_version = header.rid; // System.err.println("SFTP protocol server-version="+server_version); - extensions = new Hashtable<>(); + extensions = new HashMap<>(); if (length > 0) { // extension data fill(buf, length); diff --git a/src/main/java/com/jcraft/jsch/ChannelX11.java b/src/main/java/com/jcraft/jsch/ChannelX11.java index 92e29d26..26f6ac66 100644 --- a/src/main/java/com/jcraft/jsch/ChannelX11.java +++ b/src/main/java/com/jcraft/jsch/ChannelX11.java @@ -28,7 +28,8 @@ import java.io.IOException; import java.net.Socket; -import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; class ChannelX11 extends Channel { @@ -45,8 +46,8 @@ class ChannelX11 extends Channel { static byte[] cookie = null; private static byte[] cookie_hex = null; - private static Hashtable faked_cookie_pool = new Hashtable<>(); - private static Hashtable faked_cookie_hex_pool = new Hashtable<>(); + private static final Map faked_cookie_pool = new ConcurrentHashMap<>(); + private static final Map faked_cookie_hex_pool = new ConcurrentHashMap<>(); private static byte[] table = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66}; @@ -219,11 +220,8 @@ void write(byte[] foo, int s, int l) throws IOException { byte[] bar = new byte[dlen]; System.arraycopy(foo, s + 12 + plen + ((-plen) & 3), bar, 0, dlen); - byte[] faked_cookie = null; - synchronized (faked_cookie_pool) { - faked_cookie = faked_cookie_pool.get(_session); - } + byte[] faked_cookie = faked_cookie_pool.get(_session); /* * System.err.print("faked_cookie: "); for(int i=0; i config = new Hashtable<>(); + static Map config = new ConcurrentHashMap<>(); static { config.put("kex", Util.getSystemProperty("jsch.kex", @@ -608,14 +608,10 @@ public static String getConfig(String key) { * * @param newconf configurations */ - public static void setConfig(Hashtable newconf) { + public static void setConfig(Map newconf) { synchronized (config) { - for (Enumeration e = newconf.keys(); e.hasMoreElements();) { - String newkey = e.nextElement(); - String key = - (newkey.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : newkey); - config.put(key, newconf.get(newkey)); - } + newconf.forEach((key, value) -> config + .put(key.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : key, value)); } } diff --git a/src/main/java/com/jcraft/jsch/OpenSSHConfig.java b/src/main/java/com/jcraft/jsch/OpenSSHConfig.java index 76328a2e..74c8f3da 100644 --- a/src/main/java/com/jcraft/jsch/OpenSSHConfig.java +++ b/src/main/java/com/jcraft/jsch/OpenSSHConfig.java @@ -34,9 +34,10 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; -import java.util.Hashtable; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Set; import java.util.Vector; import java.util.stream.Collectors; @@ -113,7 +114,7 @@ public static OpenSSHConfig parseFile(String file) throws IOException { _parse(br); } - private final Hashtable> config = new Hashtable<>(); + private final Map> config = new HashMap<>(); private final Vector hosts = new Vector<>(); private void _parse(BufferedReader br) throws IOException { @@ -156,11 +157,11 @@ public Config getConfig(String host) { * * @return map */ - static Hashtable getKeymap() { + static Map getKeymap() { return keymap; } - private static final Hashtable keymap = new Hashtable<>(); + private static final Map keymap = new HashMap<>(); static { keymap.put("kex", "KexAlgorithms"); diff --git a/src/main/java/com/jcraft/jsch/Session.java b/src/main/java/com/jcraft/jsch/Session.java index 22a0c103..23da9908 100644 --- a/src/main/java/com/jcraft/jsch/Session.java +++ b/src/main/java/com/jcraft/jsch/Session.java @@ -34,12 +34,15 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; +import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Properties; import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; import javax.crypto.AEADBadTagException; public class Session { @@ -143,7 +146,7 @@ public class Session { SocketFactory socket_factory = null; - private Hashtable config = null; + private Map config = null; private Proxy proxy = null; private UserInfo userinfo; @@ -2752,17 +2755,23 @@ public void setPassword(byte[] password) { } public void setConfig(Properties newconf) { - Hashtable foo = new Hashtable<>(); + Map foo = new HashMap<>(); for (String key : newconf.stringPropertyNames()) { foo.put(key, newconf.getProperty(key)); } setConfig(foo); } + /** + * Deprecated. Please use the {@link #setConfig(Map)} + * + * @param newconf + */ + @Deprecated public void setConfig(Hashtable newconf) { synchronized (lock) { if (config == null) - config = new Hashtable<>(); + config = new ConcurrentHashMap<>(); for (Enumeration e = newconf.keys(); e.hasMoreElements();) { String newkey = e.nextElement(); String key = @@ -2773,10 +2782,21 @@ public void setConfig(Hashtable newconf) { } } + public void setConfig(Map newconf) { + synchronized (lock) { + if (config == null) { + config = new ConcurrentHashMap<>(); + } + newconf.forEach((key, value) -> { + config.put(key.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : key, value); + }); + } + } + public void setConfig(String key, String value) { synchronized (lock) { if (config == null) { - config = new Hashtable<>(); + config = new ConcurrentHashMap<>(); } if (key.equals("PubkeyAcceptedKeyTypes")) { config.put("PubkeyAcceptedAlgorithms", value); diff --git a/src/test/java/com/jcraft/jsch/JSchTest.java b/src/test/java/com/jcraft/jsch/JSchTest.java index e2735a7a..de244ecf 100644 --- a/src/test/java/com/jcraft/jsch/JSchTest.java +++ b/src/test/java/com/jcraft/jsch/JSchTest.java @@ -3,10 +3,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; -import java.util.Hashtable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.HashMap; +import java.util.Map; + class JSchTest { @BeforeEach @@ -29,8 +31,8 @@ void setPubkeyAcceptedKeyTypes() throws JSchException { } @Test - void setPubkeyAcceptedKeyTypesHashtable() throws JSchException { - Hashtable newconf = new Hashtable<>(); + void setPubkeyAcceptedKeyTypesHashtable() { + Map newconf = new HashMap<>(); newconf.put("PubkeyAcceptedKeyTypes", "JSchTest333"); JSch.setConfig(newconf); assertEquals("JSchTest333", JSch.getConfig("PubkeyAcceptedKeyTypes")); diff --git a/src/test/java/com/jcraft/jsch/KnownHostsTest.java b/src/test/java/com/jcraft/jsch/KnownHostsTest.java index c74df310..1d8be764 100644 --- a/src/test/java/com/jcraft/jsch/KnownHostsTest.java +++ b/src/test/java/com/jcraft/jsch/KnownHostsTest.java @@ -25,8 +25,9 @@ import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Arrays; -import java.util.Hashtable; +import java.util.HashMap; import java.util.LinkedList; +import java.util.Map; import java.util.Properties; import java.util.function.Function; import java.util.stream.Collectors; @@ -54,7 +55,7 @@ class KnownHostsTest { private static final byte[] rsaKeyBytes = Util.str2byte(" ssh-rsa"); private LinkedList messages; private JSch jsch; - private Hashtable orgConfig; + private Map orgConfig; private Properties orgProps; @BeforeEach @@ -62,7 +63,7 @@ void setupTest() { orgProps = System.getProperties(); Properties myProps = new Properties(orgProps); System.setProperties(myProps); - orgConfig = new Hashtable<>(JSch.config); + orgConfig = new HashMap<>(JSch.config); messages = new LinkedList<>(); jsch = new JSch(); jsch.setInstanceLogger(new TestLogger(messages));