Skip to content

Commit 5f5b054

Browse files
authored
Handle null input in StringEncoder (#8312)
1 parent 984fd4f commit 5f5b054

4 files changed

Lines changed: 25 additions & 9 deletions

File tree

exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/AbstractStringEncoder.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.exporter.internal.marshal;
77

88
import java.io.IOException;
9+
import javax.annotation.Nullable;
910

1011
/**
1112
* This class contains shared logic for UTF-8 encoding operations while allowing subclasses to
@@ -20,8 +21,11 @@ abstract class AbstractStringEncoder implements StringEncoder {
2021
private final FallbackStringEncoder fallback = new FallbackStringEncoder();
2122

2223
@Override
23-
public final void writeUtf8(CodedOutputStream output, String string, int utf8Length)
24+
public final void writeUtf8(CodedOutputStream output, @Nullable String string, int utf8Length)
2425
throws IOException {
26+
if (string == null) {
27+
return;
28+
}
2529
// if the length of the latin1 string and the utf8 output are the same then the string must be
2630
// composed of only 7bit characters and can be directly copied to the output
2731
if (string.length() == utf8Length && isLatin1(string)) {
@@ -33,8 +37,10 @@ public final void writeUtf8(CodedOutputStream output, String string, int utf8Len
3337
}
3438

3539
@Override
36-
public final int getUtf8Size(String string) {
37-
if (isLatin1(string)) {
40+
public final int getUtf8Size(@Nullable String string) {
41+
if (string == null) {
42+
return 0;
43+
} else if (isLatin1(string)) {
3844
byte[] bytes = getStringBytes(string);
3945
// latin1 bytes with negative value (most significant bit set) are encoded as 2 bytes in utf8
4046
return string.length() + countNegative(bytes);

exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/FallbackStringEncoder.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.exporter.internal.marshal;
77

88
import java.io.IOException;
9+
import javax.annotation.Nullable;
910

1011
/**
1112
* Fallback StringEncoder implementation using standard Java string operations.
@@ -20,14 +21,16 @@ final class FallbackStringEncoder implements StringEncoder {
2021
FallbackStringEncoder() {}
2122

2223
@Override
23-
public int getUtf8Size(String string) {
24-
return encodedUtf8Length(string);
24+
public int getUtf8Size(@Nullable String string) {
25+
return string != null ? encodedUtf8Length(string) : 0;
2526
}
2627

2728
@Override
28-
public void writeUtf8(CodedOutputStream output, String string, int utf8Length)
29+
public void writeUtf8(CodedOutputStream output, @Nullable String string, int utf8Length)
2930
throws IOException {
30-
encodeUtf8(output, string);
31+
if (string != null) {
32+
encodeUtf8(output, string);
33+
}
3134
}
3235

3336
// adapted from

exporters/common/src/main/java/io/opentelemetry/exporter/internal/marshal/StringEncoder.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.exporter.internal.marshal;
77

88
import java.io.IOException;
9+
import javax.annotation.Nullable;
910

1011
/**
1112
* Interface for efficient UTF-8 string encoding operations.
@@ -29,13 +30,14 @@
2930
public interface StringEncoder {
3031

3132
/** Returns the number of bytes required to encode the string as UTF-8. */
32-
int getUtf8Size(String string);
33+
int getUtf8Size(@Nullable String string);
3334

3435
/**
3536
* Write a string as UTF-8 bytes to the output stream using the pre-calculated UTF-8 length from
3637
* {@link #getUtf8Size(String)}.
3738
*/
38-
void writeUtf8(CodedOutputStream output, String string, int utf8Length) throws IOException;
39+
void writeUtf8(CodedOutputStream output, @Nullable String string, int utf8Length)
40+
throws IOException;
3941

4042
/** Returns the best available StringEncoder implementation. */
4143
static StringEncoder getInstance() {

exporters/common/src/test/java/io/opentelemetry/exporter/internal/marshal/StringEncoderTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ void testUtf8SizeLatin1_VarHandle() {
6161
private static void testUtf8Encoding(StringEncoder stringEncoder) {
6262
assertThat(stringEncoder).isNotNull();
6363

64+
assertThat(stringEncoder.getUtf8Size(null)).isEqualTo(0);
65+
assertThat(testUtf8(null, 0, stringEncoder)).isEqualTo("");
66+
6467
assertThat(stringEncoder.getUtf8Size("")).isEqualTo(0);
6568
assertThat(testUtf8("", 0, stringEncoder)).isEqualTo("");
6669

@@ -87,6 +90,8 @@ private static void testUtf8Encoding(StringEncoder stringEncoder) {
8790
}
8891

8992
private static void testUtf8SizeLatin1(StringEncoder stringEncoder) {
93+
assertThat(stringEncoder.getUtf8Size(null)).isEqualTo(0);
94+
9095
// Run repeated test logic for each encoder
9196
Random random = new Random();
9297
for (int i = 0; i < 1000; i++) {

0 commit comments

Comments
 (0)