From 8cc10ae5461dc98d28a38e5977756718ed9f5da3 Mon Sep 17 00:00:00 2001 From: "Christopher L. Shannon" Date: Mon, 8 Jun 2026 14:39:27 -0400 Subject: [PATCH] Limit platform details to a reasonable length (#2088) Now that #2083 limits value sizes for properties inside of WireFormatInfo we should add a check to make sure platform details do not go past that limit. Limit has been set to 512 bytes as that should be more than enough as the details are usually less than half that. This is not turned of by default but if someone is using it this will prevent potential future problems for too large a value. (cherry picked from commit 60af38679254749195e403df6bad7d7504f0d193) --- .../activemq/ActiveMQConnectionMetaData.java | 18 ++++++-- .../activemq/command/WireFormatInfo.java | 2 +- .../ActiveMQConnectionMetaDataTest.java | 46 +++++++++++++++++++ 3 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 activemq-client/src/test/java/org/apache/activemq/ActiveMQConnectionMetaDataTest.java diff --git a/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionMetaData.java b/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionMetaData.java index 1f0f7655c36..9ade707a5f2 100644 --- a/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionMetaData.java +++ b/activemq-client/src/main/java/org/apache/activemq/ActiveMQConnectionMetaData.java @@ -22,6 +22,7 @@ import java.util.regex.Pattern; import javax.jms.ConnectionMetaData; +import org.apache.activemq.command.WireFormatInfo; /** * A ConnectionMetaData object provides information describing @@ -35,6 +36,10 @@ public final class ActiveMQConnectionMetaData implements ConnectionMetaData { public static final String PROVIDER_NAME = "ActiveMQ"; public static final String DEFAULT_PLATFORM_DETAILS = "Java"; public static final String PLATFORM_DETAILS; + // Set the max length to WireFormatInfo.MAX_PROPERTY_BUFFER_SIZE (512 bytes) + // Now that we limit property value buffer sizes inside WireFormatInfo we need to + // limit the value from being larger than this, or we would get an exception. + public static final int PLATFORM_DETAILS_MAX_LENGTH = WireFormatInfo.MAX_PROPERTY_BUFFER_SIZE; public static final ActiveMQConnectionMetaData INSTANCE = new ActiveMQConnectionMetaData(); @@ -157,10 +162,11 @@ public Enumeration getJMSXPropertyNames() { * * @return String containing the platform details */ - private static String getPlatformDetails() { - String details = "java"; + // Package scope for testing purposes + static String getPlatformDetails() { + String details = DEFAULT_PLATFORM_DETAILS; try { - StringBuilder platformInfo = new StringBuilder(128); + final StringBuilder platformInfo = new StringBuilder(128); platformInfo.append("JVM: "); platformInfo.append(System.getProperty("java.version")); @@ -175,8 +181,10 @@ private static String getPlatformDetails() { platformInfo.append(", "); platformInfo.append(System.getProperty("os.arch")); - details = platformInfo.toString(); - } catch (Throwable e) { + // truncate to the max allowed length if too long + details = platformInfo.length() > PLATFORM_DETAILS_MAX_LENGTH ? + platformInfo.substring(0, PLATFORM_DETAILS_MAX_LENGTH) : platformInfo.toString(); + } catch (Throwable ignored) { } return details; } diff --git a/activemq-client/src/main/java/org/apache/activemq/command/WireFormatInfo.java b/activemq-client/src/main/java/org/apache/activemq/command/WireFormatInfo.java index 79a742e7e34..b415a33958a 100644 --- a/activemq-client/src/main/java/org/apache/activemq/command/WireFormatInfo.java +++ b/activemq-client/src/main/java/org/apache/activemq/command/WireFormatInfo.java @@ -42,7 +42,7 @@ public class WireFormatInfo implements Command, MarshallAware { // Max number of properties allowed in the map is 64 static final int MAX_PROPERTY_SIZE = 64; // Used to validate property values that allocate buffers, limit to 512 bytes - static final int MAX_PROPERTY_BUFFER_SIZE = 512; + public static final int MAX_PROPERTY_BUFFER_SIZE = 512; // Do not allow any nested collections in properties static final int MAX_PROPERTY_DEPTH = 0; private static final byte[] MAGIC = new byte[] {'A', 'c', 't', 'i', 'v', 'e', 'M', 'Q'}; diff --git a/activemq-client/src/test/java/org/apache/activemq/ActiveMQConnectionMetaDataTest.java b/activemq-client/src/test/java/org/apache/activemq/ActiveMQConnectionMetaDataTest.java new file mode 100644 index 00000000000..e4162b3ae00 --- /dev/null +++ b/activemq-client/src/test/java/org/apache/activemq/ActiveMQConnectionMetaDataTest.java @@ -0,0 +1,46 @@ +/* + * 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; + +import static org.apache.activemq.ActiveMQConnectionMetaData.PLATFORM_DETAILS_MAX_LENGTH; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class ActiveMQConnectionMetaDataTest { + + @Test + public void testPlatformDetails() { + // static final should match generated from the utility method + assertEquals(ActiveMQConnectionMetaData.PLATFORM_DETAILS, + ActiveMQConnectionMetaData.getPlatformDetails()); + } + + @Test + public void testPlatformDetailsTruncation() { + String javaVendor = System.getProperty("java.vendor"); + try { + System.setProperty("java.vendor", "a".repeat(PLATFORM_DETAILS_MAX_LENGTH + 1)); + // ensure we truncate if too large + assertEquals(PLATFORM_DETAILS_MAX_LENGTH, + ActiveMQConnectionMetaData.getPlatformDetails().length()); + } finally { + // restore original + System.setProperty("java.vendor", javaVendor); + } + } +}