• Bug#1104933: activemq: diff for NMU version 5.17.6+dfsg-1.1 (3/48)

    From Emmanuel Arias@1:229/2 to All on Sun Jun 1 01:20:01 2025
    [continued from previous message]

    ++ int size = bytesIn.readInt();
    ++ if (maxFrameSizeEnabled && size > maxFrameSize) {
    ++ throw IOExceptionSupport.createFrameSizeException(size, maxFrameSize);
    ++ }
    ++ context.setFrameSize(size);
    + }
    ++ return doUnmarshal(bytesIn);
    ++ } finally {
    ++ // After we unmarshal we can clear the context
    ++ marshallingContext.remove();
    + }
    +-
    +- Object command = doUnmarshal(bytesIn);
    +- // if( !cacheEnabled && ((DataStructure)command).isMarshallAware() ) {
    +- // ((MarshallAware) command).setCachedMarshalledForm(this, sequence); +- // }
    +- return command;
    + }
    +
    + @Override
    +@@ -275,19 +281,22 @@
    +
    + @Override
    + public Object unmarshal(DataInput dis) throws IOException {
    +- DataInput dataIn = dis;
    +- if (!sizePrefixDisabled) {
    +- int size = dis.readInt();
    +- if (maxFrameSizeEnabled && size > maxFrameSize) {
    +- throw IOExceptionSupport.createFrameSizeException(size, maxFrameSize);
    +- }
    +- // int size = dis.readInt();
    +- // byte[] data = new byte[size];
    +- // dis.readFully(data);
    +- // bytesIn.restart(data);
    +- // dataIn = bytesIn;
    ++ try {
    ++ final var context = new MarshallingContext();
    ++ marshallingContext.set(context);
    ++
    ++ if (!sizePrefixDisabled) {
    ++ int size = dis.readInt();
    ++ if (maxFrameSizeEnabled && size > maxFrameSize) {
    ++ throw IOExceptionSupport.createFrameSizeException(size, maxFrameSize);
    ++ }
    ++ context.setFrameSize(size);
    ++ }
    ++ return doUnmarshal(dis);
    ++ } finally {
    ++ // After we unmarshal we can clear
    ++ marshallingContext.remove();
    + }
    +- return doUnmarshal(dataIn);
    + }
    +
    + /**
    +@@ -363,7 +372,7 @@
    + this.version = version;
    + }
    +
    +- public Object doUnmarshal(DataInput dis) throws IOException {
    ++ private Object doUnmarshal(DataInput dis) throws IOException {
    + byte dataType = dis.readByte();
    + if (dataType != NULL_TYPE) {
    + DataStreamMarshaller dsm = dataMarshallers[dataType & 0xFF];
    +@@ -698,4 +707,47 @@
    + }
    + return version2;
    + }
    ++
    ++ MarshallingContext getMarshallingContext() {
    ++ return marshallingContext.get();
    ++ }
    ++
    ++ // Used to track the estimated allocated buffer sizes to validate
    ++ // against the current frame being processed
    ++ static class MarshallingContext {
    ++ // Use primitives to minimize memory footprint
    ++ private int frameSize = -1;
    ++ private int estimatedAllocated = 0;
    ++
    ++ void setFrameSize(int frameSize) throws IOException {
    ++ this.frameSize = frameSize;
    ++ if (frameSize < 0) {
    ++ throw error("Frame size " + frameSize + " can't be negative.");
    ++ }
    ++ }
    ++
    ++ void increment(int size) throws IOException {
    ++ if (size < 0) {
    ++ throw error("Size " + size + " can't be negative.");
    ++ }
    ++ try {
    ++ estimatedAllocated = Math.addExact(estimatedAllocated, size); ++ } catch (ArithmeticException e) {
    ++ throw error("Buffer overflow when incrementing size value: " + size);
    ++ }
    ++ }
    ++
    ++ public int getFrameSize() {
    ++ return frameSize;
    ++ }
    ++
    ++ public int getEstimatedAllocated() {
    ++ return estimatedAllocated;
    ++ }
    ++
    ++ private static IOException error(String errorMessage) {
    ++ return new IOException(new IllegalArgumentException(errorMessage));
    ++ }
    ++ }
    ++
    + }
    +--- a/activemq-client/src/main/java/org/apache/activemq/openwire/OpenWireUtil.java
    ++++ b/activemq-client/src/main/java/org/apache/activemq/openwire/OpenWireUtil.java
    +@@ -16,9 +16,56 @@
    + */
    + package org.apache.activemq.openwire;
    +
    ++import java.io.IOException;
    ++import org.apache.activemq.util.IOExceptionSupport;
    ++
    + public class OpenWireUtil {
    +
    + /**
    ++ * Verify that the buffer size that will be allocated will not push the total allocated
    ++ * size of this frame above the expected frame size. This is an estimate as the current
    ++ * size is only tracked when calls to this method are made and is primarily intended
    ++ * to prevent large arrays from being created due to an invalid size.
    ++ *
    ++ * Also verify the size against configured max frame size.
    ++ * This check is a sanity check in case of corrupt packets contain invalid size values.
    ++ *
    ++ * @param wireFormat configured OpenWireFormat
    ++ * @param size buffer size to verify
    ++ * @throws IOException If size is larger than currentFrameSize or maxFrameSize
    ++ */
    ++ public static void validateBufferSize(OpenWireFormat wireFormat, int size) throws IOException {
    ++ validateLessThanFrameSize(wireFormat, size);
    ++
    ++ // if currentFrameSize is set and was checked above then this check should not be needed,
    ++ // but it doesn't hurt to verify again in case the max frame size check was missed
    ++ // somehow
    ++ if (wireFormat.isMaxFrameSizeEnabled() && size > wireFormat.getMaxFrameSize()) {
    ++ throw IOExceptionSupport.createFrameSizeException(size, wireFormat.getMaxFrameSize());
    ++ }
    ++ }
    ++
    ++ // Verify total tracked sizes will not exceed the overall size of the frame
    ++ private static void validateLessThanFrameSize(OpenWireFormat wireFormat, int size)
    ++ throws IOException {
    ++ final var context = wireFormat.getMarshallingContext();
    ++ // No information on current frame size so just return
    ++ if (context == null || context.getFrameSize() < 0) {
    ++ return;
    ++ }
    ++
    ++ // Increment existing estimated buffer size with new size
    ++ context.increment(size);
    ++
    ++ // We should never be trying to allocate a buffer that is going to push the total
    ++ // size greater than the entire frame itself
    ++ if (context.getEstimatedAllocated() > context.getFrameSize()) {
    ++ throw IOExceptionSupport.createFrameSizeBufferException(
    ++ context.getEstimatedAllocated(), context.getFrameSize());
    ++ }
    ++ }
    ++
    ++ /**
    + * Verify that the provided class extends {@link Throwable} and throw an + * {@link IllegalArgumentException} if it does not.
    + *
    +--- a/activemq-client/src/main/java/org/apache/activemq/openwire/v1/BaseDataStreamMarshaller.java
    ++++ b/activemq-client/src/main/java/org/apache/activemq/openwire/v1/BaseDataStreamMarshaller.java
    +@@ -411,10 +411,11 @@
    + }
    + }
    +
    +- protected byte[] tightUnmarshalByteArray(DataInput dataIn, BooleanStream bs) throws IOException {
    ++ protected byte[] tightUnmarshalByteArray(OpenWireFormat wireFormat, DataInput dataIn, BooleanStream bs) throws IOException {
    + byte rc[] = null;
    + if (bs.readBoolean()) {
    + int size = dataIn.readInt();
    ++ OpenWireUtil.validateBufferSize(wireFormat, size);
    + rc = new byte[size];
    + dataIn.readFully(rc);
    + }

    [continued in next message]

    --- SoupGate-Win32 v1.05
    * Origin: you cannot sedate... all the things you hate (1:229/2)