Skip to content

Commit

Permalink
fix fabric8io#4234: fixing the skip method for base64 inputstream
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Jul 5, 2022
1 parent 6b13cd2 commit 0687d7c
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 36 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Fix #2811: Approve/Reject CSR not supported in v1beta1 CertificateSigningRequest API
* Fix #4216: Update metadata when `replaceStatus()` is called
* Fix #4217: patchStatus doesn't increment metadata.generation field in Kubernetes Mock Server (CRUD)
* Fix #4234: corrected the skip method for base64 inputstream

#### Improvements
* Fix #3227 : Move `config.openshift.io` apiGroup resources out of `openshift-model/`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

import io.fabric8.kubernetes.client.KubernetesClientException;

import java.io.IOException;

//@formatter:off
/**
* <p>Encodes and decodes to and from Base64 notation.</p>
* <p>Homepage: <a href="http://iharder.net/base64">http://iharder.net/base64</a>.</p>
Expand Down Expand Up @@ -1329,7 +1332,7 @@ public static byte[] decode( String s, int options ) throws java.io.IOException
* @see Base64
* @since 1.3
*/
public static class InputStream extends java.io.FilterInputStream {
public static class InputStream extends java.io.InputStream {

private boolean encode; // Encoding or decoding
private int position; // Current position in the buffer
Expand All @@ -1340,6 +1343,7 @@ public static class InputStream extends java.io.FilterInputStream {
private boolean breakLines; // Break lines at less than 80 characters
private int options; // Record options used to create the stream.
private byte[] decodabet; // Local copies to avoid extra method calls
private java.io.InputStream in;


/**
Expand Down Expand Up @@ -1375,7 +1379,7 @@ public InputStream( java.io.InputStream in ) {
*/
public InputStream( java.io.InputStream in, int options ) {

super( in );
this.in = in;
this.options = options; // Record for later
this.breakLines = (options & DO_BREAK_LINES) > 0;
this.encode = (options & ENCODE) > 0;
Expand All @@ -1385,6 +1389,11 @@ public InputStream( java.io.InputStream in, int options ) {
this.lineLength = 0;
this.decodabet = getDecodabet(options);
} // end constructor

@Override
public void close() throws IOException {
in.close();
}

/**
* Reads enough of the input stream to convert
Expand Down Expand Up @@ -1489,40 +1498,6 @@ else if( i == 0 ){
} // end else
} // end read


/**
* Calls {@link #read()} repeatedly until the end of stream
* is reached or <var>len</var> bytes are read.
* Returns number of bytes read into array or -1 if
* end of stream is encountered.
*
* @param dest array to hold values
* @param off offset for array
* @param len max number of bytes to read into array
* @return bytes read into array or -1 if end of stream is encountered.
* @since 1.3
*/
@Override
public int read( byte[] dest, int off, int len )
throws java.io.IOException {
int i;
int b;
for( i = 0; i < len; i++ ) {
b = read();

if( b >= 0 ) {
dest[off + i] = (byte) b;
}
else if( i == 0 ) {
return -1;
}
else {
break; // Out of 'for' loop
} // Out of 'for' loop
} // end for: each byte read
return i;
} // end read

} // end inner class InputStream


Expand Down Expand Up @@ -1756,3 +1731,4 @@ public void resumeEncoding() {


} // end class Base64
//@formatter:on
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright (C) 2015 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.fabric8.kubernetes.client.utils.internal;

import org.junit.jupiter.api.Test;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

import static org.junit.jupiter.api.Assertions.assertEquals;

class Base64Test {

@Test
void testSkip() throws IOException {
Base64.InputStream is = new Base64.InputStream(
new ByteArrayInputStream(Base64.encodeBytesToBytes("hello".getBytes(StandardCharsets.UTF_8))));
assertEquals(104, is.read());
assertEquals(3, is.skip(3));
assertEquals(111, is.read());
assertEquals(-1, is.read());
}
}
53 changes: 53 additions & 0 deletions kubernetes-itests/src/test/java/io/fabric8/kubernetes/PodIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import io.fabric8.kubernetes.client.dsl.ExecWatch;
import io.fabric8.kubernetes.client.dsl.PodResource;
import io.fabric8.kubernetes.client.readiness.Readiness;
import io.fabric8.kubernetes.client.utils.InputStreamPumper;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -49,6 +51,7 @@
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -215,6 +218,43 @@ public void onExit(int code, Status status) {
assertNotNull(out.toString());
}

@Test
void execExitCode() throws Exception {
client.pods().withName("pod-standard").waitUntilReady(POD_READY_WAIT_IN_SECONDS, TimeUnit.SECONDS);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ExecWatch watch = client.pods().withName("pod-standard")
.writingOutput(out)
.exec("sh", "-c", "echo 'hello world!'");
assertEquals(0, watch.exitCode().join());
assertNotNull("hello world!", out.toString());
}

@Test
void execInteractiveShell() throws Exception {
client.pods().withName("pod-standard").waitUntilReady(POD_READY_WAIT_IN_SECONDS, TimeUnit.SECONDS);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ExecWatch watch = client.pods().withName("pod-standard")
.redirectingInput()
.redirectingOutput()
.redirectingError()
.withTTY()
.exec("sh", "-i");

InputStreamPumper.pump(watch.getOutput(), baos::write, Executors.newSingleThreadExecutor());

watch.getInput().write("whoami\n".getBytes(StandardCharsets.UTF_8));
watch.getInput().flush();

Awaitility.await().atMost(30, TimeUnit.SECONDS).until(() -> {
return new String(baos.toByteArray(), StandardCharsets.UTF_8).contains("root");
});

watch.close();

// no error is expected
assertEquals(-1, watch.getError().read());
}

@Test
void readFile() throws IOException {
client.pods().withName("pod-standard").waitUntilReady(POD_READY_WAIT_IN_SECONDS, TimeUnit.SECONDS);
Expand Down Expand Up @@ -285,6 +325,19 @@ void uploadDir() throws IOException {
}
}

@Test
void copyDir() throws IOException {
client.pods().withName("pod-standard").waitUntilReady(POD_READY_WAIT_IN_SECONDS, TimeUnit.SECONDS);

final Path tmpDir = Files.createTempDirectory("copyFile");

PodResource podResource = client.pods().withName("pod-standard");
podResource.dir("/etc").copy(tmpDir);

Path msg = tmpDir.resolve("/etc/hosts");
assertTrue(Files.exists(msg));
}

@Test
void copyFile() throws IOException {
client.pods().withName("pod-standard").waitUntilReady(POD_READY_WAIT_IN_SECONDS, TimeUnit.SECONDS);
Expand Down

0 comments on commit 0687d7c

Please sign in to comment.