This is an automated email from the ASF dual-hosted git repository.

mbien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 9fe8eeec24 #4818: Update string renderer to only escape undisplayable 
code points.
     new c35fe3c9a7 Merge pull request #5757 from 
rkeen-siemens/rk/4818/escape-only-undisplayable-codepoints
9fe8eeec24 is described below

commit 9fe8eeec2411c0a0aa442c2f4a2a8da86ab03a72
Author: Rangi Keen <[email protected]>
AuthorDate: Mon Apr 3 12:20:38 2023 -0400

    #4818: Update string renderer to only escape undisplayable code points.
---
 .../explorer/propertysheet/RendererFactory.java    |  28 +++--
 .../explorer/propertysheet/StringRendererTest.java | 139 +++++++++++++++++++++
 2 files changed, 154 insertions(+), 13 deletions(-)

diff --git 
a/platform/openide.explorer/src/org/openide/explorer/propertysheet/RendererFactory.java
 
b/platform/openide.explorer/src/org/openide/explorer/propertysheet/RendererFactory.java
index 4484ce07f5..60db44922a 100644
--- 
a/platform/openide.explorer/src/org/openide/explorer/propertysheet/RendererFactory.java
+++ 
b/platform/openide.explorer/src/org/openide/explorer/propertysheet/RendererFactory.java
@@ -481,13 +481,12 @@ final class RendererFactory {
             f = new JLabel().getFont();
         }
 
-        StringBuffer buf = new StringBuffer(str.length() * 6); // x -> \u1234
-        char[] chars = str.toCharArray();
+        StringBuilder buf = new StringBuilder(str.length() * 6); // x -> \u1234
+        final int length = str.length();
+        for (int offset = 0; offset < length; ) {
+            final int cp = str.codePointAt(offset);
 
-        for (int i = 0; i < chars.length; i++) {
-            char c = chars[i];
-
-            switch (c) {
+            switch (cp) {
             // label doesn't interpret tab correctly
             case '\t':
                 buf.append("        "); // NOI18N
@@ -511,19 +510,22 @@ final class RendererFactory {
 
             default:
 
-                if ((null == f) || f.canDisplay(c)) {
-                    buf.append(c);
+                if ((null == f) || f.canDisplay(cp)) {
+                    buf.appendCodePoint(cp);
                 } else {
-                    buf.append("\\u"); // NOI18N
+                    for (char c : Character.toChars(cp)) {
+                        buf.append("\\u"); // NOI18N
 
-                    String hex = Integer.toHexString(c);
+                        String hex = Integer.toHexString(c);
 
-                    for (int j = 0; j < (4 - hex.length()); j++)
-                        buf.append('0');
+                        for (int j = 0; j < (4 - hex.length()); j++)
+                            buf.append('0');
 
-                    buf.append(hex);
+                        buf.append(hex);
+                    }
                 }
             }
+            offset += Character.charCount(cp);
         }
 
         return buf.toString();
diff --git 
a/platform/openide.explorer/test/unit/src/org/openide/explorer/propertysheet/StringRendererTest.java
 
b/platform/openide.explorer/test/unit/src/org/openide/explorer/propertysheet/StringRendererTest.java
new file mode 100644
index 0000000000..08cf2e2e87
--- /dev/null
+++ 
b/platform/openide.explorer/test/unit/src/org/openide/explorer/propertysheet/StringRendererTest.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.openide.explorer.propertysheet;
+
+import static java.util.stream.Collectors.joining;
+
+import java.awt.Font;
+import java.awt.GraphicsEnvironment;
+import java.util.stream.Stream;
+import javax.swing.JLabel;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.netbeans.junit.NbTestCase;
+
+public class StringRendererTest extends NbTestCase {
+
+    private static final int MAX_DISPLAYABLE = 512;
+    private static final String TEXT = "a";
+    private static final String ESCAPED_TEXT = "\\u0061";
+    private static final String MAX_LENGTH_TEXT = Stream.generate(() -> TEXT)
+            .limit(MAX_DISPLAYABLE)
+            .collect(joining());
+    private static final String TOO_LONG_TEXT = Stream.generate(() -> TEXT)
+            .limit(MAX_DISPLAYABLE + 1)
+            .collect(joining());
+
+    public static Test suite() {
+        return GraphicsEnvironment.isHeadless() ? new TestSuite() : new 
TestSuite(StringRendererTest.class);
+    }
+
+    public StringRendererTest(String name) {
+        super(name);
+    }
+
+    private class TestFont extends Font {
+
+        public TestFont() {
+            super(new JLabel().getFont());
+        }
+
+        @Override
+        public boolean canDisplay(char c) {
+            return displayableChar;
+        }
+
+        @Override
+        public boolean canDisplay(int codePoint) {
+            return displayableCodePoint;
+        }
+    }
+
+    private boolean displayableChar;
+    private boolean displayableCodePoint;
+    private final Font font = new TestFont();
+
+    private JLabel stringRenderer;
+
+    @Override
+    protected void setUp() {
+        ReusablePropertyEnv env = new ReusablePropertyEnv();
+        RendererFactory factory = new RendererFactory(true, env, 
env.getReusablePropertyModel());
+        stringRenderer = (JLabel) factory.getStringRenderer();
+
+        displayableChar = true;
+        displayableCodePoint = true;
+        stringRenderer.setFont(font);
+    }
+
+    private void assertSettingText(String input, String expected) {
+        stringRenderer.setText(input);
+
+        assertEquals(expected, stringRenderer.getText());
+    }
+
+    public void testConvertsNullTextToEmptyString() {
+        assertSettingText(null, "");
+    }
+
+    public void testDisplayableTextIsUnchanged() {
+        assertSettingText(MAX_LENGTH_TEXT, MAX_LENGTH_TEXT);
+    }
+
+    public void testTruncatesToMaxLengthText() {
+        assertSettingText(TOO_LONG_TEXT, MAX_LENGTH_TEXT);
+    }
+
+    public void testShouldTransformTabsToSpaces() {
+        assertSettingText("\t", "        ");
+    }
+
+    public void testRemovesNewLines() {
+        assertSettingText("\n", "");
+    }
+
+    public void testRemovesCarriageReturns() {
+        assertSettingText("\r", "");
+    }
+
+    public void testRemovesLineFeeds() {
+        assertSettingText("\r", "");
+    }
+
+    public void testEscapesBackspaces() {
+        assertSettingText("\b", "\\b");
+    }
+
+    public void testEscapesFormFeeds() {
+        assertSettingText("\f", "\\f");
+    }
+
+    public void testEscapesUndisplayableText() {
+        displayableChar = false;
+        displayableCodePoint = false;
+
+        assertSettingText(TEXT, ESCAPED_TEXT);
+    }
+
+    public void testDoesNotEscapeDisplayableCodePoint() {
+        displayableChar = false;
+
+        assertSettingText(TEXT, TEXT);
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to