diff --git a/src/main/java/com/google/devtools/build/lib/events/BUILD b/src/main/java/com/google/devtools/build/lib/events/BUILD index 217315d8da8ea4..8ee748003258c9 100644 --- a/src/main/java/com/google/devtools/build/lib/events/BUILD +++ b/src/main/java/com/google/devtools/build/lib/events/BUILD @@ -18,6 +18,7 @@ java_library( exclude = ["EventBusEventHandler.java"], ), deps = [ + "//src/main/java/com/google/devtools/build/lib/unsafe:string", "//src/main/java/com/google/devtools/build/lib/util:string_encoding", "//src/main/java/com/google/devtools/build/lib/util/io:out-err", "//src/main/java/net/starlark/java/eval", diff --git a/src/main/java/com/google/devtools/build/lib/events/Event.java b/src/main/java/com/google/devtools/build/lib/events/Event.java index ded7ba6a50ccc3..86b326f4369132 100644 --- a/src/main/java/com/google/devtools/build/lib/events/Event.java +++ b/src/main/java/com/google/devtools/build/lib/events/Event.java @@ -15,10 +15,10 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Comparator.comparing; import com.google.common.collect.ImmutableClassToInstanceMap; +import com.google.devtools.build.lib.unsafe.StringUnsafe; import com.google.errorprone.annotations.CheckReturnValue; import java.io.IOException; import java.util.Arrays; @@ -84,16 +84,21 @@ public EventKind getKind() { } public String getMessage() { - return message instanceof String ? (String) message : new String((byte[]) message, UTF_8); + return message instanceof String + ? (String) message + : StringUnsafe.newInstance((byte[]) message, StringUnsafe.LATIN1); } /** - * Returns this event's message as a {@link byte[]}. If this event was instantiated using a {@link - * String}, the returned byte array is encoded using {@link - * java.nio.charset.StandardCharsets#UTF_8}. + * Returns this event's message as a {@link byte[]} by unwrapping Bazel's {@link + * com.google.devtools.build.lib.util.StringEncoding internal string encoding}. + * + *
Caller's must not modify the returned array. */ public byte[] getMessageBytes() { - return message instanceof byte[] ? (byte[]) message : ((String) message).getBytes(UTF_8); + return message instanceof byte[] + ? (byte[]) message + : StringUnsafe.getInternalStringBytes((String) message); } /** Returns the property value associated with {@code type} if any, and {@code null} otherwise. */ diff --git a/src/main/java/com/google/devtools/build/lib/events/PrintingEventHandler.java b/src/main/java/com/google/devtools/build/lib/events/PrintingEventHandler.java index 93a8908cb7f914..2288971b86ba6e 100644 --- a/src/main/java/com/google/devtools/build/lib/events/PrintingEventHandler.java +++ b/src/main/java/com/google/devtools/build/lib/events/PrintingEventHandler.java @@ -13,6 +13,7 @@ // limitations under the License. package com.google.devtools.build.lib.events; +import com.google.devtools.build.lib.unsafe.StringUnsafe; import com.google.devtools.build.lib.util.io.OutErr; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -102,7 +103,7 @@ public void handle(Event event) { builder.append(event.getLocation()).append(": "); } builder.append(event.getMessage()).append("\n"); - outErr.getErrorStream().write(builder.toString().getBytes(StandardCharsets.UTF_8)); + outErr.getErrorStream().write(StringUnsafe.getInternalStringBytes(builder.toString())); outErr.getErrorStream().flush(); } } diff --git a/src/main/java/com/google/devtools/build/lib/util/io/AnsiTerminal.java b/src/main/java/com/google/devtools/build/lib/util/io/AnsiTerminal.java index 743157d47c03dc..a70d0a081df5c4 100644 --- a/src/main/java/com/google/devtools/build/lib/util/io/AnsiTerminal.java +++ b/src/main/java/com/google/devtools/build/lib/util/io/AnsiTerminal.java @@ -15,6 +15,7 @@ import static java.nio.charset.StandardCharsets.US_ASCII; +import com.google.devtools.build.lib.unsafe.StringUnsafe; import java.io.IOException; import java.io.OutputStream; @@ -139,9 +140,8 @@ public void textMagenta() throws IOException { } /** Set the terminal title. */ - @SuppressWarnings("DefaultCharset") public void setTitle(String title) throws IOException { - writeBytes(osc, setTermTitle, title.getBytes(), st); + writeBytes(osc, setTermTitle, StringUnsafe.getInternalStringBytes(title), st); } /** @@ -149,9 +149,8 @@ public void setTitle(String title) throws IOException { * * @param text the text to write */ - @SuppressWarnings("DefaultCharset") public void writeString(String text) throws IOException { - out.write(text.getBytes()); + out.write(StringUnsafe.getInternalStringBytes(text)); } /** diff --git a/src/main/java/com/google/devtools/build/lib/util/io/BUILD b/src/main/java/com/google/devtools/build/lib/util/io/BUILD index 9e366a2426b20b..f21afd1a773f25 100644 --- a/src/main/java/com/google/devtools/build/lib/util/io/BUILD +++ b/src/main/java/com/google/devtools/build/lib/util/io/BUILD @@ -73,6 +73,7 @@ java_library( srcs = OUT_ERR_SRCS, deps = [ "//src/main/java/com/google/devtools/build/lib/concurrent:thread_safety", + "//src/main/java/com/google/devtools/build/lib/unsafe:string", "//third_party:flogger", "//third_party:guava", ], diff --git a/src/test/java/com/google/devtools/build/lib/events/BUILD b/src/test/java/com/google/devtools/build/lib/events/BUILD index 801edf02ffd21d..ed10c4cb494d8c 100644 --- a/src/test/java/com/google/devtools/build/lib/events/BUILD +++ b/src/test/java/com/google/devtools/build/lib/events/BUILD @@ -19,6 +19,8 @@ java_library( deps = [ "//src/main/java/com/google/devtools/build/lib/events", "//src/main/java/com/google/devtools/build/lib/events:event_bus_event_handler", + "//src/main/java/com/google/devtools/build/lib/unsafe:string", + "//src/main/java/com/google/devtools/build/lib/util:string_encoding", "//src/main/java/com/google/devtools/build/lib/util/io:out-err", "//src/main/java/net/starlark/java/eval", "//src/main/java/net/starlark/java/syntax", diff --git a/src/test/java/com/google/devtools/build/lib/events/EventTest.java b/src/test/java/com/google/devtools/build/lib/events/EventTest.java index c402ce97047aac..c481ce8d25a40d 100644 --- a/src/test/java/com/google/devtools/build/lib/events/EventTest.java +++ b/src/test/java/com/google/devtools/build/lib/events/EventTest.java @@ -14,7 +14,8 @@ package com.google.devtools.build.lib.events; import static com.google.common.truth.Truth.assertThat; -import static java.nio.charset.StandardCharsets.UTF_8; +import static java.nio.charset.StandardCharsets.ISO_8859_1; +import static java.nio.charset.StandardCharsets.US_ASCII; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -22,6 +23,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.testing.EqualsTester; import com.google.devtools.build.lib.events.Event.ProcessOutput; +import com.google.devtools.build.lib.unsafe.StringUnsafe; +import com.google.devtools.build.lib.util.StringEncoding; import net.starlark.java.eval.Mutability; import net.starlark.java.eval.StarlarkSemantics; import net.starlark.java.eval.StarlarkThread; @@ -47,22 +50,17 @@ public void eventKindMessage() { @Test public void eventMessageEncoding() { - String message = "Bazel \u1f33f"; + String message = StringEncoding.unicodeToInternal("Bazel ἳf"); Event stringEvent = Event.of(EventKind.WARNING, message); - Event stringEvent2 = Event.of(EventKind.WARNING, "Bazel \u1f33f"); assertThat(stringEvent.getMessage()).isEqualTo(message); - assertThat(stringEvent.getMessageBytes()).isEqualTo(message.getBytes(UTF_8)); + assertThat(stringEvent.getMessageBytes()).isEqualTo(message.getBytes(ISO_8859_1)); - Event byteArrayEvent = Event.of(EventKind.WARNING, message.getBytes(UTF_8)); - Event byteArrayEvent2 = Event.of(EventKind.WARNING, "Bazel \u1f33f".getBytes(UTF_8)); + Event byteArrayEvent = Event.of(EventKind.WARNING, StringUnsafe.getByteArray(message)); assertThat(byteArrayEvent.getMessage()).isEqualTo(message); - assertThat(byteArrayEvent.getMessageBytes()).isEqualTo(message.getBytes(UTF_8)); + assertThat(byteArrayEvent.getMessageBytes()).isEqualTo(message.getBytes(ISO_8859_1)); - new EqualsTester() - .addEqualityGroup(stringEvent, stringEvent2) - .addEqualityGroup(byteArrayEvent, byteArrayEvent2) - .testEquals(); + assertThat(stringEvent).isNotEqualTo(byteArrayEvent); } @Test @@ -77,7 +75,7 @@ public void eventLocationSensitiveToString() { @Test public void messageReference() throws Exception { - byte[] messageBytes = "message".getBytes(UTF_8); + byte[] messageBytes = "message".getBytes(US_ASCII); Event event = Event.of(EventKind.WARNING, messageBytes); assertThat(event.getMessageBytes()).isEqualTo(messageBytes); } @@ -182,9 +180,9 @@ public void tagIsSameAsStringProperty() { @Test public void testWithProcessOutput() throws Exception { String stdoutPath = "/stdout"; - byte[] stdout = "some stdout output".getBytes(UTF_8); + byte[] stdout = "some stdout output".getBytes(US_ASCII); String stderrPath = "/stderr"; - byte[] stderr = "some stderr error".getBytes(UTF_8); + byte[] stderr = "some stderr error".getBytes(US_ASCII); ProcessOutput testProcessOutput = new ProcessOutput() {