You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2017/07/03 15:50:30 UTC

svn commit: r1800694 - in /commons/proper/net/trunk/src: main/java/org/apache/commons/net/telnet/TelnetClient.java main/java/org/apache/commons/net/telnet/TelnetInputStream.java test/java/org/apache/commons/net/telnet/TelnetClientTest.java

Author: sebb
Date: Mon Jul  3 15:50:29 2017
New Revision: 1800694

URL: http://svn.apache.org/viewvc?rev=1800694&view=rev
Log:
NET-638 - Telnet subnegotiations hard-limited to 512 bytes - allow override

Modified:
    commons/proper/net/trunk/src/main/java/org/apache/commons/net/telnet/TelnetClient.java
    commons/proper/net/trunk/src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java
    commons/proper/net/trunk/src/test/java/org/apache/commons/net/telnet/TelnetClientTest.java

Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/telnet/TelnetClient.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/telnet/TelnetClient.java?rev=1800694&r1=1800693&r2=1800694&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/telnet/TelnetClient.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/telnet/TelnetClient.java Mon Jul  3 15:50:29 2017
@@ -43,6 +43,9 @@ import java.io.OutputStream;
 
 public class TelnetClient extends Telnet
 {
+    private static final int DEFAULT_MAX_SUBNEGOTIATION_LENGTH = 512;
+
+    final int _maxSubnegotiationLength;
     private InputStream __input;
     private OutputStream __output;
     protected boolean readerThread = true;
@@ -53,11 +56,7 @@ public class TelnetClient extends Telnet
      ***/
     public TelnetClient()
     {
-        /* TERMINAL-TYPE option (start)*/
-        super ("VT100");
-        /* TERMINAL-TYPE option (end)*/
-        __input = null;
-        __output = null;
+        this("VT100", DEFAULT_MAX_SUBNEGOTIATION_LENGTH);
     }
 
     /**
@@ -65,14 +64,39 @@ public class TelnetClient extends Telnet
      *
      * @param termtype the terminal type to use, e.g. {@code VT100}
      */
-    /* TERMINAL-TYPE option (start)*/
     public TelnetClient(String termtype)
     {
-        super (termtype);
+        this(termtype, DEFAULT_MAX_SUBNEGOTIATION_LENGTH);
+    }
+
+    /**
+     * Construct an instance with the specified max subnegotiation
+     * length and the default terminal-type {@code VT100}
+     *
+     * @param maxSubnegotiationLength the size of the subnegotiation buffer
+     */
+    public TelnetClient(int maxSubnegotiationLength)
+    {
+        this("VT100", maxSubnegotiationLength);
+    }
+
+
+    /**
+     * Construct an instance with the specified terminal type
+     * and max subnegotiation length
+     *
+     * @param termtype the terminal type to use, e.g. {@code VT100}
+     * @param maxSubnegotiationLength the size of the subnegotiation buffer
+     */
+    public TelnetClient(String termtype, int maxSubnegotiationLength)
+    {
+    /* TERMINAL-TYPE option (start)*/
+        super(termtype);
+    /* TERMINAL-TYPE option (end)*/
         __input = null;
         __output = null;
+        _maxSubnegotiationLength = maxSubnegotiationLength;
     }
-    /* TERMINAL-TYPE option (end)*/
 
     void _flushOutputStream() throws IOException
     {

Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java?rev=1800694&r1=1800693&r2=1800694&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java Mon Jul  3 15:50:29 2017
@@ -45,7 +45,7 @@ final class TelnetInputStream extends Bu
     private IOException __ioException;
 
     /* TERMINAL-TYPE option (start)*/
-    private final int __suboption[] = new int[512];
+    private final int __suboption[];
     private int __suboption_count = 0;
     /* TERMINAL-TYPE option (end)*/
 
@@ -64,6 +64,7 @@ final class TelnetInputStream extends Bu
         __queue = new int[2049];
         __queueHead = 0;
         __queueTail = 0;
+        __suboption = new int[client._maxSubnegotiationLength];
         __bytesAvailable = 0;
         __ioException = null;
         __readIsWaiting = false;

Modified: commons/proper/net/trunk/src/test/java/org/apache/commons/net/telnet/TelnetClientTest.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/test/java/org/apache/commons/net/telnet/TelnetClientTest.java?rev=1800694&r1=1800693&r2=1800694&view=diff
==============================================================================
--- commons/proper/net/trunk/src/test/java/org/apache/commons/net/telnet/TelnetClientTest.java (original)
+++ commons/proper/net/trunk/src/test/java/org/apache/commons/net/telnet/TelnetClientTest.java Mon Jul  3 15:50:29 2017
@@ -59,8 +59,9 @@ extends TestCase implements TelnetNotifi
     private TestConnection OPTIONS;
     private TestConnection ANSI;
     private TestConnection NOREAD;
+    private TestConnection SMALL_BUFFER;
 
-    private final int NUM_CONNECTIONS = 4;
+    private final int NUM_CONNECTIONS = 5;
 
 
     protected int numdo = 0;
@@ -68,12 +69,26 @@ extends TestCase implements TelnetNotifi
     protected int numwill = 0;
     protected int numwont = 0;
 
+    protected int[] lastSubnegotiation;
+    protected int lastSubnegotiationLength;
+
     /*
      * open connections needed for the tests for the test.
      */
     @Override
     protected void setUp() throws Exception
     {
+        SimpleOptionHandler subnegotiationSizeHandler = new SimpleOptionHandler(99, false, false, true, false)
+        {
+            @Override
+            public int[] answerSubnegotiation(int[] suboptionData, int suboptionLength)
+            {
+                lastSubnegotiation = suboptionData;
+                lastSubnegotiationLength = suboptionLength;
+                return null;
+            }
+        };
+
         int socket = 0;
         super.setUp();
         for (int port = 3333; socket < NUM_CONNECTIONS && port < 4000; port++)
@@ -87,6 +102,7 @@ extends TestCase implements TelnetNotifi
                         client = new TelnetClient();
                         // redundant but makes code clearer.
                         client.setReaderThread(true);
+                        client.addOptionHandler(subnegotiationSizeHandler);
                         client.connect("127.0.0.1", port);
                         STANDARD = new TestConnection(server, client, port);
                         break;
@@ -116,6 +132,12 @@ extends TestCase implements TelnetNotifi
                         client.connect("127.0.0.1", port);
                         NOREAD = new TestConnection(server, client, port);
                         break;
+                    case 4:
+                        client = new TelnetClient(8);
+                        client.addOptionHandler(subnegotiationSizeHandler);
+                        client.connect("127.0.0.1", port);
+                        SMALL_BUFFER = new TestConnection(server, client, port);
+                        break;
                }
                // only increment socket number on success
                socket++;
@@ -138,6 +160,7 @@ extends TestCase implements TelnetNotifi
         ANSI.close();
         OPTIONS.close();
         STANDARD.close();
+        SMALL_BUFFER.close();
         try {
             Thread.sleep(1000);
         } catch (InterruptedException ie) {
@@ -844,6 +867,57 @@ extends TestCase implements TelnetNotifi
         assertTrue("Expected negotiation2_ok to be true, got " + negotiation2_ok, negotiation2_ok);
     }
 
+    /*
+     * test of max subnegotiation length
+     */
+    public void testMaxSubnegotiationLength() throws Exception
+    {
+        byte send[] =
+            {
+                (byte) TelnetCommand.IAC, (byte) TelnetCommand.SB, (byte) 99,
+                (byte) 1, (byte) 2, (byte) 3,
+                (byte) 4, (byte) 5, (byte) 6,
+                (byte) 7, (byte) 8, (byte) 9,
+                (byte) 10, (byte) 11, (byte) 12,
+                (byte) 13, (byte) 14, (byte) 15,
+                (byte) TelnetCommand.IAC, (byte) TelnetCommand.SE,
+            };
+
+        OutputStream os1 = SMALL_BUFFER.server.getOutputStream();
+        os1.write(send);
+        os1.flush();
+        Thread.sleep(500);
+
+        // we sent 16 bytes, but the buffer size should just be 8
+        assertEquals(8, lastSubnegotiationLength);
+        assertEquals(8, lastSubnegotiation.length);
+        assertEquals(99, lastSubnegotiation[0]);
+        assertEquals(1, lastSubnegotiation[1]);
+        assertEquals(2, lastSubnegotiation[2]);
+        assertEquals(3, lastSubnegotiation[3]);
+        assertEquals(4, lastSubnegotiation[4]);
+        assertEquals(5, lastSubnegotiation[5]);
+        assertEquals(6, lastSubnegotiation[6]);
+        assertEquals(7, lastSubnegotiation[7]);
+
+        OutputStream os2 = STANDARD.server.getOutputStream();
+        os2.write(send);
+        os2.flush();
+        Thread.sleep(500);
+
+        // the standard subnegotiation buffer size is 512
+        assertEquals(16, lastSubnegotiationLength);
+        assertEquals(512, lastSubnegotiation.length);
+        assertEquals(99, lastSubnegotiation[0]);
+        assertEquals(1, lastSubnegotiation[1]);
+        assertEquals(2, lastSubnegotiation[2]);
+        assertEquals(3, lastSubnegotiation[3]);
+        assertEquals(4, lastSubnegotiation[4]);
+        assertEquals(5, lastSubnegotiation[5]);
+        assertEquals(6, lastSubnegotiation[6]);
+        assertEquals(7, lastSubnegotiation[7]);
+    }
+
 
     /*
      * Helper method. compares two arrays of int