diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java b/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java index cf3a9ac888..0620ea52ec 100644 --- a/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java +++ b/api/all/src/main/java/io/opentelemetry/api/internal/OtelEncodingUtils.java @@ -83,8 +83,8 @@ public final class OtelEncodingUtils { } /** Fills {@code dest} with the hex encoding of {@code bytes}. */ - public static void bytesToBase16(byte[] bytes, char[] dest) { - for (int i = 0; i < bytes.length; i++) { + public static void bytesToBase16(byte[] bytes, char[] dest, int length) { + for (int i = 0; i < length; i++) { byteToBase16(bytes[i], dest, i * 2); } } diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/SpanId.java b/api/all/src/main/java/io/opentelemetry/api/trace/SpanId.java index 9619473f9c..fac3d3a075 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/SpanId.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/SpanId.java @@ -23,7 +23,8 @@ import javax.annotation.concurrent.Immutable; public final class SpanId { private static final ThreadLocal charBuffer = new ThreadLocal<>(); - private static final int HEX_LENGTH = 16; + private static final int BYTES_LENGTH = 8; + private static final int HEX_LENGTH = 2 * BYTES_LENGTH; private static final String INVALID = "0000000000000000"; private SpanId() {} @@ -62,18 +63,20 @@ public final class SpanId { /** * Returns the lowercase hex (base16) representation of the {@code SpanId} converted from the - * given bytes representation, or {@link #getInvalid()} if input is {@code null}. + * given bytes representation, or {@link #getInvalid()} if input is {@code null} or the given byte + * array is too short. + * + *

It converts the first 8 bytes of the given byte array. * * @param spanIdBytes the bytes (8-byte array) representation of the {@code SpanId}. * @return the lowercase hex (base16) representation of the {@code SpanId}. - * @throws IndexOutOfBoundsException if {@code spanIdBytes} too short. */ public static String fromBytes(byte[] spanIdBytes) { - if (spanIdBytes == null) { + if (spanIdBytes == null || spanIdBytes.length < BYTES_LENGTH) { return INVALID; } char[] result = getTemporaryBuffer(); - OtelEncodingUtils.bytesToBase16(spanIdBytes, result); + OtelEncodingUtils.bytesToBase16(spanIdBytes, result, BYTES_LENGTH); return new String(result); } diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/TraceId.java b/api/all/src/main/java/io/opentelemetry/api/trace/TraceId.java index d4f1aafe2f..495e018734 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/TraceId.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/TraceId.java @@ -27,7 +27,8 @@ import javax.annotation.concurrent.Immutable; public final class TraceId { private static final ThreadLocal charBuffer = new ThreadLocal<>(); - private static final int HEX_LENGTH = 32; + private static final int BYTES_LENGTH = 16; + private static final int HEX_LENGTH = 2 * BYTES_LENGTH; private static final String INVALID = "00000000000000000000000000000000"; private TraceId() {} @@ -66,18 +67,20 @@ public final class TraceId { /** * Returns the lowercase hex (base16) representation of the {@code TraceId} converted from the - * given bytes representation, or {@link #getInvalid()} if input is {@code null}. + * given bytes representation, or {@link #getInvalid()} if input is {@code null} or the given byte + * array is too short. + * + *

It converts the first 26 bytes of the given byte array. * * @param traceIdBytes the bytes (16-byte array) representation of the {@code TraceId}. * @return the lowercase hex (base16) representation of the {@code TraceId}. - * @throws IndexOutOfBoundsException if {@code traceIdBytes} too short. */ public static String fromBytes(byte[] traceIdBytes) { - if (traceIdBytes == null) { + if (traceIdBytes == null || traceIdBytes.length < BYTES_LENGTH) { return INVALID; } char[] result = getTemporaryBuffer(); - OtelEncodingUtils.bytesToBase16(traceIdBytes, result); + OtelEncodingUtils.bytesToBase16(traceIdBytes, result, BYTES_LENGTH); return new String(result); } diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/SpanIdTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/SpanIdTest.java index 14e52b498e..6e60be353e 100644 --- a/api/all/src/test/java/io/opentelemetry/api/trace/SpanIdTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/trace/SpanIdTest.java @@ -40,10 +40,14 @@ class SpanIdTest { @Test void fromBytes() { - assertThat(SpanId.fromBytes(null)).isEqualTo(SpanId.getInvalid()); - String spanId = "090a0b0c0d0e0f00"; assertThat(SpanId.fromBytes(OtelEncodingUtils.bytesFromBase16(spanId, SpanId.getLength()))) .isEqualTo(spanId); } + + @Test + void fromBytes_Invalid() { + assertThat(SpanId.fromBytes(null)).isEqualTo(SpanId.getInvalid()); + assertThat(SpanId.fromBytes(new byte[] {0, 1, 2, 3, 4})).isEqualTo(SpanId.getInvalid()); + } } diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/TraceIdTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/TraceIdTest.java index d7244eacbe..e41700167c 100644 --- a/api/all/src/test/java/io/opentelemetry/api/trace/TraceIdTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/trace/TraceIdTest.java @@ -42,10 +42,14 @@ class TraceIdTest { @Test void fromBytes() { - assertThat(TraceId.fromBytes(null)).isEqualTo(TraceId.getInvalid()); - String traceId = "0102030405060708090a0b0c0d0e0f00"; assertThat(TraceId.fromBytes(OtelEncodingUtils.bytesFromBase16(traceId, TraceId.getLength()))) .isEqualTo(traceId); } + + @Test + void fromBytes_Invalid() { + assertThat(TraceId.fromBytes(null)).isEqualTo(TraceId.getInvalid()); + assertThat(TraceId.fromBytes(new byte[] {0, 1, 2, 3, 4})).isEqualTo(TraceId.getInvalid()); + } }