-
Notifications
You must be signed in to change notification settings - Fork 310
SSLEngine.unwrap precondition tests. #1414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1033,6 +1033,92 @@ private void assertWrapSucceeds(ByteBuffer[] buffers, int offset, int length) th | |
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void unwrapPreconditions() throws Exception { | ||
| int bufferSize = 128; | ||
| int arrayLength = 5; | ||
| ByteBuffer buffer = ByteBuffer.allocate(bufferSize); | ||
| ByteBuffer readOnlyBuffer = buffer.asReadOnlyBuffer(); | ||
| ByteBuffer[] buffers = BufferType.HEAP.newBufferArray(arrayLength, bufferSize); | ||
| ByteBuffer[] buffersWithNullEntry = Arrays.copyOf(buffers, buffers.length); | ||
| int nullBufferIndex = 2; | ||
| buffersWithNullEntry[nullBufferIndex] = null; | ||
| ByteBuffer[] buffersWithReadOnlyEntry = Arrays.copyOf(buffers, buffers.length); | ||
| int readOnlyBufferIndex = 2; | ||
| buffersWithReadOnlyEntry[readOnlyBufferIndex] = | ||
| buffersWithReadOnlyEntry[readOnlyBufferIndex].asReadOnlyBuffer(); | ||
|
|
||
| // Client/server mode not set => IllegalStateException | ||
| assertThrows( | ||
| IllegalStateException.class, () -> newUnconnectedEngine().unwrap(buffer, buffer)); | ||
| assertThrows( | ||
| IllegalStateException.class, () -> newUnconnectedEngine().unwrap(buffer, buffers)); | ||
| assertThrows(IllegalStateException.class, | ||
| () -> newUnconnectedEngine().unwrap(buffer, buffers, 0, 1)); | ||
|
|
||
| // Read-only destination => ReadOnlyBufferException | ||
| assertThrows(ReadOnlyBufferException.class, | ||
| () -> newConnectedEngine().unwrap(buffer, readOnlyBuffer)); | ||
| assertThrows(ReadOnlyBufferException.class, | ||
| () -> newConnectedEngine().unwrap(buffer, buffersWithReadOnlyEntry)); | ||
| assertThrows(ReadOnlyBufferException.class, | ||
| () | ||
| -> newConnectedEngine().unwrap( | ||
| buffer, buffersWithReadOnlyEntry, 0, arrayLength)); | ||
|
|
||
| // Null destination => IllegalArgumentException | ||
| assertThrows(IllegalArgumentException.class, | ||
| () -> newConnectedEngine().unwrap(buffer, (ByteBuffer) null)); | ||
| assertThrows(IllegalArgumentException.class, | ||
| () -> newConnectedEngine().unwrap(buffer, (ByteBuffer[]) null)); | ||
| assertThrows(IllegalArgumentException.class, | ||
| () -> newConnectedEngine().unwrap(buffer, null, 0, 1)); | ||
|
|
||
| // Null source => IllegalArgumentException | ||
| assertThrows( | ||
| IllegalArgumentException.class, () -> newConnectedEngine().unwrap(null, buffer)); | ||
| assertThrows( | ||
| IllegalArgumentException.class, () -> newConnectedEngine().unwrap(null, buffers)); | ||
| assertThrows(IllegalArgumentException.class, | ||
| () -> newConnectedEngine().unwrap(null, buffers, 0, 1)); | ||
|
|
||
| // Null entries in buffer array => IllegalArgumentException | ||
| assertThrows(IllegalArgumentException.class, | ||
| () -> newConnectedEngine().unwrap(buffer, buffersWithNullEntry)); | ||
| assertThrows(IllegalArgumentException.class, | ||
| () -> newConnectedEngine().unwrap(buffer, buffersWithNullEntry, 0, arrayLength)); | ||
|
|
||
| // Bad offset or length => IndexOutOfBoundsException | ||
| assertThrows(IndexOutOfBoundsException.class, | ||
| () -> newConnectedEngine().unwrap(buffer, buffers, 0, arrayLength + 1)); | ||
| assertThrows(IndexOutOfBoundsException.class, | ||
| () -> newConnectedEngine().unwrap(buffer, buffers, arrayLength, 1)); | ||
| wrapThenUnwrap(bufferSize, buffers, 0, arrayLength); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer to move wrapThenUnwrap into a new test.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the review! Just for clarity, you're basically suggesting to split into a precondition failures test and and precondition "should pass" test? I can do that and add suitable comments.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, exactly. it is also related to the other comment: for the prcondition pass test, can we re-use the input data? or should we create new input data for each test case, to make sure that the previous test doesn't change the test data?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The pass cases as they currently are, will often return an error due to data re-use, under/overflow etc but not throw. There are tests elsewhere to check data flows correctly. These tests are just to ensure that the preconditions checks performed by warp/unwrap behave as expected. That said, it's probably good practice to ensure that pass tests work end to end, so I'll split the wrap ones out too.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about something like #1420 ? |
||
| // Zero length array is allowed | ||
| wrapThenUnwrap(bufferSize, buffers, 0, 0); | ||
| wrapThenUnwrap(bufferSize, buffers, arrayLength, 0); | ||
| } | ||
|
|
||
| private void wrapThenUnwrap(int bufferSize, ByteBuffer[] dest, int offset, int length) | ||
| throws Exception { | ||
| ByteBuffer src = ByteBuffer.allocate(bufferSize); | ||
| ByteBuffer tlsBuffer = ByteBuffer.allocate(bufferSize + 128); | ||
| tlsBuffer.clear(); | ||
|
|
||
| try (TestSSLEnginePair pair = TestSSLEnginePair.create()) { | ||
| SSLEngineResult result = pair.client.wrap(src, tlsBuffer); | ||
| assertEquals(Status.OK, result.getStatus()); | ||
|
|
||
| tlsBuffer.flip(); | ||
| for (int i = offset; i < offset + length; i++) { | ||
| dest[i].clear(); | ||
| } | ||
| // Unwrap result ignored because unwrap may not succeed (e.g. overflowing zero length | ||
| // buffer array), but it should not throw any exception due to preconditions | ||
| pair.server.unwrap(tlsBuffer, dest, offset, length); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void bufferArrayOffsets() throws Exception{ | ||
| TestSSLEnginePair pair = TestSSLEnginePair.create(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test first sets up some test data, and then calls unwrap several times. This only works as expected if the test data is not changed, which is not guaranteed for unwrap. It should be fine here, because the precondition check should fail at the start before any changes to the input happen. But still, we should make sure that the reader is aware of this. So I think this should either create fresh input data for each call, or have a comment on why it is fine to reuse the input data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, I'll rework it.