Skip to content

Commit 59fe017

Browse files
committed
Don't call onComplete after onError in ChecksumValidatingSubscriber#onComplete method which results in NPE
1 parent dbbc0a8 commit 59fe017

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"category": "AWS SDK for Java v2",
3+
"type": "bugfix",
4+
"description": "Fix bug in ChecksumValidatingSubscriber which results in NPE if checksum validation fails."
5+
}

services/s3/src/main/java/software/amazon/awssdk/services/s3/checksums/ChecksumValidatingPublisher.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ public void onComplete() {
138138
onError(SdkClientException.create(
139139
String.format("Data read has a different checksum than expected. Was %d, but expected %d",
140140
computedChecksumInt, streamChecksumInt)));
141+
return; // Return after onError and not call onComplete below
141142
}
142143
}
143144
wrapped.onComplete();

services/s3/src/test/java/software/amazon/awssdk/services/s3/checksums/ChecksumValidatingPublisherTest.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,19 @@
1717

1818
import static org.junit.Assert.assertArrayEquals;
1919
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertFalse;
2021
import static org.junit.Assert.assertTrue;
2122
import static org.junit.Assert.fail;
2223

2324
import java.nio.ByteBuffer;
2425
import java.util.ArrayList;
2526
import java.util.Arrays;
2627
import java.util.List;
27-
2828
import org.junit.BeforeClass;
2929
import org.junit.Test;
3030
import org.reactivestreams.Publisher;
3131
import org.reactivestreams.Subscriber;
3232
import org.reactivestreams.Subscription;
33-
3433
import software.amazon.awssdk.core.checksums.Md5Checksum;
3534

3635
/**
@@ -66,6 +65,7 @@ public void testSinglePacket() {
6665
driver.doOnComplete();
6766

6867
assertTrue(s.hasCompleted());
68+
assertFalse(s.isOnErrorCalled());
6969
}
7070

7171
@Test
@@ -81,6 +81,7 @@ public void testTwoPackets() {
8181
driver.doOnComplete();
8282

8383
assertTrue(s.hasCompleted());
84+
assertFalse(s.isOnErrorCalled());
8485
}
8586
}
8687

@@ -100,6 +101,7 @@ public void testTinyPackets() {
100101
driver.doOnComplete();
101102

102103
assertTrue(s.hasCompleted());
104+
assertFalse(s.isOnErrorCalled());
103105
}
104106
}
105107

@@ -121,12 +123,29 @@ public void testUnknownLength() {
121123
driver.doOnComplete();
122124

123125
assertTrue(s.hasCompleted());
126+
assertFalse(s.isOnErrorCalled());
127+
}
128+
129+
@Test
130+
public void checksumValidationFailure_throwsSdkClientException_NotNPE() {
131+
final byte[] incorrectData = new byte[0];
132+
final TestPublisher driver = new TestPublisher();
133+
final TestSubscriber s = new TestSubscriber(Arrays.copyOfRange(incorrectData, 0, TEST_DATA_SIZE));
134+
final ChecksumValidatingPublisher p = new ChecksumValidatingPublisher(driver, new Md5Checksum(), TEST_DATA_SIZE + CHECKSUM_SIZE);
135+
p.subscribe(s);
136+
137+
driver.doOnNext(ByteBuffer.wrap(incorrectData));
138+
driver.doOnComplete();
139+
140+
assertTrue(s.isOnErrorCalled());
141+
assertFalse(s.hasCompleted());
124142
}
125143

126144
private class TestSubscriber implements Subscriber<ByteBuffer> {
127145
final byte[] expected;
128146
final List<ByteBuffer> received;
129147
boolean completed;
148+
boolean onErrorCalled;
130149

131150
TestSubscriber(byte[] expected) {
132151
this.expected = expected;
@@ -148,10 +167,9 @@ public void onNext(ByteBuffer buffer) {
148167

149168
@Override
150169
public void onError(Throwable t) {
151-
fail("Test failed");
170+
onErrorCalled = true;
152171
}
153172

154-
155173
@Override
156174
public void onComplete() {
157175
int matchPos = 0;
@@ -168,6 +186,10 @@ public void onComplete() {
168186
public boolean hasCompleted() {
169187
return completed;
170188
}
189+
190+
public boolean isOnErrorCalled() {
191+
return onErrorCalled;
192+
}
171193
}
172194

173195
private class TestPublisher implements Publisher<ByteBuffer> {

0 commit comments

Comments
 (0)