From 8067edd97d7a50a3efb3fbe45c58ba5b81ec6ebd Mon Sep 17 00:00:00 2001 From: Marco Miller Date: Mon, 4 Nov 2013 11:36:12 -0500 Subject: [PATCH] Throw IOException if negative int from port-based cli connection stream. -Instead of failing at initializing array with negative size. Introducing PowerMock test for the zero-size array case. Negative-size case not tested thx to unhelping PowerMock behavior. Using ConnectionMockTest instead of ConnectionTest; needed by PowerMock. --- cli/pom.xml | 10 ++++ cli/src/main/java/hudson/cli/Connection.java | 7 ++- .../java/hudson/cli/ConnectionMockTest.java | 56 +++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 cli/src/test/java/hudson/cli/ConnectionMockTest.java diff --git a/cli/pom.xml b/cli/pom.xml index 3df9914325..9ec92b158e 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -13,6 +13,16 @@ Jenkins CLI + + org.powermock + powermock-module-junit4 + test + + + org.powermock + powermock-api-mockito + test + commons-codec commons-codec diff --git a/cli/src/main/java/hudson/cli/Connection.java b/cli/src/main/java/hudson/cli/Connection.java index 232970869d..8f35276cb7 100644 --- a/cli/src/main/java/hudson/cli/Connection.java +++ b/cli/src/main/java/hudson/cli/Connection.java @@ -35,7 +35,6 @@ import javax.crypto.SecretKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -128,7 +127,11 @@ public class Connection { } public byte[] readByteArray() throws IOException { - byte[] buf = new byte[din.readInt()]; + int bufSize = din.readInt(); + if (bufSize < 0) { + throw new IOException("DataInputStream unexpectedly returned negative integer"); + } + byte[] buf = new byte[bufSize]; din.readFully(buf); return buf; } diff --git a/cli/src/test/java/hudson/cli/ConnectionMockTest.java b/cli/src/test/java/hudson/cli/ConnectionMockTest.java new file mode 100644 index 0000000000..77b319a4d2 --- /dev/null +++ b/cli/src/test/java/hudson/cli/ConnectionMockTest.java @@ -0,0 +1,56 @@ +/* + * The MIT License + * + * Copyright (c) 2013 Ericsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.cli; + +import hudson.remoting.FastPipedInputStream; +import hudson.remoting.FastPipedOutputStream; + +import java.io.DataInputStream; +import java.io.IOException; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.powermock.api.mockito.PowerMockito.*; + +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +/** + * @author marco.miller@ericsson.com + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({Connection.class}) +public class ConnectionMockTest { + + @Test + public void shouldTolerateEmptyByteArrayUponStreamZeroValue() throws IOException { + DataInputStream din = mock(DataInputStream.class); + //when(din.readInt()).thenReturn(0) does not work; mock always return 0 for some TBD reason + Connection c = new Connection(din, new FastPipedOutputStream(new FastPipedInputStream())); + assertTrue(c.readByteArray().length == 0); + } +}