From b5c0c6e104c626fbfb6276b01bf0882603fb5d09 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Mon, 2 Jun 2025 08:58:43 +0100 Subject: [PATCH] Fix out-of-bounds when pasting too-long text Used a `<=` instead of a `<`! How did I mess this up!? Fixes #2209 --- .../client/gui/KeyConverter.java | 3 +- .../computercraft/core/util/StringUtil.java | 2 +- .../core/util/StringUtilTest.java | 36 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 projects/core/src/test/java/dan200/computercraft/core/util/StringUtilTest.java diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java b/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java index 99ee64077..f99a254bf 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/KeyConverter.java @@ -26,7 +26,8 @@ public class KeyConverter { var name = GLFW.glfwGetKeyName(key, scanCode); if (name == null || name.length() != 1) return key; - // If we've got a single character key name, try to translate it to a + // If we've got a single character as the key name, treat that as the ASCII value of the key, + // and map that back to a key code. var character = name.charAt(0); // 0-9 and A-Z map directly to their GLFW key (they're the same ASCII code). diff --git a/projects/core/src/main/java/dan200/computercraft/core/util/StringUtil.java b/projects/core/src/main/java/dan200/computercraft/core/util/StringUtil.java index 234127244..2916929f1 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/util/StringUtil.java +++ b/projects/core/src/main/java/dan200/computercraft/core/util/StringUtil.java @@ -120,7 +120,7 @@ public final class StringUtil { var idx = 0; var iterator = clipboard.codePoints().iterator(); - while (iterator.hasNext() && idx <= output.length) { + while (iterator.hasNext() && idx < output.length) { var chr = unicodeToTerminal(iterator.next()); if (chr < 0) continue; // Strip out unconvertible characters if (!isTypableChar(chr)) break; // Stop at untypable ones. diff --git a/projects/core/src/test/java/dan200/computercraft/core/util/StringUtilTest.java b/projects/core/src/test/java/dan200/computercraft/core/util/StringUtilTest.java new file mode 100644 index 000000000..69e9d3c07 --- /dev/null +++ b/projects/core/src/test/java/dan200/computercraft/core/util/StringUtilTest.java @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.core.util; + +import dan200.computercraft.api.lua.LuaValues; +import dan200.computercraft.test.core.ReplaceUnderscoresDisplayNameGenerator; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DisplayNameGeneration(ReplaceUnderscoresDisplayNameGenerator.class) +class StringUtilTest { + @ParameterizedTest + @ValueSource(strings = { "hello\nworld", "hello\n\rworld", "hello\rworld" }) + public void getClipboardString_returns_a_single_line(String input) { + var result = StringUtil.getClipboardString(input); + assertEquals(LuaValues.encode("hello"), result); + } + + @Test + public void getClipboardString_limits_length() { + var input = "abcdefghijklmnop".repeat(50); + var result = StringUtil.getClipboardString(input); + assertEquals(StringUtil.MAX_PASTE_LENGTH, result.limit()); + + assertEquals( + LuaValues.encode(input.substring(0, StringUtil.MAX_PASTE_LENGTH)), + result + ); + } +}