From acfa734cf87036d903ce5352bc44a9b3426a00c4 Mon Sep 17 00:00:00 2001 From: Christopher Hermann Date: Tue, 7 Jan 2025 10:45:10 +0100 Subject: [PATCH] Display.withCrLf() is producing wrong line breaks on Windows Replacing all line breaks on windows with CrLf using regex, which is much safer. Fixes #1557 --- .../org/eclipse/swt/widgets/Display.java | 79 ++----------------- .../Test_org_eclipse_swt_widgets_Display.java | 11 +++ 2 files changed, 16 insertions(+), 74 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java index 100b47e6daf..7a8d39b7f56 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java @@ -5152,85 +5152,16 @@ String wrapText (String text, long handle, int width) { } static String withCrLf (String string) { - - /* If the string is empty, return the string. */ - int length = string.length (); - if (length == 0) return string; - - /* - * Check for an LF or CR/LF and assume the rest of - * the string is formated that way. This will not - * work if the string contains mixed delimiters. - */ - int i = string.indexOf ('\n', 0); - if (i == -1) return string; - if (i > 0 && string.charAt (i - 1) == '\r') { + if (string == null) { return string; } - - /* - * The string is formatted with LF. Compute the - * number of lines and the size of the buffer - * needed to hold the result - */ - i++; - int count = 1; - while (i < length) { - if ((i = string.indexOf ('\n', i)) == -1) break; - count++; i++; - } - count += length; - - /* Create a new string with the CR/LF line terminator. */ - i = 0; - StringBuilder result = new StringBuilder (count); - while (i < length) { - int j = string.indexOf ('\n', i); - if (j == -1) j = length; - result.append (string.substring (i, j)); - if ((i = j) < length) { - result.append ("\r\n"); //$NON-NLS-1$ - i++; - } - } - return result.toString (); + // Replace \r\n, \r, or \n with \r\n return input.replaceAll("(\r\n|\r|\n)", "\r\n"); + return string.replaceAll("(\r\n|\r|\n)", "\r\n"); } static char [] withCrLf (char [] string) { - /* If the string is empty, return the string. */ - int length = string.length; - if (length == 0) return string; - - /* - * Check for an LF or CR/LF and assume the rest of - * the string is formated that way. This will not - * work if the string contains mixed delimiters. - * Also, compute the number of lines. - */ - int count = 0; - for (int i = 0; i < string.length; i++) { - if (string [i] == '\n') { - count++; - if (count == 1 && i > 0 && string [i - 1] == '\r') return string; - } - } - if (count == 0) return string; - - /* - * The string is formatted with LF. - */ - count += length; - - /* Create a new string with the CR/LF line terminator. */ - char [] result = new char [count]; - for (int i = 0, j = 0; i < length && j < count; i++) { - if (string [i] == '\n') { - result [j++] = '\r'; - } - result [j++] = string [i]; - } - - return result; + String withCrLf = withCrLf(new String(string)); + return withCrLf.toCharArray(); } static boolean isActivateShellOnForceFocus() { diff --git a/tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/widgets/Test_org_eclipse_swt_widgets_Display.java b/tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/widgets/Test_org_eclipse_swt_widgets_Display.java index 316fec13d82..2f17f5aed2c 100644 --- a/tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/widgets/Test_org_eclipse_swt_widgets_Display.java +++ b/tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/widgets/Test_org_eclipse_swt_widgets_Display.java @@ -13,6 +13,8 @@ *******************************************************************************/ package org.eclipse.swt.tests.win32.widgets; +import static org.junit.Assert.assertEquals; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -35,4 +37,13 @@ public void test_isXMouseActive() throws NoSuchMethodException, SecurityExceptio display.dispose(); } } + + @Test + public void test_mixedLfAndCrfl() { + String actString = Display.withCrLf("First Line \n second line \r\n third line"); + assertEquals("First Line \r\n second line \r\n third line", actString); + + char[] actCharArray = Display.withCrLf("First Line \n second line \r\n third line".toCharArray()); + assertEquals("First Line \r\n second line \r\n third line", new String(actCharArray)); + } }