From d3d2b16a446507ea15eabebe91c419615f224a48 Mon Sep 17 00:00:00 2001 From: Francisco Prieto Date: Fri, 15 Aug 2025 01:02:54 -0300 Subject: [PATCH] Fix TraceState key validation limits to match W3C spec --- .../trace/ArrayBasedTraceStateBuilder.java | 8 +++--- .../api/trace/TraceStateTest.java | 27 +++++++++++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/ArrayBasedTraceStateBuilder.java b/api/all/src/main/java/io/opentelemetry/api/trace/ArrayBasedTraceStateBuilder.java index 4b8836fe10c..09c3d1e0303 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/ArrayBasedTraceStateBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/ArrayBasedTraceStateBuilder.java @@ -14,7 +14,7 @@ final class ArrayBasedTraceStateBuilder implements TraceStateBuilder { - private static final int MAX_VENDOR_ID_SIZE = 13; + private static final int MAX_VENDOR_ID_SIZE = 14; // Needs to be in this class to avoid initialization deadlock because super class depends on // subclass (the auto-value generate class). @@ -24,7 +24,7 @@ final class ArrayBasedTraceStateBuilder implements TraceStateBuilder { private static final int MAX_ENTRIES = 32; private static final int KEY_MAX_SIZE = 256; private static final int VALUE_MAX_SIZE = 256; - private static final int MAX_TENANT_ID_SIZE = 240; + private static final int MAX_TENANT_ID_SIZE = 241; // Later calls to put must be at the front of trace state. We append to the list and then reverse // when finished. @@ -157,11 +157,11 @@ private static boolean isKeyValid(@Nullable String key) { return false; } isMultiTenantVendorKey = true; - // tenant id (the part to the left of the '@' sign) must be 240 characters or less + // tenant id (the part to the left of the '@' sign) must be 241 characters or less if (i > MAX_TENANT_ID_SIZE) { return false; } - // vendor id (the part to the right of the '@' sign) must be 1-13 characters long + // vendor id (the part to the right of the '@' sign) must be 1-14 characters long int remainingKeyChars = key.length() - i - 1; if (remainingKeyChars > MAX_VENDOR_ID_SIZE || remainingKeyChars == 0) { return false; diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/TraceStateTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/TraceStateTest.java index d4d8f0fda3f..22a04b4176b 100644 --- a/api/all/src/test/java/io/opentelemetry/api/trace/TraceStateTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/trace/TraceStateTest.java @@ -123,22 +123,39 @@ void testValidAtSignVendorNamePrefix() { } @Test - void testVendorIdLongerThan13Characters() { - assertThat(TraceState.builder().put("1@nrabcdefghijkl", FIRST_VALUE).build()) + void testVendorIdWith14Characters() { + String key = "1@nrabcdefghijkl"; + assertThat(TraceState.builder().put(key, FIRST_VALUE).build().get(key)).isEqualTo(FIRST_VALUE); + } + + @Test + void testVendorIdLongerThan14Characters() { + assertThat(TraceState.builder().put("1@nrabcdefghijklm", FIRST_VALUE).build()) .isEqualTo(TraceState.getDefault()); } @Test - void testVendorIdLongerThan13Characters_longTenantId() { - assertThat(TraceState.builder().put("12345678901234567890@nrabcdefghijkl", FIRST_VALUE).build()) + void testVendorIdLongerThan14Characters_longTenantId() { + assertThat( + TraceState.builder().put("12345678901234567890@nrabcdefghijklm", FIRST_VALUE).build()) .isEqualTo(TraceState.getDefault()); } @Test - void tenantIdLongerThan240Characters() { + void tenantIdWith241Characters() { char[] chars = new char[241]; Arrays.fill(chars, 'a'); String tenantId = new String(chars); + assertThat( + TraceState.builder().put(tenantId + "@nr", FIRST_VALUE).build().get(tenantId + "@nr")) + .isEqualTo(FIRST_VALUE); + } + + @Test + void tenantIdLongerThan241Characters() { + char[] chars = new char[242]; + Arrays.fill(chars, 'a'); + String tenantId = new String(chars); assertThat(TraceState.builder().put(tenantId + "@nr", FIRST_VALUE).build()) .isEqualTo(TraceState.getDefault()); }