diff --git a/Ghidra/Features/Base/src/main/java/ghidra/base/actions/HorizontalRuleAction.java b/Ghidra/Features/Base/src/main/java/ghidra/base/actions/HorizontalRuleAction.java index 568855e25c..81834beb74 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/base/actions/HorizontalRuleAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/base/actions/HorizontalRuleAction.java @@ -48,9 +48,16 @@ public class HorizontalRuleAction extends DockingAction { // the description is meant to be used for the tooltip and is larger String padding = "     "; - setDescription("
" + padding + HTMLUtilities.escapeHTML(topName) + padding + - "
" + padding + HTMLUtilities.escapeHTML(bottomName) + padding + - "
"); + setDescription("
" + padding + + fixupFirstAmp(HTMLUtilities.escapeHTML(topName) + padding + "
" + padding + + HTMLUtilities.escapeHTML(bottomName)) + + padding + "
"); + } + + private String fixupFirstAmp(String text) { + // add an extra & to replace the one that the MenuData will eat + int index = text.indexOf('&'); + return index < 0 ? text : text.substring(0, index) + "&" + text.substring(index); } @Override diff --git a/Ghidra/Features/Base/src/test/java/ghidra/app/util/html/DataTypeDifferTest.java b/Ghidra/Features/Base/src/test/java/ghidra/app/util/html/DataTypeDifferTest.java index ac7dd9824b..ad0ee0c5aa 100644 --- a/Ghidra/Features/Base/src/test/java/ghidra/app/util/html/DataTypeDifferTest.java +++ b/Ghidra/Features/Base/src/test/java/ghidra/app/util/html/DataTypeDifferTest.java @@ -26,7 +26,7 @@ import javax.swing.*; import org.junit.Assert; import org.junit.Test; -import docking.widgets.label.GDHtmlLabel; +import docking.widgets.label.GHtmlLabel; import ghidra.app.util.html.diff.*; public class DataTypeDifferTest { @@ -490,24 +490,19 @@ public class DataTypeDifferTest { JPanel panel = new JPanel(new BorderLayout()); JPanel rightPanel = new JPanel(new BorderLayout()); - StringBuffer buffy1 = new StringBuffer(htmlLeft); - JLabel rightLabel = new GDHtmlLabel(); + JLabel rightLabel = new GHtmlLabel(htmlLeft); rightLabel.setOpaque(true); rightLabel.setBackground(Color.WHITE); rightLabel.setVerticalAlignment(SwingConstants.TOP); rightPanel.add(rightLabel); JPanel leftPanel = new JPanel(new BorderLayout()); - StringBuffer buffy2 = new StringBuffer(htmlRight); - JLabel leftLabel = new GDHtmlLabel(); + JLabel leftLabel = new GHtmlLabel(htmlRight); leftLabel.setOpaque(true); leftLabel.setBackground(Color.WHITE); leftLabel.setVerticalAlignment(SwingConstants.TOP); leftPanel.add(leftLabel); - rightLabel.setText(buffy1.toString()); - leftLabel.setText(buffy2.toString()); - JSplitPane pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(leftPanel), new JScrollPane(rightPanel)); pane.setResizeWeight(.5); diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/util/HTMLUtilities.java b/Ghidra/Framework/Generic/src/main/java/ghidra/util/HTMLUtilities.java index a6526adc62..98d79a0e00 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/util/HTMLUtilities.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/util/HTMLUtilities.java @@ -601,9 +601,12 @@ public class HTMLUtilities { /** * Escapes any HTML special characters in the specified text. *

- * Does not otherwise modify the input text or wrap lines. + * Does not otherwise modify the input text or wrap lines. + *

+ * Calling this twice will result in text being double-escaped, which will not display correctly. + *

+ * See also {@link StringEscapeUtils#escapeHtml3(String)} if you need quote-safe html encoding. *

- * See also {@link StringEscapeUtils#escapeHtml3(String)}. * * @param text plain-text that might have some characters that should NOT be interpreted as HTML * @return string with any html characters replaced with equivalents diff --git a/Ghidra/Framework/Generic/src/test/java/ghidra/util/HTMLUtilitiesTest.java b/Ghidra/Framework/Generic/src/test/java/ghidra/util/HTMLUtilitiesTest.java index 2f46d72948..92c1203df4 100644 --- a/Ghidra/Framework/Generic/src/test/java/ghidra/util/HTMLUtilitiesTest.java +++ b/Ghidra/Framework/Generic/src/test/java/ghidra/util/HTMLUtilitiesTest.java @@ -173,4 +173,17 @@ public class HTMLUtilitiesTest { String htmlStr = HTMLUtilities.convertLinkPlaceholdersToHyperlinks(placeholderStr); assertEquals("Stuff inside link tag", htmlStr); } + + @Test + public void testEscapeHTML() { + assertEquals("abc", HTMLUtilities.escapeHTML("abc")); + assertEquals("∢", HTMLUtilities.escapeHTML("\u2222")); + + // unicode char above 0xffff encoded with 2 utf-16 characters + assertEquals("🍄", HTMLUtilities.escapeHTML("\uD83C\uDF44")); + + assertEquals("<abc>", HTMLUtilities.escapeHTML("")); + assertEquals("a&b", HTMLUtilities.escapeHTML("a&b")); + + } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTablePanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTablePanel.java index e988107073..aca4e79313 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTablePanel.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTablePanel.java @@ -30,7 +30,7 @@ import docking.ComponentProvider; import docking.action.DockingActionIf; import docking.help.Help; import docking.help.HelpService; -import docking.widgets.label.GDHtmlLabel; +import docking.widgets.label.GHtmlLabel; import docking.widgets.table.*; import docking.widgets.table.threaded.*; import ghidra.framework.main.FrontEndPlugin; @@ -222,8 +222,8 @@ public class ProjectDataTablePanel extends JPanel { } } - private JLabel capacityExceededText = - new GDHtmlLabel("

Table view disabled for very large projects, or
" + + private GHtmlLabel capacityExceededText = + new GHtmlLabel("
Table view disabled for very large projects, or
" + "if an older project/repository filesystem is in use.
" + "View will remain disabled until project is closed.
");