Skip to content

Commit b2515e9

Browse files
committed
Ensure setupPayload is actually copied
Closes gh-970 Signed-off-by: Rossen Stoyanchev <[email protected]>
1 parent 0601f88 commit b2515e9

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

rsocket-core/src/main/java/io/rsocket/core/RSocketConnector.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2020 the original author or authors.
2+
* Copyright 2015-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -153,12 +153,24 @@ public RSocketConnector setupPayload(Payload payload) {
153153
if (payload instanceof DefaultPayload) {
154154
this.setupPayloadMono = Mono.just(payload);
155155
} else {
156-
this.setupPayloadMono = Mono.just(DefaultPayload.create(Objects.requireNonNull(payload)));
156+
this.setupPayloadMono = Mono.just(copyPayload(payload));
157157
payload.release();
158158
}
159159
return this;
160160
}
161161

162+
private Payload copyPayload(Payload payload) {
163+
Objects.requireNonNull(payload);
164+
byte[] dataBytes = new byte[payload.data().readableBytes()];
165+
payload.data().readBytes(dataBytes);
166+
byte[] metadataBytes = null;
167+
if (payload.metadata().readableBytes() > 0) {
168+
metadataBytes = new byte[payload.metadata().readableBytes()];
169+
payload.metadata().readBytes(metadataBytes);
170+
}
171+
return DefaultPayload.create(dataBytes, metadataBytes);
172+
}
173+
162174
/**
163175
* Set the MIME type to use for formatting payload data on the established connection. This is set
164176
* in the initial {@code SETUP} frame sent to the server.

rsocket-core/src/test/java/io/rsocket/core/RSocketConnectorTest.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,14 @@ public void ensuresThatSetupPayloadCanBeRetained() {
7373
@Test
7474
public void ensuresThatMonoFromRSocketConnectorCanBeUsedForMultipleSubscriptions() {
7575
Payload setupPayload = ByteBufPayload.create("TestData", "TestMetadata");
76-
7776
Assertions.assertThat(setupPayload.refCnt()).isOne();
7877

78+
// Keep the data and metadata around so we can try changing them independently
79+
ByteBuf dataBuf = setupPayload.data();
80+
ByteBuf metadataBuf = setupPayload.metadata();
81+
dataBuf.retain();
82+
metadataBuf.retain();
83+
7984
TestClientTransport testClientTransport = new TestClientTransport();
8085
Mono<RSocket> connectionMono =
8186
RSocketConnector.create().setupPayload(setupPayload).connect(testClientTransport);
@@ -92,6 +97,15 @@ public void ensuresThatMonoFromRSocketConnectorCanBeUsedForMultipleSubscriptions
9297
.expectComplete()
9398
.verify(Duration.ofMillis(100));
9499

100+
// Changing the original data and metadata should not impact the SetupPayload
101+
dataBuf.writerIndex(dataBuf.readerIndex());
102+
dataBuf.writeChar('d');
103+
dataBuf.release();
104+
105+
metadataBuf.writerIndex(metadataBuf.readerIndex());
106+
metadataBuf.writeChar('m');
107+
metadataBuf.release();
108+
95109
Assertions.assertThat(testClientTransport.testConnection().getSent())
96110
.hasSize(2)
97111
.allMatch(
@@ -100,7 +114,11 @@ public void ensuresThatMonoFromRSocketConnectorCanBeUsedForMultipleSubscriptions
100114
return payload.getDataUtf8().equals("TestData")
101115
&& payload.getMetadataUtf8().equals("TestMetadata");
102116
})
103-
.allMatch(ReferenceCounted::release);
117+
.allMatch(
118+
byteBuf -> {
119+
System.out.println("calling release " + byteBuf.refCnt());
120+
return byteBuf.release();
121+
});
104122
Assertions.assertThat(setupPayload.refCnt()).isZero();
105123
}
106124

0 commit comments

Comments
 (0)