Skip to content

Commit

Permalink
Prevent IAE for close reason phrase > 123 bytes
Browse files Browse the repository at this point in the history
Signed-off-by: jansupol <jan.supol@oracle.com>
  • Loading branch information
jansupol committed Feb 24, 2022
1 parent 422e0d0 commit 047c32c
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2017 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -43,6 +43,7 @@
import org.glassfish.tyrus.client.auth.AuthenticationException;
import org.glassfish.tyrus.client.auth.Authenticator;
import org.glassfish.tyrus.client.auth.Credentials;
import org.glassfish.tyrus.core.CloseReasons;
import org.glassfish.tyrus.core.DebugContext;
import org.glassfish.tyrus.core.Handshake;
import org.glassfish.tyrus.core.HandshakeException;
Expand Down Expand Up @@ -730,7 +731,7 @@ public void handle(ByteBuffer data) {
socket.onClose(new CloseFrame(e.getCloseReason()));
} catch (Exception e) {
LOGGER.log(Level.FINE, e.getMessage(), e);
socket.onClose(new CloseFrame(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, e
socket.onClose(new CloseFrame(CloseReasons.create(CloseReason.CloseCodes.UNEXPECTED_CONDITION, e
.getMessage())));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2017 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -271,7 +271,7 @@ private void httpSessionForcedClose(int closeCode, String closeReason) {
private void close(int closeCode, String closeReason) {
if (!closed) {
try {
connection.close(new CloseReason(CloseReason.CloseCodes.getCloseCode(closeCode), closeReason));
connection.close(CloseReasons.create(CloseReason.CloseCodes.getCloseCode(closeCode), closeReason));
closed = true;
wc.close();
} catch (Exception e) {
Expand Down
30 changes: 29 additions & 1 deletion core/src/main/java/org/glassfish/tyrus/core/CloseReasons.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2017 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -17,6 +17,8 @@
package org.glassfish.tyrus.core;

import javax.websocket.CloseReason;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

/**
* Enum containing standard CloseReasons defined in RFC 6455, see chapter
Expand Down Expand Up @@ -149,4 +151,30 @@ public enum CloseReasons {
public CloseReason getCloseReason() {
return closeReason;
}

/* Utility CloseReason methods */

public static CloseReason create(CloseReason.CloseCode closeCode, String reasonPhrase) {
return new CloseReason(closeCode, trimTo123Bytes(reasonPhrase));
}

private static String trimTo123Bytes(String reasonPhrase) {
try {
final byte[] bytes;
return reasonPhrase == null
? reasonPhrase
: ((bytes = reasonPhrase.getBytes("UTF-8")).length <= 123)
? reasonPhrase
: new String(trimTo123Bytes(bytes), "UTF-8");
} catch (UnsupportedEncodingException uee) {
throw new IllegalArgumentException(uee);
}
}

private static byte[] trimTo123Bytes(byte[] bytes) {
byte[] newBytes = new byte[123];
System.arraycopy(bytes, 0, newBytes, 0, 120);
newBytes[120] = newBytes[121] = newBytes[122] = (byte) '.';
return newBytes;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -549,12 +549,7 @@ public void handle(ByteBuffer data) {
debugContext.appendLogMessageWithThrowable(LOGGER, Level.FINE, DebugContext.Type.MESSAGE_IN, e,
e.getMessage());
if (endpointWrapper.onError(socket, e)) {
if (message != null && message.length() > 123) {
// reason phrase length is limited.
message = message.substring(0, 123);
}
socket.onClose(
new CloseFrame(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, message)));
socket.onClose(new CloseFrame(CloseReasons.create(CloseReason.CloseCodes.UNEXPECTED_CONDITION, message)));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2017 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -82,7 +82,7 @@ public CloseReason getCloseReason() {
}
}

closeReason = new CloseReason(CloseReason.CloseCodes.getCloseCode(closeCode), closeReasonString);
closeReason = CloseReasons.create(CloseReason.CloseCodes.getCloseCode(closeCode), closeReasonString);
}

/**
Expand Down
53 changes: 53 additions & 0 deletions core/src/test/java/org/glassfish/tyrus/core/CloseReasonsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://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: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.tyrus.core;

import javax.websocket.CloseReason;
import org.junit.Assert;
import org.junit.Test;

public class CloseReasonsTest {
@Test
public void testReasonOfLength123() {
String reason = createStringOfLength(123);
CloseReason closeReason = CloseReasons.create(CloseReason.CloseCodes.NO_STATUS_CODE, reason);
Assert.assertEquals(reason, closeReason.getReasonPhrase());
}

@Test
public void testReasonOfLength124() {
String reason = createStringOfLength(124);
CloseReason closeReason = CloseReasons.create(CloseReason.CloseCodes.NO_STATUS_CODE, reason);

String expected = createStringOfLength(120) + "...";
Assert.assertEquals(expected, closeReason.getReasonPhrase());
}

@Test
public void testNullReason() {
CloseReason closeReason = CloseReasons.create(CloseReason.CloseCodes.NO_STATUS_CODE, null);
Assert.assertEquals("", closeReason.getReasonPhrase());
}

private String createStringOfLength(int length) {
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i != length; i++) {
sb.append(i % 10);
}
return sb.toString();
}
}

0 comments on commit 047c32c

Please sign in to comment.