[continued from previous message]
++/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file
to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*
http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by
applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing
permissions and
* limitations under the License.
*/
package org.apache.activemq.openwire.v9;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.activemq.openwire.*;
import org.apache.activemq.command.*;
/**
* Marshalling code for Open Wire Format for WireFormatInfoMarshaller
*
*
* NOTE!: This file is auto generated - do not modify!
* if you need to make a change, please see the modify the groovy scripts in the
* under src/gram/
script and then use maven openwire:generate to regenerate
* this file.
*
*
*/
public class WireFormatInfoMarshaller extends BaseDataStreamMarshaller {
/**
* Return the type of Data Structure we marshal
* @return short
representation of the type data structure
*/
public byte getDataStructureType() {
return WireFormatInfo.DATA_STRUCTURE_TYPE;
}
/**
* @return a new object instance
*/
public DataStructure createObject() {
return new WireFormatInfo();
}
/**
* Un-marshal an object instance from the data input stream
*
* @param o the object to un-marshal
* @param dataIn the data input stream to build the object from
* @throws IOException
*/
public void tightUnmarshal(OpenWireFormat wireFormat, Object o, DataInput dataIn, BooleanStream bs) throws IOException {
super.tightUnmarshal(wireFormat, o, dataIn, bs);
WireFormatInfo info = (WireFormatInfo)o;
info.
beforeUnmarshall(wireFormat);
info.setMagic(tightUnmarshalConstByteArray(dataIn, bs, 8));
info.setVersion(dataIn.readInt());
info.setMarshalledProperties(tightUnmarshalByteSequence(wireFormat, dataIn, bs));
info.
afterUnmarshall(wireFormat);
}
/**
* Write the booleans that this object uses to a BooleanStream
*/
public int tightMarshal1(OpenWireFormat wireFormat, Object o, BooleanStream bs) throws IOException {
WireFormatInfo info
= (WireFormatInfo)o;
info.beforeMarshall(wireFormat);
int rc = super.tightMarshal1(wireFormat, o, bs);
rc += tightMarshalConstByteArray1(info.getMagic(), bs, 8);
rc += tightMarshalByteSequence1(info.
getMarshalledProperties(), bs);
return rc + 4;
}
/**
* Write a object instance to data output stream
*
* @param o the instance to be marshaled
* @param dataOut the output stream
* @throws IOException thrown if
an error occurs
*/
public void tightMarshal2(OpenWireFormat wireFormat, Object o, DataOutput dataOut, BooleanStream bs) throws IOException {
super.tightMarshal2(wireFormat, o, dataOut, bs);
WireFormatInfo info = (WireFormatInfo)
o;
tightMarshalConstByteArray2(info.getMagic(), dataOut, bs, 8);
dataOut.writeInt(info.getVersion());
tightMarshalByteSequence2(info.getMarshalledProperties(), dataOut, bs);
info.afterMarshall(wireFormat);
}
/**
* Un-marshal an object instance from the data input stream
*
* @param o the object to un-marshal
* @param dataIn the data input stream to build the object from
* @throws IOException
*/
public void looseUnmarshal(
OpenWireFormat wireFormat, Object o, DataInput dataIn) throws IOException {
super.looseUnmarshal(wireFormat, o, dataIn);
WireFormatInfo info = (WireFormatInfo)o;
info.beforeUnmarshall(wireFormat);
info.setMagic(
looseUnmarshalConstByteArray(dataIn, 8));
info.setVersion(dataIn.readInt());
info.setMarshalledProperties(looseUnmarshalByteSequence(wireFormat, dataIn));
info.afterUnmarshall(wireFormat);
}
/**
* Write the
booleans that this object uses to a BooleanStream
*/
public void looseMarshal(OpenWireFormat wireFormat, Object o, DataOutput dataOut) throws IOException {
WireFormatInfo info = (WireFormatInfo)o;
info.beforeMarshall(wireFormat)
;
super.looseMarshal(wireFormat, o, dataOut);
looseMarshalConstByteArray(wireFormat, info.getMagic(), dataOut, 8);
dataOut.writeInt(info.getVersion());
looseMarshalByteSequence(wireFormat, info.getMarshalledProperties(), dataOut);
}
}
+\ No newline at end of file
+--- a/activemq-client/src/main/java/org/apache/activemq/openwire/v9/XATransactionIdMarshaller.java
++++ b/activemq-client/src/main/java/org/apache/activemq/openwire/v9/XATransactionIdMarshaller.java
+@@ -1 +1 @@
+-/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file
to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*
http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by
applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing
permissions and
* limitations under the License.
*/
package org.apache.activemq.openwire.v9;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.activemq.openwire.*;
import org.apache.activemq.command.*;
/**
* Marshalling code for Open Wire Format for XATransactionIdMarshaller
*
*
* NOTE!: This file is auto generated - do not modify!
* if you need to make a change, please see the modify the groovy scripts in the
* under src/gram/
script and then use maven openwire:generate to regenerate
* this file.
*
*
*/
public class XATransactionIdMarshaller extends TransactionIdMarshaller {
/**
* Return the type of Data Structure we marshal
* @return short
representation of the type data structure
*/
public byte getDataStructureType() {
return XATransactionId.DATA_STRUCTURE_TYPE;
}
/**
* @return a new object instance
*/
public DataStructure createObject() {
return new XATransactionId();
}
/**
* Un-marshal an object instance from the data input stream
*
* @param o the object to un-marshal
* @param dataIn the data input stream to build the object from
* @throws IOException
*/
public void tightUnmarshal(OpenWireFormat wireFormat, Object o, DataInput dataIn, BooleanStream bs) throws IOException {
super.tightUnmarshal(wireFormat, o, dataIn, bs);
XATransactionId info = (XATransactionId)o;
info.
setFormatId(dataIn.readInt());
info.setGlobalTransactionId(tightUnmarshalByteArray(dataIn, bs));
info.setBranchQualifier(tightUnmarshalByteArray(dataIn, bs));
}
/**
* Write the booleans that this object uses to a
BooleanStream
*/
public int tightMarshal1(OpenWireFormat wireFormat, Object o, BooleanStream bs) throws IOException {
XATransactionId info = (XATransactionId)o;
int rc = super.tightMarshal1(wireFormat, o, bs);
rc +=
tightMarshalByteArray1(info.getGlobalTransactionId(), bs);
rc += tightMarshalByteArray1(info.getBranchQualifier(), bs);
return rc + 4;
}
/**
* Write a object instance to data output stream
*
* @param o the
instance to be marshaled
* @param dataOut the output stream
* @throws IOException thrown if an error occurs
*/
public void tightMarshal2(OpenWireFormat wireFormat, Object o, DataOutput dataOut, BooleanStream bs) throws IOException {
super.tightMarshal2(wireFormat, o, dataOut, bs);
XATransactionId info = (XATransactionId)o;
dataOut.writeInt(info.getFormatId());
tightMarshalByteArray2(info.getGlobalTransactionId(), dataOut, bs);
tightMarshalByteArray2(info.getBranchQualifier(), dataOut, bs);
}
/**
* Un-marshal an object instance from the data input stream
*
* @param o the object to un-marshal
* @param dataIn the data input stream to build the object
from
* @throws IOException
*/
public void looseUnmarshal(OpenWireFormat wireFormat, Object o, DataInput dataIn) throws IOException {
super.looseUnmarshal(wireFormat, o, dataIn);
XATransactionId info = (XATransactionId)o;
info.setFormatId(dataIn.readInt());
info.setGlobalTransactionId(looseUnmarshalByteArray(dataIn));
info.setBranchQualifier(looseUnmarshalByteArray(dataIn));
}
/**
* Write the booleans that this object uses to a
BooleanStream
*/
public void looseMarshal(OpenWireFormat wireFormat, Object o, DataOutput dataOut) throws IOException {
XATransactionId info = (XATransactionId)o;
super.looseMarshal(wireFormat, o, dataOut);
dataOut.
writeInt(info.getFormatId());
looseMarshalByteArray(wireFormat, info.getGlobalTransactionId(), dataOut);
looseMarshalByteArray(wireFormat, info.getBranchQualifier(), dataOut);
}
}
+\ No newline at end of file
++/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file
to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*
http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by
applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing
permissions and
* limitations under the License.
*/
package org.apache.activemq.openwire.v9;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.activemq.openwire.*;
import org.apache.activemq.command.*;
/**
* Marshalling code for Open Wire Format for XATransactionIdMarshaller
*
*
* NOTE!: This file is auto generated - do not modify!
* if you need to make a change, please see the modify the groovy scripts in the
* under src/gram/
script and then use maven openwire:generate to regenerate
* this file.
*
*
*/
public class XATransactionIdMarshaller extends TransactionIdMarshaller {
/**
* Return the type of Data Structure we marshal
* @return short
representation of the type data structure
*/
public byte getDataStructureType() {
return XATransactionId.DATA_STRUCTURE_TYPE;
}
/**
* @return a new object instance
*/
public DataStructure createObject() {
return new XATransactionId();
}
/**
* Un-marshal an object instance from the data input stream
*
* @param o the object to un-marshal
* @param dataIn the data input stream to build the object from
* @throws IOException
*/
public void tightUnmarshal(OpenWireFormat wireFormat, Object o, DataInput dataIn, BooleanStream bs) throws IOException {
super.tightUnmarshal(wireFormat, o, dataIn, bs);
XATransactionId info = (XATransactionId)o;
info.
setFormatId(dataIn.readInt());
info.setGlobalTransactionId(tightUnmarshalByteArray(wireFormat, dataIn, bs));
info.setBranchQualifier(tightUnmarshalByteArray(wireFormat, dataIn, bs));
}
/**
* Write the booleans that this
object uses to a BooleanStream
*/
public int tightMarshal1(OpenWireFormat wireFormat, Object o, BooleanStream bs) throws IOException {
XATransactionId info = (XATransactionId)o;
int rc = super.tightMarshal1(wireFormat, o, bs);
rc += tightMarshalByteArray1(info.getGlobalTransactionId(), bs);
rc += tightMarshalByteArray1(info.getBranchQualifier(), bs);
return rc + 4;
}
/**
* Write a object instance to data output stream
*
* @param
o the instance to be marshaled
* @param dataOut the output stream
* @throws IOException thrown if an error occurs
*/
public void tightMarshal2(OpenWireFormat wireFormat, Object o, DataOutput dataOut, BooleanStream bs) throws
IOException {
super.tightMarshal2(wireFormat, o, dataOut, bs);
XATransactionId info = (XATransactionId)o;
dataOut.writeInt(info.getFormatId());
tightMarshalByteArray2(info.getGlobalTransactionId(), dataOut, bs);
tightMarshalByteArray2(info.getBranchQualifier(), dataOut, bs);
}
/**
* Un-marshal an object instance from the data input stream
*
* @param o the object to un-marshal
* @param dataIn the data input stream to build the object
from
* @throws IOException
*/
public void looseUnmarshal(OpenWireFormat wireFormat, Object o, DataInput dataIn) throws IOException {
super.looseUnmarshal(wireFormat, o, dataIn);
XATransactionId info = (XATransactionId)o;
info.setFormatId(dataIn.readInt());
info.setGlobalTransactionId(looseUnmarshalByteArray(wireFormat, dataIn));
info.setBranchQualifier(looseUnmarshalByteArray(wireFormat, dataIn));
}
/**
* Write the booleans that this
object uses to a BooleanStream
*/
public void looseMarshal(OpenWireFormat wireFormat, Object o, DataOutput dataOut) throws IOException {
XATransactionId info = (XATransactionId)o;
super.looseMarshal(wireFormat, o, dataOut);
dataOut.writeInt(info.getFormatId());
looseMarshalByteArray(wireFormat, info.getGlobalTransactionId(), dataOut);
looseMarshalByteArray(wireFormat, info.getBranchQualifier(), dataOut);
}
}
+\ No newline at end of file
+--- a/activemq-client/src/main/java/org/apache/activemq/util/ByteSequence.java ++++ b/activemq-client/src/main/java/org/apache/activemq/util/ByteSequence.java +@@ -17,6 +17,8 @@
+
+ package org.apache.activemq.util;
+
++import java.util.Arrays;
++
+ public class ByteSequence {
+
+ public byte[] data;
+@@ -126,4 +128,14 @@
+ }
+ return true;
+ }
++
++ /**
++ * Makes a deep copy of the data into a new byte array
++ * starting at the offset.
++ *
++ * @return
++ */
++ public byte[] toArray() {
++ return Arrays.copyOfRange(getData(), getOffset(), getLength());
++ }
+ }
+--- a/activemq-client/src/main/java/org/apache/activemq/util/IOExceptionSupport.java
++++ b/activemq-client/src/main/java/org/apache/activemq/util/IOExceptionSupport.java
+@@ -52,7 +52,13 @@
+
+ public static IOException createFrameSizeException(int size, long maxSize) {
+ return new MaxFrameSizeExceededException("Frame size of " + toHumanReadableSizeString(size) +
+- " larger than max allowed " + toHumanReadableSizeString(maxSize));
++ " is larger than max allowed " + toHumanReadableSizeString(maxSize));
++ }
++
++ public static IOException createFrameSizeBufferException(int bufferSize, long frameSize) {
++ return new IOException("Estimated allocated buffer size of "
++ + toHumanReadableSizeString(bufferSize) + " is larger than frame size of "
++ + toHumanReadableSizeString(frameSize));
+ }
+
+ private static String toHumanReadableSizeString(final int size) {
+--- /dev/null
++++ b/activemq-client/src/test/java/org/apache/activemq/openwire/OpenWireUtilTest.java
+@@ -0,0 +1,119 @@
++/**
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ *
http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.apache.activemq.openwire;
++
++
++import javax.jms.InvalidClientIDException;
++import javax.jms.JMSException;
++import org.apache.activemq.ActiveMQConnection;
++import org.apache.activemq.MaxFrameSizeExceededException;
++import org.apache.activemq.command.WireFormatInfo;
++import org.junit.Test;
++
++import java.io.IOException;
++import java.lang.reflect.Field;
++
++import static org.junit.Assert.assertEquals;
++import static org.junit.Assert.fail;
++
++public class OpenWireUtilTest {
++
++ @Test
++ public void testValidateIsThrowable() {
++ OpenWireUtil.validateIsThrowable(Exception.class);
++ OpenWireUtil.validateIsThrowable(Throwable.class);
++ OpenWireUtil.validateIsThrowable(JMSException.class);
++ OpenWireUtil.validateIsThrowable(InvalidClientIDException.class);
++
++ try {
++ OpenWireUtil.validateIsThrowable(String.class);
++ fail("Not a valid Throwable");
++ } catch (IllegalArgumentException e) {
++ // expected
++ }
++
++ try {
++ OpenWireUtil.validateIsThrowable(ActiveMQConnection.class);
++ fail("Not a valid Throwable");
++ } catch (IllegalArgumentException e) {
++ // expected
++ }
++ }
++
++ @Test
++ public void testConvertJmsPackage() {
++ // should not change
++ assertEquals(InvalidClientIDException.class.getName(),
++ OpenWireUtil.convertJmsPackage(InvalidClientIDException.class.getName()));
++
++ // should convert to correct exception type
++ assertEquals(InvalidClientIDException.class.getName(),
++ OpenWireUtil.convertJmsPackage(OpenWireUtil.jmsPackageToReplace + ".InvalidClientIDException"));
++ }
++
++ @Test
++ public void testValidateBufferSize() throws IOException {
++ OpenWireFormatFactory factory = new OpenWireFormatFactory();
++
++ var wireFormat = (OpenWireFormat) factory.createWireFormat();
++
++ // Nothing set, no validation
++ OpenWireUtil.validateBufferSize(wireFormat, 2048);
++
++ // verify max frame check works
++ try {
++ wireFormat.setMaxFrameSize(1024);
++ OpenWireUtil.validateBufferSize(wireFormat, 2048);
++ fail("should have failed");
++ } catch (MaxFrameSizeExceededException e) {
++ // expected
++ }
++
++ // rest max frame size back so we can test validating current size
++ // is less than expected buffer size
++ wireFormat.setMaxFrameSize(OpenWireFormat.DEFAULT_MAX_FRAME_SIZE);
++ WireFormatInfo wfi = new WireFormatInfo();
++ wfi.setProperty("test", "test");
++
++ // should be no error for the first 2 calls, last call should
++ // go over frame size and error
++ initContext(wireFormat, 2048);
++ OpenWireUtil.validateBufferSize(wireFormat, 1024);
++ OpenWireUtil.validateBufferSize(wireFormat, 1024);
++ try {
++ OpenWireUtil.validateBufferSize(wireFormat, 1);
++ fail("should have failed");
++ } catch (IOException e) {
++ // expected
++ }
++ }
++
++ @SuppressWarnings("unchecked")
++ private void initContext(OpenWireFormat format, int frameSize) throws IOException {
++ try {
++ Field mcThreadLocalField = OpenWireFormat.class.getDeclaredField("marshallingContext");
++ mcThreadLocalField.setAccessible(true);
++ var mcThreadLocal = (ThreadLocal<OpenWireFormat.MarshallingContext>) mcThreadLocalField.get(format);
++ var context = new OpenWireFormat.MarshallingContext();
++ context.setFrameSize(frameSize);
++ mcThreadLocal.set(context);
++ } catch (ReflectiveOperationException e) {
++ throw new RuntimeException(e);
++ }
++ }
++
++}
+--- a/activemq-client/src/test/java/org/apache/activemq/openwire/OpenWireValidationTest.java
++++ b/activemq-client/src/test/java/org/apache/activemq/openwire/OpenWireValidationTest.java
+@@ -16,25 +16,31 @@
+ */
+ package org.apache.activemq.openwire;
+
+-import static org.junit.Assert.assertTrue;
+-
++import java.io.DataInputStream;
+ import java.io.DataOutput;
+ import java.io.IOException;
++import java.lang.reflect.InvocationTargetException;
+ import java.lang.reflect.Method;
++import java.nio.ByteBuffer;
++import java.nio.charset.StandardCharsets;
+ import java.util.ArrayList;
+ import java.util.Collection;
+ import java.util.List;
+-import org.apache.activemq.command.CommandTypes;
+-import org.apache.activemq.command.ExceptionResponse;
++import javassist.util.proxy.MethodHandler;
++import javassist.util.proxy.ProxyFactory;
++import javassist.util.proxy.ProxyObject;
++import org.apache.activemq.command.*;
++import org.apache.activemq.transport.nio.NIOInputStream;
+ import org.apache.activemq.util.ByteSequence;
+ import org.junit.Test;
+ import org.junit.runner.RunWith;
+ import org.junit.runners.Parameterized;
+ import org.junit.runners.Parameterized.Parameters;
+
++import static org.junit.Assert.*;
++
+ /**
+- * Test that Openwire marshalling will validate Throwable types during
+- * unmarshalling commands that contain a Throwable
++ * Test that Openwire marshalling will validate commands correctly
+ */
+ @RunWith(Parameterized.class)
+ public class OpenWireValidationTest {
+@@ -53,7 +59,7 @@
+ // This will make sure that we don't forget to update this test to include
+ // any future versions that are generated
+ assertTrue("List of Openwire versions does not include latest version",
+- versions.contains((int)CommandTypes.PROTOCOL_VERSION));
++ versions.contains((int) CommandTypes.PROTOCOL_VERSION));
+
+ return versionObjs;
+ }
+@@ -63,20 +69,97 @@
+ }
+
+ @Test
++ public void testLooseUnmarshalByteSequenceValidation() throws Exception { ++ testUnmarshalByteSequenceValidation(false);
++ }
++
++ @Test
++ public void testTightUnmarshalByteSequenceValidation() throws Exception { ++ testUnmarshalByteSequenceValidation(true);
++ }
++
++ @Test
++ public void testLooseUnmarshalByteArray() throws Exception {
++ testUnmarshalByteArray(false);
++ }
++
++ @Test
++ public void testTightUnmarshalByteArray() throws Exception {
++ testUnmarshalByteArray(true);
++ }
++
++ // WireFormatInfo eventually delegates to BaseDataStreamMarshaller#tightUnmarshalByteSequence() and
++ // BaseDataStreamMarshaller#looseUnmarshalByteSequence()
++ private void testUnmarshalByteSequenceValidation(boolean tightEncoding) throws Exception {
++ WireFormatInfo wfi = new WireFormatInfo();
++ wfi.setProperty("prop1", "val1");
++ testUnmarshal(wfi, tightEncoding);
++ }
++
++ // PartialCommand eventually delegates to BaseDataStreamMarshaller#tightUnmarshalByteArray()
++ // and BaseDataStreamMarshaller#looseUnmarshalByteArray()
++ private void testUnmarshalByteArray(boolean tightEncoding) throws Exception {
++ PartialCommand pc = new PartialCommand();
++ pc.setData("bytes".getBytes(StandardCharsets.UTF_8));
++ testUnmarshal(pc, tightEncoding);
++ }
++
++ private void testUnmarshal(Command command, boolean tightEncoding) throws Exception {
++ var format = setupWireFormat(tightEncoding);
++ ByteSequence bss = format.marshal(command);
++ try {
++ // We should get an exception from an invalid size value that is too large
++ // Test OpenWireFormat#unmarshal(ByteSequence) method
++ format.unmarshal(bss);
++ fail("Should have received an IOException");
++ } catch (IOException io) {
++ assertTrue(io.getMessage().contains("Estimated allocated buffer size"));
++ assertTrue(io.getMessage().contains("is larger than frame size"));
++ }
++ // Verify thread local is cleared even after exception
++ assertNull(format.getMarshallingContext());
++
++ try {
++ // We should get an exception from an invalid size value that is too large
++ // Test OpenWireFormat#unmarshal(DataInput) method
++ format.unmarshal(new DataInputStream(new NIOInputStream(
++ ByteBuffer.wrap(bss.toArray()))));
++ fail("Should have received an IOException");
++ } catch (IOException io) {
++ assertTrue(io.getMessage().contains("Estimated allocated buffer size"));
++ assertTrue(io.getMessage().contains("is larger than frame size"));
++ }
++ // Verify thread local is cleared even after exception
++ assertNull(format.getMarshallingContext());
++ }
++
++ // Verify MarshallingContext thread local is cleared where there is
++ // successful unmarshalling and no error. The other tests that check
++ // validation works if invalid size will validate the context is cleared ++ // when there is an error
++ @Test
++ public void testUnmarshalNoErrorClearContext() throws Exception {
++ var format = new OpenWireFormat();
++ ByteSequence bss = format.marshal(new ConnectionInfo());
++
++ // make sure context cleared after calling
++ // OpenWireFormat#unmarshal(ByteSequence) method
++ format.unmarshal(bss);
++ assertNull(format.getMarshallingContext());
++
++ // Make sure context cleared after calling
++ // OpenWireFormat#unmarshal(DataInput) method
++ format.unmarshal(new DataInputStream(new NIOInputStream(
++ ByteBuffer.wrap(bss.toArray()))));
++ assertNull(format.getMarshallingContext());
++ }
++
++ @Test
+ public void testOpenwireThrowableValidation() throws Exception {
+ // Create a format which will use loose encoding by default
+ // The code for handling exception creation is shared between both
+ // tight/loose encoding so only need to test 1
+- OpenWireFormat format = new OpenWireFormat();
+-
+- // Override the marshaller map with a custom impl to purposely marshal a class type that is
+- // not a Throwable for testing the unmarshaller
+- Class<?> marshallerFactory = getMarshallerFactory();
+- Method createMarshallerMap = marshallerFactory.getMethod("createMarshallerMap", OpenWireFormat.class);
+- DataStreamMarshaller[] map = (DataStreamMarshaller[]) createMarshallerMap.invoke(marshallerFactory, format);
+- map[ExceptionResponse.DATA_STRUCTURE_TYPE] = getExceptionMarshaller();
+- // This will trigger updating the marshaller from the marshaller map with the right version
+- format.setVersion(version);
++ var format = setupWireFormat(false);
+
+ // Build the response and try to unmarshal which should give an IllegalArgumentExeption on unmarshall
+ // as the test marshaller should have encoded a class type that is not a Throwable
+@@ -89,6 +172,23 @@
+ assertTrue(response.getException().getMessage().contains("is not assignable to Throwable"));
+ }
+
++ private OpenWireFormat setupWireFormat(boolean tightEncoding) throws Exception {
++ // Create a format
++ OpenWireFormat format = new OpenWireFormat();
++ format.setTightEncodingEnabled(tightEncoding);
++
++ // Override the marshaller map with a custom impl to purposely marshal a bad size value
++ Class<?> marshallerFactory = getMarshallerFactory();
++ Method createMarshallerMap = marshallerFactory.getMethod("createMarshallerMap", OpenWireFormat.class);
++ DataStreamMarshaller[] map = (DataStreamMarshaller[]) createMarshallerMap.invoke(marshallerFactory, format);
++ map[ExceptionResponse.DATA_STRUCTURE_TYPE] = getExceptionMarshaller();
++ map[WireFormatInfo.DATA_STRUCTURE_TYPE] = getWireFormatInfoMarshaller();
++ map[PartialCommand.DATA_STRUCTURE_TYPE] = getPartialCommandMarshaller();
++ // This will trigger updating the marshaller from the marshaller map with the right version
++ format.setVersion(version);
++ return format;
++ }
++
+ static class NotAThrowable {
+ private String message;
+
+@@ -163,4 +263,127 @@
+ }
+ }
+
++ // Create test marshallers for all non-legacy versions
++ // WireFormatInfo will test the bytesequence marshallers
++ protected DataStreamMarshaller getWireFormatInfoMarshaller() {
++ switch (version) {
++ case 12:
++ return proxyBadBufferCommand(new org.apache.activemq.openwire.v12.WireFormatInfoMarshaller());
++ case 11:
++ return proxyBadBufferCommand(new org.apache.activemq.openwire.v11.WireFormatInfoMarshaller());
++ case 10:
++ return proxyBadBufferCommand(new org.apache.activemq.openwire.v10.WireFormatInfoMarshaller());
++ case 9:
++ return proxyBadBufferCommand(new org.apache.activemq.openwire.v9.WireFormatInfoMarshaller());
++ case 1:
++ return proxyBadBufferCommand(new org.apache.activemq.openwire.v1.WireFormatInfoMarshaller());
++ default:
++ throw new IllegalArgumentException("Unknown OpenWire version of " + version);
++ }
++ }
++
++ // PartialCommand will test the byte array marshallers
++ protected DataStreamMarshaller getPartialCommandMarshaller() {
++ switch (version) {
++ case 12:
++ return proxyBadBufferCommand(new org.apache.activemq.openwire.v12.PartialCommandMarshaller());
++ case 11:
++ return proxyBadBufferCommand(new org.apache.activemq.openwire.v11.PartialCommandMarshaller());
++ case 10:
++ return proxyBadBufferCommand(new org.apache.activemq.openwire.v10.PartialCommandMarshaller());
++ case 9:
++ return proxyBadBufferCommand(new org.apache.activemq.openwire.v9.PartialCommandMarshaller());
++ case 1:
++ return proxyBadBufferCommand(new org.apache.activemq.openwire.v1.PartialCommandMarshaller());
++ default:
++ throw new IllegalArgumentException("Unknown OpenWire version of " + version);
++ }
++ }
++
++ protected static void badTightMarshalByteSequence(ByteSequence data, DataOutput dataOut,
++ BooleanStream bs) throws IOException {
++ if (bs.readBoolean()) {
[continued in next message]
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)