Issue #4538 - add invalid utf8 validation tests for MessageReader
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
2467d5a8c5
commit
1b123b87a9
|
@ -23,6 +23,7 @@ import java.io.Reader;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
|
@ -63,19 +64,25 @@ public class MessageReader extends Reader implements MessageSink
|
|||
public int read(char[] cbuf, int off, int len) throws IOException
|
||||
{
|
||||
CharBuffer charBuffer = CharBuffer.wrap(cbuf, off, len);
|
||||
if (!buffer.hasRemaining())
|
||||
boolean endOfInput = false;
|
||||
while (true)
|
||||
{
|
||||
int read = stream.read(buffer);
|
||||
if (read == 0)
|
||||
return read;
|
||||
break;
|
||||
if (read < 0)
|
||||
{
|
||||
utf8Decoder.decode(BufferUtil.EMPTY_BUFFER, charBuffer, true);
|
||||
return (charBuffer.position() > 0) ? charBuffer.position() : read;
|
||||
endOfInput = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
utf8Decoder.decode(buffer, charBuffer, false);
|
||||
CoderResult result = utf8Decoder.decode(buffer, charBuffer, endOfInput);
|
||||
if (result.isError())
|
||||
result.throwException();
|
||||
|
||||
if (endOfInput && (charBuffer.position() == 0))
|
||||
return -1;
|
||||
return charBuffer.position();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,34 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under
|
||||
// the terms of the Eclipse Public License 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// This Source Code may also be made available under the following
|
||||
// Secondary Licenses when the conditions for such availability set
|
||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||
// the Apache License v2.0 which is available at
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.MalformedInputException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.websocket.core.Frame;
|
||||
import org.eclipse.jetty.websocket.core.OpCode;
|
||||
import org.eclipse.jetty.websocket.util.messages.MessageReader;
|
||||
|
@ -90,10 +112,25 @@ public class MessageReaderTest
|
|||
assertThat(cause.getMessage(), is("Closed"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidUtf8() throws Exception
|
||||
{
|
||||
ByteBuffer invalidUtf8Payload = BufferUtil.toBuffer(new byte[]{0x7F, (byte)0xFF, (byte)0xFF});
|
||||
giveByteBuffer(invalidUtf8Payload, true);
|
||||
|
||||
ExecutionException error = assertThrows(ExecutionException.class, () -> message.get(5, TimeUnit.SECONDS));
|
||||
assertThat(error.getCause(), instanceOf(MalformedInputException.class));
|
||||
}
|
||||
|
||||
private void giveString(String s, boolean last) throws IOException
|
||||
{
|
||||
giveByteBuffer(ByteBuffer.wrap(StringUtil.getUtf8Bytes(s)), last);
|
||||
}
|
||||
|
||||
private void giveByteBuffer(ByteBuffer buffer, boolean last) throws IOException
|
||||
{
|
||||
byte opCode = first ? OpCode.TEXT : OpCode.CONTINUATION;
|
||||
Frame frame = new Frame(opCode, last, s);
|
||||
Frame frame = new Frame(opCode, last, buffer);
|
||||
FutureCallback callback = new FutureCallback();
|
||||
reader.accept(frame, callback);
|
||||
callback.block(5, TimeUnit.SECONDS);
|
||||
|
|
Loading…
Reference in New Issue