This closes #900

This commit is contained in:
Clebert Suconic 2016-12-01 17:48:17 -05:00
commit 895ffb5b3c
7 changed files with 86 additions and 0 deletions

View File

@ -25,6 +25,7 @@ public class ActiveMQStompException extends Exception {
public static final int NONE = 0; public static final int NONE = 0;
public static final int INVALID_EOL_V10 = 1; public static final int INVALID_EOL_V10 = 1;
public static final int INVALID_COMMAND = 2; public static final int INVALID_COMMAND = 2;
public static final int UNDEFINED_ESCAPE = 3;
private static final long serialVersionUID = -274452327574950068L; private static final long serialVersionUID = -274452327574950068L;

View File

@ -150,4 +150,7 @@ public interface ActiveMQStompProtocolMessageBundle {
@Message(id = 339039, value = "No id header in ACK/NACK frame.") @Message(id = 339039, value = "No id header in ACK/NACK frame.")
ActiveMQStompException noIDInAck(); ActiveMQStompException noIDInAck();
@Message(id = 339040, value = "Undefined escape sequence: {0}", format = Message.Format.MESSAGE_FORMAT)
ActiveMQStompException undefinedEscapeSequence(String sequence);
} }

View File

@ -121,6 +121,7 @@ public final class StompConnection implements RemotingConnection {
frame = decode(buffer); frame = decode(buffer);
break; break;
case ActiveMQStompException.INVALID_COMMAND: case ActiveMQStompException.INVALID_COMMAND:
case ActiveMQStompException.UNDEFINED_ESCAPE:
frameHandler.onError(e); frameHandler.onError(e);
break; break;
default: default:

View File

@ -558,6 +558,12 @@ public class StompFrameHandlerV11 extends VersionedStompFrameHandler implements
} }
} }
protected void throwUndefinedEscape(byte b) throws ActiveMQStompException {
ActiveMQStompException error = BUNDLE.undefinedEscapeSequence(new String(new char[]{ESC_CHAR, (char) b})).setHandler(handler);
error.setCode(ActiveMQStompException.UNDEFINED_ESCAPE);
throw error;
}
@Override @Override
protected boolean parseHeaders() throws ActiveMQStompException { protected boolean parseHeaders() throws ActiveMQStompException {
@ -645,6 +651,9 @@ public class StompFrameHandlerV11 extends VersionedStompFrameHandler implements
headerValueWhitespace = false; headerValueWhitespace = false;
if (isEscaping) {
throwUndefinedEscape(b);
}
holder.append(b); holder.append(b);
} }
} }

View File

@ -230,6 +230,9 @@ public class StompFrameHandlerV12 extends StompFrameHandlerV11 {
headerValueWhitespace = false; headerValueWhitespace = false;
if (isEscaping) {
throwUndefinedEscape(b);
}
holder.append(b); holder.append(b);
} }
} }

View File

@ -389,6 +389,39 @@ public class StompV11Test extends StompV11TestBase {
newConn.disconnect(); newConn.disconnect();
} }
/**
* In 1.1, undefined escapes must cause a fatal protocol error.
*/
@Test
public void testHeaderUndefinedEscape() throws Exception {
connV11.connect(defUser, defPass);
ClientStompFrame frame = connV11.createFrame("SEND");
String body = "Hello World 1!";
String cLen = String.valueOf(body.getBytes(StandardCharsets.UTF_8).length);
frame.addHeader("destination", getQueuePrefix() + getQueueName());
frame.addHeader("content-type", "text/plain");
frame.addHeader("content-length", cLen);
String hKey = "undefined-escape";
String hVal = "is\\ttab";
frame.addHeader(hKey, hVal);
System.out.println("key: |" + hKey + "| val: |" + hVal + "|");
frame.setBody(body);
connV11.sendFrame(frame);
ClientStompFrame error = connV11.receiveFrame();
System.out.println("received " + error);
String desc = "Should have received an ERROR for undefined escape sequence";
Assert.assertNotNull(desc, error);
Assert.assertEquals(desc, "ERROR", error.getCommand());
}
@Test @Test
public void testHeartBeat() throws Exception { public void testHeartBeat() throws Exception {
//no heart beat at all if heat-beat absent //no heart beat at all if heat-beat absent

View File

@ -564,6 +564,42 @@ public class StompV12Test extends StompV11TestBase {
newConn.disconnect(); newConn.disconnect();
} }
/**
* In 1.2, undefined escapes must cause a fatal protocol error.
*/
@Test
public void testHeaderUndefinedEscape() throws Exception {
connV12.connect(defUser, defPass);
ClientStompFrame frame = connV12.createFrame("SEND");
String body = "Hello World 1!";
String cLen = String.valueOf(body.getBytes(StandardCharsets.UTF_8).length);
frame.addHeader("destination", getQueuePrefix() + getQueueName());
frame.addHeader("content-type", "text/plain");
frame.addHeader("content-length", cLen);
String hKey = "undefined-escape";
String hVal = "is\\ttab";
frame.addHeader(hKey, hVal);
System.out.println("key: |" + hKey + "| val: |" + hVal + "|");
frame.setBody(body);
connV12.sendFrame(frame);
ClientStompFrame error = connV12.receiveFrame();
System.out.println("received " + error);
String desc = "Should have received an ERROR for undefined escape sequence";
Assert.assertNotNull(desc, error);
Assert.assertEquals(desc, "ERROR", error.getCommand());
waitDisconnect(connV12);
Assert.assertFalse("Should be disconnected in STOMP 1.2 after ERROR", connV12.isConnected());
}
@Test @Test
public void testHeartBeat() throws Exception { public void testHeartBeat() throws Exception {
StompClientConnection conn = StompClientConnectionFactory.createClientConnection("1.2", hostname, port); StompClientConnection conn = StompClientConnectionFactory.createClientConnection("1.2", hostname, port);